* entity_list_default use ":" as delimiter for values. Ex:
*
* <pre>
+ * smart_linkify_enabled (boolean)
+ * system_textclassifier_enabled (boolean)
* model_dark_launch_enabled (boolean)
* smart_selection_enabled (boolean)
* smart_text_share_enabled (boolean)
* This is encoded as a key=value list, separated by commas. Ex:
*
* <pre>
+ * smart_linkify_enabled (boolean)
+ * system_textclassifier_enabled (boolean)
* model_dark_launch_enabled (boolean)
* smart_selection_enabled (boolean)
* smart_text_share_enabled (boolean)
private static final String LOG_TAG = "TextClassificationConstants";
+ private static final String LOCAL_TEXT_CLASSIFIER_ENABLED =
+ "local_textclassifier_enabled";
+ private static final String SYSTEM_TEXT_CLASSIFIER_ENABLED =
+ "system_textclassifier_enabled";
private static final String MODEL_DARK_LAUNCH_ENABLED =
"model_dark_launch_enabled";
private static final String SMART_SELECTION_ENABLED =
private static final String ENTITY_LIST_EDITABLE =
"entity_list_editable";
+ private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
+ private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
private static final boolean MODEL_DARK_LAUNCH_ENABLED_DEFAULT = false;
private static final boolean SMART_SELECTION_ENABLED_DEFAULT = true;
private static final boolean SMART_TEXT_SHARE_ENABLED_DEFAULT = true;
.add(TextClassifier.TYPE_DATE_TIME)
.add(TextClassifier.TYPE_FLIGHT_NUMBER).toString();
+ private final boolean mSystemTextClassifierEnabled;
+ private final boolean mLocalTextClassifierEnabled;
private final boolean mModelDarkLaunchEnabled;
private final boolean mSmartSelectionEnabled;
private final boolean mSmartTextShareEnabled;
// Failed to parse the settings string, log this and move on with defaults.
Slog.e(LOG_TAG, "Bad TextClassifier settings: " + settings);
}
+ mSystemTextClassifierEnabled = parser.getBoolean(
+ SYSTEM_TEXT_CLASSIFIER_ENABLED,
+ SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT);
+ mLocalTextClassifierEnabled = parser.getBoolean(
+ LOCAL_TEXT_CLASSIFIER_ENABLED,
+ LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT);
mModelDarkLaunchEnabled = parser.getBoolean(
MODEL_DARK_LAUNCH_ENABLED,
MODEL_DARK_LAUNCH_ENABLED_DEFAULT);
SMART_SELECTION_ENABLED,
SMART_SELECTION_ENABLED_DEFAULT);
mSmartTextShareEnabled = parser.getBoolean(
- SMART_TEXT_SHARE_ENABLED,
- SMART_TEXT_SHARE_ENABLED_DEFAULT);
+ SMART_TEXT_SHARE_ENABLED,
+ SMART_TEXT_SHARE_ENABLED_DEFAULT);
mSmartLinkifyEnabled = parser.getBoolean(
SMART_LINKIFY_ENABLED,
SMART_LINKIFY_ENABLED_DEFAULT);
return new TextClassificationConstants(settings);
}
+ public boolean isLocalTextClassifierEnabled() {
+ return mLocalTextClassifierEnabled;
+ }
+
+ public boolean isSystemTextClassifierEnabled() {
+ return mSystemTextClassifierEnabled;
+ }
+
public boolean isModelDarkLaunchEnabled() {
return mModelDarkLaunchEnabled;
}
import android.os.ServiceManager;
import android.provider.Settings;
import android.service.textclassifier.TextClassifierService;
+import android.view.textclassifier.TextClassifier.TextClassifierType;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
/**
@SystemService(Context.TEXT_CLASSIFICATION_SERVICE)
public final class TextClassificationManager {
- // TODO: Make this a configurable flag.
- private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED = true;
-
private static final String LOG_TAG = "TextClassificationManager";
private final Object mLock = new Object();
private final Context mContext;
private final TextClassificationConstants mSettings;
+
+ @GuardedBy("mLock")
private TextClassifier mTextClassifier;
+ @GuardedBy("mLock")
+ private TextClassifier mLocalTextClassifier;
+ @GuardedBy("mLock")
private TextClassifier mSystemTextClassifier;
/** @hide */
}
/**
- * Returns the system's default TextClassifier.
- * @hide
- */
- // TODO: Unhide when this is ready.
- public TextClassifier getSystemDefaultTextClassifier() {
- synchronized (mLock) {
- if (mSystemTextClassifier == null && isSystemTextClassifierEnabled()) {
- try {
- Log.d(LOG_TAG, "Initialized SystemTextClassifier");
- mSystemTextClassifier = new SystemTextClassifier(mContext, mSettings);
- } catch (ServiceManager.ServiceNotFoundException e) {
- Log.e(LOG_TAG, "Could not initialize SystemTextClassifier", e);
- }
- }
- if (mSystemTextClassifier == null) {
- Log.d(LOG_TAG, "Using an in-process TextClassifier as the system default");
- mSystemTextClassifier = new TextClassifierImpl(mContext, mSettings);
- }
- }
- return mSystemTextClassifier;
- }
-
- /**
- * Returns the text classifier.
+ * Returns the text classifier that was set via {@link #setTextClassifier(TextClassifier)}.
+ * If this is null, this method returns a default text classifier (i.e. either the system text
+ * classifier if one exists, or a local text classifier running in this app.)
+ *
+ * @see #setTextClassifier(TextClassifier)
*/
public TextClassifier getTextClassifier() {
synchronized (mLock) {
if (mTextClassifier == null) {
if (isSystemTextClassifierEnabled()) {
- mTextClassifier = getSystemDefaultTextClassifier();
+ mTextClassifier = getSystemTextClassifier();
} else {
- mTextClassifier = new TextClassifierImpl(mContext, mSettings);
+ mTextClassifier = getLocalTextClassifier();
}
}
return mTextClassifier;
}
}
+ /**
+ * Returns a specific type of text classifier.
+ * If the specified text classifier cannot be found, this returns {@link TextClassifier#NO_OP}.
+ *
+ * @see TextClassifier#LOCAL
+ * @see TextClassifier#SYSTEM
+ * @hide
+ */
+ // TODO: Expose as system API.
+ public TextClassifier getTextClassifier(@TextClassifierType int type) {
+ switch (type) {
+ case TextClassifier.LOCAL:
+ return getLocalTextClassifier();
+ default:
+ return getSystemTextClassifier();
+ }
+ }
+
+ /** @hide */
+ public TextClassificationConstants getSettings() {
+ return mSettings;
+ }
+
+ private TextClassifier getSystemTextClassifier() {
+ synchronized (mLock) {
+ if (mSystemTextClassifier == null && isSystemTextClassifierEnabled()) {
+ try {
+ mSystemTextClassifier = new SystemTextClassifier(mContext, mSettings);
+ Log.d(LOG_TAG, "Initialized SystemTextClassifier");
+ } catch (ServiceManager.ServiceNotFoundException e) {
+ Log.e(LOG_TAG, "Could not initialize SystemTextClassifier", e);
+ }
+ }
+ }
+ if (mSystemTextClassifier != null) {
+ return mSystemTextClassifier;
+ }
+ return TextClassifier.NO_OP;
+ }
+
+ private TextClassifier getLocalTextClassifier() {
+ synchronized (mLock) {
+ if (mLocalTextClassifier == null) {
+ if (mSettings.isLocalTextClassifierEnabled()) {
+ mLocalTextClassifier = new TextClassifierImpl(mContext, mSettings);
+ } else {
+ Log.d(LOG_TAG, "Local TextClassifier disabled");
+ mLocalTextClassifier = TextClassifierImpl.NO_OP;
+ }
+ }
+ return mLocalTextClassifier;
+ }
+ }
+
private boolean isSystemTextClassifierEnabled() {
- return SYSTEM_TEXT_CLASSIFIER_ENABLED
+ return mSettings.isSystemTextClassifierEnabled()
&& TextClassifierService.getServiceComponentName(mContext) != null;
}
package android.view.textclassifier;
+import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
/** @hide */
String DEFAULT_LOG_TAG = "androidtc";
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {LOCAL, SYSTEM})
+ @interface TextClassifierType {} // TODO: Expose as system APIs.
+ /** Specifies a TextClassifier that runs locally in the app's process. @hide */
+ int LOCAL = 0;
+ /** Specifies a TextClassifier that runs in the system process and serves all apps. @hide */
+ int SYSTEM = 1;
+
/** The TextClassifier failed to run. */
String TYPE_UNKNOWN = "";
/** The classifier ran, but didn't recognize a known entity. */
@Test
public void testLoadFromString() {
- final String s = "model_dark_launch_enabled=true,"
+ final String s = "local_textclassifier_enabled=true,"
+ + "system_textclassifier_enabled=true,"
+ + "model_dark_launch_enabled=true,"
+ "smart_selection_enabled=true,"
+ "smart_text_share_enabled=true,"
+ "smart_linkify_enabled=true,"
+ "generate_links_log_sample_rate=13";
final TextClassificationConstants constants =
TextClassificationConstants.loadFromString(s);
+ assertTrue("local_textclassifier_enabled",
+ constants.isLocalTextClassifierEnabled());
+ assertTrue("system_textclassifier_enabled",
+ constants.isSystemTextClassifierEnabled());
assertTrue("model_dark_launch_enabled", constants.isModelDarkLaunchEnabled());
assertTrue("smart_selection_enabled", constants.isSmartSelectionEnabled());
assertTrue("smart_text_share_enabled", constants.isSmartTextShareEnabled());
@Test
public void testLoadFromString_differentValues() {
- final String s = "model_dark_launch_enabled=false,"
+ final String s = "local_textclassifier_enabled=false,"
+ + "system_textclassifier_enabled=false,"
+ + "model_dark_launch_enabled=false,"
+ "smart_selection_enabled=false,"
+ "smart_text_share_enabled=false,"
+ "smart_linkify_enabled=false,"
+ "generate_links_log_sample_rate=5";
final TextClassificationConstants constants =
TextClassificationConstants.loadFromString(s);
+ assertFalse("local_textclassifier_enabled",
+ constants.isLocalTextClassifierEnabled());
+ assertFalse("system_textclassifier_enabled",
+ constants.isSystemTextClassifierEnabled());
assertFalse("model_dark_launch_enabled", constants.isModelDarkLaunchEnabled());
assertFalse("smart_selection_enabled", constants.isSmartSelectionEnabled());
assertFalse("smart_text_share_enabled", constants.isSmartTextShareEnabled());
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
+import android.content.Context;
import android.os.LocaleList;
+import android.service.textclassifier.TextClassifierService;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
private static final LocaleList LOCALES = LocaleList.forLanguageTags("en-US");
private static final String NO_TYPE = null;
+ private Context mContext;
private TextClassificationManager mTcm;
private TextClassifier mClassifier;
private TextSelection.Options mSelectionOptions;
@Before
public void setup() {
- mTcm = InstrumentationRegistry.getTargetContext()
- .getSystemService(TextClassificationManager.class);
+ mContext = InstrumentationRegistry.getTargetContext();
+ mTcm = mContext.getSystemService(TextClassificationManager.class);
mTcm.setTextClassifier(null);
mClassifier = mTcm.getTextClassifier();
mSelectionOptions = new TextSelection.Options().setDefaultLocales(LOCALES);
assertEquals(classifier, mTcm.getTextClassifier());
}
+ @Test
+ public void testGetLocalTextClassifier() {
+ assertTrue(mTcm.getTextClassifier(TextClassifier.LOCAL) instanceof TextClassifierImpl);
+ }
+
+ @Test
+ public void testGetSystemTextClassifier() {
+ assertTrue(
+ TextClassifierService.getServiceComponentName(mContext) == null
+ || mTcm.getTextClassifier(TextClassifier.SYSTEM) instanceof SystemTextClassifier);
+ }
+
private boolean isTextClassifierDisabled() {
return mClassifier == TextClassifier.NO_OP;
}