OSDN Git Service

Add TCM.getTextClassifier(int type)
authorAbodunrinwa Toki <toki@google.com>
Wed, 28 Feb 2018 23:02:13 +0000 (23:02 +0000)
committerAbodunrinwa Toki <toki@google.com>
Thu, 1 Mar 2018 00:00:16 +0000 (00:00 +0000)
Bug: 72747726
Test: bit FrameworksCoreTests:android.view.textclassifier.TextClassificationManagerTest
Test: bit FrameworksCoreTests:android.view.textclassifier.TextClassificationConstantsTest
Test: bit CtsWidgetTestCases:android.widget.cts.TextViewTest
Test: bit FrameworksCoreTests:android.widget.TextViewActivityTest
Change-Id: I0d6cb5eaf3f9baa0564672c4d4b680fb00f40a51

core/java/android/provider/Settings.java
core/java/android/view/textclassifier/TextClassificationConstants.java
core/java/android/view/textclassifier/TextClassificationManager.java
core/java/android/view/textclassifier/TextClassifier.java
core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java
core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java

index 569a0db..2c86564 100644 (file)
@@ -10516,6 +10516,8 @@ public final class Settings {
          * 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)
index 32a7f37..21b5603 100644 (file)
@@ -30,6 +30,8 @@ import java.util.StringJoiner;
  * 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)
@@ -58,6 +60,10 @@ public final class TextClassificationConstants {
 
     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 =
@@ -83,6 +89,8 @@ public final class TextClassificationConstants {
     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;
@@ -102,6 +110,8 @@ public final class TextClassificationConstants {
             .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;
@@ -123,6 +133,12 @@ public final class TextClassificationConstants {
             // 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);
@@ -130,8 +146,8 @@ public final class TextClassificationConstants {
                 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);
@@ -166,6 +182,14 @@ public final class TextClassificationConstants {
         return new TextClassificationConstants(settings);
     }
 
+    public boolean isLocalTextClassifierEnabled() {
+        return mLocalTextClassifierEnabled;
+    }
+
+    public boolean isSystemTextClassifierEnabled() {
+        return mSystemTextClassifierEnabled;
+    }
+
     public boolean isModelDarkLaunchEnabled() {
         return mModelDarkLaunchEnabled;
     }
index fea932c..a7f1ca1 100644 (file)
@@ -22,7 +22,9 @@ import android.content.Context;
 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;
 
 /**
@@ -31,16 +33,18 @@ 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 */
@@ -51,38 +55,19 @@ public final class TextClassificationManager {
     }
 
     /**
-     * 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;
@@ -100,8 +85,62 @@ public final class TextClassificationManager {
         }
     }
 
+    /**
+     * 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;
     }
 
index 0321bb6..ec40fdd 100644 (file)
@@ -16,6 +16,7 @@
 
 package android.view.textclassifier;
 
+import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -49,6 +50,16 @@ public interface TextClassifier {
     /** @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. */
index 7f16359..54007fb 100644 (file)
@@ -32,7 +32,9 @@ public class TextClassificationConstantsTest {
 
     @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,"
@@ -43,6 +45,10 @@ public class TextClassificationConstantsTest {
                 + "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());
@@ -60,7 +66,9 @@ public class TextClassificationConstantsTest {
 
     @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,"
@@ -71,6 +79,10 @@ public class TextClassificationConstantsTest {
                 + "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());
index 5407ce6..57db153 100644 (file)
@@ -22,7 +22,9 @@ import static org.junit.Assert.assertThat;
 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;
@@ -44,6 +46,7 @@ public class TextClassificationManagerTest {
     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;
@@ -52,8 +55,8 @@ public class TextClassificationManagerTest {
 
     @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);
@@ -282,6 +285,18 @@ public class TextClassificationManagerTest {
         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;
     }