Migrate to DeviceConfig in TextClassifier
ConfigParser is introduced to read the flags from DeviceConfig.
If the flag is missing, fallback to Settings.
Also, adds a new setting key: TEXT_CLASSIFIER_ACTION_MODEL_PARAMS
Test: atest frameworks/base/core/tests/coretests/src/android/view/textclassifier/
Test: adb shell cmd device_config put textclassifier system_textclassifier_enabled false
adb shell dumpsys textclassification, observed that the flag is updated.
BUG: 123389900
Change-Id: Icbd26ec7ed223e40b60696d12327cb123b96c4fd
diff --git a/api/system-current.txt b/api/system-current.txt
index 8dedd2c..eac3e99 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5862,6 +5862,7 @@
field public static final String NAMESPACE_NETD_NATIVE = "netd_native";
field public static final String NAMESPACE_RUNTIME_NATIVE_BOOT = "runtime_native_boot";
field public static final String NAMESPACE_SYSTEMUI = "systemui";
+ field public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";
}
public static interface DeviceConfig.AttentionManagerService {
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 5d4539c..0b106d9 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -144,6 +144,14 @@
public static final String NAMESPACE_SYSTEMUI = "systemui";
/**
+ * Namespace for TextClassifier related features.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";
+
+ /**
* Namespace for all runtime related features.
*
* @hide
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 45219d6..e619461 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11895,22 +11895,24 @@
* 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)
- * smart_linkify_enabled (boolean)
- * smart_select_animation_enabled (boolean)
- * suggest_selection_max_range_length (int)
- * classify_text_max_range_length (int)
- * generate_links_max_text_length (int)
- * generate_links_log_sample_rate (int)
- * entity_list_default (String[])
- * entity_list_not_editable (String[])
- * entity_list_editable (String[])
- * lang_id_threshold_override (float)
- * template_intent_factory_enabled (boolean)
+ * smart_linkify_enabled (boolean)
+ * system_textclassifier_enabled (boolean)
+ * model_dark_launch_enabled (boolean)
+ * smart_selection_enabled (boolean)
+ * smart_text_share_enabled (boolean)
+ * smart_linkify_enabled (boolean)
+ * smart_select_animation_enabled (boolean)
+ * suggest_selection_max_range_length (int)
+ * classify_text_max_range_length (int)
+ * generate_links_max_text_length (int)
+ * generate_links_log_sample_rate (int)
+ * entity_list_default (String[])
+ * entity_list_not_editable (String[])
+ * entity_list_editable (String[])
+ * in_app_conversation_action_types_default (String[])
+ * notification_conversation_action_types_default (String[])
+ * lang_id_threshold_override (float)
+ * template_intent_factory_enabled (boolean)
* </pre>
*
* <p>
@@ -14565,6 +14567,14 @@
*/
public static final String BATTERY_CHARGING_STATE_UPDATE_DELAY =
"battery_charging_state_update_delay";
+
+ /**
+ * A serialized string of params that will be loaded into a text classifier action model.
+ *
+ * @hide
+ */
+ public static final String TEXT_CLASSIFIER_ACTION_MODEL_PARAMS =
+ "text_classifier_action_model_params";
}
/**
diff --git a/core/java/android/view/textclassifier/ConfigParser.java b/core/java/android/view/textclassifier/ConfigParser.java
new file mode 100644
index 0000000..8e0bdf9
--- /dev/null
+++ b/core/java/android/view/textclassifier/ConfigParser.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.textclassifier;
+
+import android.annotation.Nullable;
+import android.provider.DeviceConfig;
+import android.util.KeyValueListParser;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Retrieves settings from {@link DeviceConfig} and {@link android.provider.Settings}.
+ * It will try DeviceConfig first and then Settings.
+ *
+ * @hide
+ */
+@VisibleForTesting
+public final class ConfigParser {
+ private static final String TAG = "ConfigParser";
+
+ private final KeyValueListParser mParser;
+
+ public ConfigParser(@Nullable String textClassifierConstants) {
+ final KeyValueListParser parser = new KeyValueListParser(',');
+ try {
+ parser.setString(textClassifierConstants);
+ } catch (IllegalArgumentException e) {
+ // Failed to parse the settings string, log this and move on with defaults.
+ Log.w(TAG, "Bad text_classifier_constants: " + textClassifierConstants);
+ }
+ mParser = parser;
+ }
+
+ /**
+ * Reads a boolean flag.
+ */
+ public boolean getBoolean(String key, boolean defaultValue) {
+ return DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ mParser.getBoolean(key, defaultValue));
+ }
+
+ /**
+ * Reads an integer flag.
+ */
+ public int getInt(String key, int defaultValue) {
+ return DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ mParser.getInt(key, defaultValue));
+ }
+
+ /**
+ * Reads a float flag.
+ */
+ public float getFloat(String key, float defaultValue) {
+ return DeviceConfig.getFloat(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ mParser.getFloat(key, defaultValue));
+ }
+
+ /**
+ * Reads a string flag.
+ */
+ public String getString(String key, String defaultValue) {
+ return DeviceConfig.getString(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ mParser.getString(key, defaultValue));
+ }
+}
diff --git a/core/java/android/view/textclassifier/TextClassificationConstants.java b/core/java/android/view/textclassifier/TextClassificationConstants.java
index 2ef8d04..125b0d3 100644
--- a/core/java/android/view/textclassifier/TextClassificationConstants.java
+++ b/core/java/android/view/textclassifier/TextClassificationConstants.java
@@ -17,8 +17,6 @@
package android.view.textclassifier;
import android.annotation.Nullable;
-import android.util.KeyValueListParser;
-import android.util.Slog;
import com.android.internal.util.IndentingPrintWriter;
@@ -32,22 +30,24 @@
* 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)
- * smart_linkify_enabled (boolean)
- * smart_select_animation_enabled (boolean)
- * suggest_selection_max_range_length (int)
- * classify_text_max_range_length (int)
- * generate_links_max_text_length (int)
- * generate_links_log_sample_rate (int)
- * entity_list_default (String[])
- * entity_list_not_editable (String[])
- * entity_list_editable (String[])
- * lang_id_threshold_override (float)
- * template_intent_factory_enabled (boolean)
+ * smart_linkify_enabled (boolean)
+ * system_textclassifier_enabled (boolean)
+ * model_dark_launch_enabled (boolean)
+ * smart_selection_enabled (boolean)
+ * smart_text_share_enabled (boolean)
+ * smart_linkify_enabled (boolean)
+ * smart_select_animation_enabled (boolean)
+ * suggest_selection_max_range_length (int)
+ * classify_text_max_range_length (int)
+ * generate_links_max_text_length (int)
+ * generate_links_log_sample_rate (int)
+ * entity_list_default (String[])
+ * entity_list_not_editable (String[])
+ * entity_list_editable (String[])
+ * in_app_conversation_action_types_default (String[])
+ * notification_conversation_action_types_default (String[])
+ * lang_id_threshold_override (float)
+ * template_intent_factory_enabled (boolean)
* </pre>
*
* <p>
@@ -61,43 +61,90 @@
* @hide
*/
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 =
- "smart_selection_enabled";
- private static final String SMART_TEXT_SHARE_ENABLED =
- "smart_text_share_enabled";
- private static final String SMART_LINKIFY_ENABLED =
- "smart_linkify_enabled";
+ /**
+ * Whether the smart linkify feature is enabled.
+ */
+ private static final String SMART_LINKIFY_ENABLED = "smart_linkify_enabled";
+ /**
+ * Whether SystemTextClassifier is enabled.
+ */
+ private static final String SYSTEM_TEXT_CLASSIFIER_ENABLED = "system_textclassifier_enabled";
+ /**
+ * Whether TextClassifierImpl is enabled.
+ */
+ private static final String LOCAL_TEXT_CLASSIFIER_ENABLED = "local_textclassifier_enabled";
+ /**
+ * Enable smart selection without a visible UI changes.
+ */
+ private static final String MODEL_DARK_LAUNCH_ENABLED = "model_dark_launch_enabled";
+
+ /**
+ * Whether the smart selection feature is enabled.
+ */
+ private static final String SMART_SELECTION_ENABLED = "smart_selection_enabled";
+ /**
+ * Whether the smart text share feature is enabled.
+ */
+ private static final String SMART_TEXT_SHARE_ENABLED = "smart_text_share_enabled";
+ /**
+ * Whether animation for smart selection is enabled.
+ */
private static final String SMART_SELECT_ANIMATION_ENABLED =
"smart_select_animation_enabled";
+ /**
+ * Max length of text that suggestSelection can accept.
+ */
private static final String SUGGEST_SELECTION_MAX_RANGE_LENGTH =
"suggest_selection_max_range_length";
- private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH =
- "classify_text_max_range_length";
- private static final String GENERATE_LINKS_MAX_TEXT_LENGTH =
- "generate_links_max_text_length";
+ /**
+ * Max length of text that classifyText can accept.
+ */
+ private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH = "classify_text_max_range_length";
+ /**
+ * Max length of text that generateLinks can accept.
+ */
+ private static final String GENERATE_LINKS_MAX_TEXT_LENGTH = "generate_links_max_text_length";
+ /**
+ * Sampling rate for generateLinks logging.
+ */
private static final String GENERATE_LINKS_LOG_SAMPLE_RATE =
"generate_links_log_sample_rate";
- private static final String ENTITY_LIST_DEFAULT =
- "entity_list_default";
- private static final String ENTITY_LIST_NOT_EDITABLE =
- "entity_list_not_editable";
- private static final String ENTITY_LIST_EDITABLE =
- "entity_list_editable";
+ /**
+ * A colon(:) separated string that specifies the default entities types for
+ * generateLinks when hint is not given.
+ */
+ private static final String ENTITY_LIST_DEFAULT = "entity_list_default";
+ /**
+ * A colon(:) separated string that specifies the default entities types for
+ * generateLinks when the text is in a not editable UI widget.
+ */
+ private static final String ENTITY_LIST_NOT_EDITABLE = "entity_list_not_editable";
+ /**
+ * A colon(:) separated string that specifies the default entities types for
+ * generateLinks when the text is in an editable UI widget.
+ */
+ private static final String ENTITY_LIST_EDITABLE = "entity_list_editable";
+ /**
+ * A colon(:) separated string that specifies the default action types for
+ * suggestConversationActions when the suggestions are used in an app.
+ */
private static final String IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT =
"in_app_conversation_action_types_default";
+ /**
+ * A colon(:) separated string that specifies the default action types for
+ * suggestConversationActions when the suggestions are used in a notification.
+ */
private static final String NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT =
"notification_conversation_action_types_default";
- private static final String LANG_ID_THRESHOLD_OVERRIDE =
- "lang_id_threshold_override";
+ /**
+ * Threshold in classifyText to consider a text is in a foreign language.
+ */
+ private static final String LANG_ID_THRESHOLD_OVERRIDE = "lang_id_threshold_override";
+ /**
+ * Whether to enable {@link android.view.textclassifier.TemplateIntentFactory}.
+ */
private static final String TEMPLATE_INTENT_FACTORY_ENABLED = "template_intent_factory_enabled";
private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
@@ -162,66 +209,77 @@
private final boolean mTemplateIntentFactoryEnabled;
private TextClassificationConstants(@Nullable String settings) {
- final KeyValueListParser parser = new KeyValueListParser(',');
- try {
- parser.setString(settings);
- } catch (IllegalArgumentException e) {
- // 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);
- mSmartSelectionEnabled = parser.getBoolean(
- SMART_SELECTION_ENABLED,
- SMART_SELECTION_ENABLED_DEFAULT);
- mSmartTextShareEnabled = parser.getBoolean(
- SMART_TEXT_SHARE_ENABLED,
- SMART_TEXT_SHARE_ENABLED_DEFAULT);
- mSmartLinkifyEnabled = parser.getBoolean(
- SMART_LINKIFY_ENABLED,
- SMART_LINKIFY_ENABLED_DEFAULT);
- mSmartSelectionAnimationEnabled = parser.getBoolean(
- SMART_SELECT_ANIMATION_ENABLED,
- SMART_SELECT_ANIMATION_ENABLED_DEFAULT);
- mSuggestSelectionMaxRangeLength = parser.getInt(
- SUGGEST_SELECTION_MAX_RANGE_LENGTH,
- SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
- mClassifyTextMaxRangeLength = parser.getInt(
- CLASSIFY_TEXT_MAX_RANGE_LENGTH,
- CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT);
- mGenerateLinksMaxTextLength = parser.getInt(
- GENERATE_LINKS_MAX_TEXT_LENGTH,
- GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT);
- mGenerateLinksLogSampleRate = parser.getInt(
- GENERATE_LINKS_LOG_SAMPLE_RATE,
- GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT);
- mEntityListDefault = parseStringList(parser.getString(
+ ConfigParser configParser = new ConfigParser(settings);
+ mSystemTextClassifierEnabled =
+ configParser.getBoolean(
+ SYSTEM_TEXT_CLASSIFIER_ENABLED,
+ SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT);
+ mLocalTextClassifierEnabled =
+ configParser.getBoolean(
+ LOCAL_TEXT_CLASSIFIER_ENABLED,
+ LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT);
+ mModelDarkLaunchEnabled =
+ configParser.getBoolean(
+ MODEL_DARK_LAUNCH_ENABLED,
+ MODEL_DARK_LAUNCH_ENABLED_DEFAULT);
+ mSmartSelectionEnabled =
+ configParser.getBoolean(
+ SMART_SELECTION_ENABLED,
+ SMART_SELECTION_ENABLED_DEFAULT);
+ mSmartTextShareEnabled =
+ configParser.getBoolean(
+ SMART_TEXT_SHARE_ENABLED,
+ SMART_TEXT_SHARE_ENABLED_DEFAULT);
+ mSmartLinkifyEnabled =
+ configParser.getBoolean(
+ SMART_LINKIFY_ENABLED,
+ SMART_LINKIFY_ENABLED_DEFAULT);
+ mSmartSelectionAnimationEnabled =
+ configParser.getBoolean(
+ SMART_SELECT_ANIMATION_ENABLED,
+ SMART_SELECT_ANIMATION_ENABLED_DEFAULT);
+ mSuggestSelectionMaxRangeLength =
+ configParser.getInt(
+ SUGGEST_SELECTION_MAX_RANGE_LENGTH,
+ SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
+ mClassifyTextMaxRangeLength =
+ configParser.getInt(
+ CLASSIFY_TEXT_MAX_RANGE_LENGTH,
+ CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT);
+ mGenerateLinksMaxTextLength =
+ configParser.getInt(
+ GENERATE_LINKS_MAX_TEXT_LENGTH,
+ GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT);
+ mGenerateLinksLogSampleRate =
+ configParser.getInt(
+ GENERATE_LINKS_LOG_SAMPLE_RATE,
+ GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT);
+ mEntityListDefault = parseStringList(configParser.getString(
ENTITY_LIST_DEFAULT,
ENTITY_LIST_DEFAULT_VALUE));
- mEntityListNotEditable = parseStringList(parser.getString(
- ENTITY_LIST_NOT_EDITABLE,
- ENTITY_LIST_DEFAULT_VALUE));
- mEntityListEditable = parseStringList(parser.getString(
- ENTITY_LIST_EDITABLE,
- ENTITY_LIST_DEFAULT_VALUE));
- mInAppConversationActionTypesDefault = parseStringList(parser.getString(
- IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT,
- CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
- mNotificationConversationActionTypesDefault = parseStringList(parser.getString(
- NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT,
- CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
- mLangIdThresholdOverride = parser.getFloat(
- LANG_ID_THRESHOLD_OVERRIDE,
- LANG_ID_THRESHOLD_OVERRIDE_DEFAULT);
- mTemplateIntentFactoryEnabled = parser.getBoolean(
- TEMPLATE_INTENT_FACTORY_ENABLED, TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT);
+ mEntityListNotEditable = parseStringList(
+ configParser.getString(
+ ENTITY_LIST_NOT_EDITABLE,
+ ENTITY_LIST_DEFAULT_VALUE));
+ mEntityListEditable = parseStringList(
+ configParser.getString(
+ ENTITY_LIST_EDITABLE,
+ ENTITY_LIST_DEFAULT_VALUE));
+ mInAppConversationActionTypesDefault = parseStringList(
+ configParser.getString(
+ IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT,
+ CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
+ mNotificationConversationActionTypesDefault = parseStringList(
+ configParser.getString(
+ NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT,
+ CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
+ mLangIdThresholdOverride =
+ configParser.getFloat(
+ LANG_ID_THRESHOLD_OVERRIDE,
+ LANG_ID_THRESHOLD_OVERRIDE_DEFAULT);
+ mTemplateIntentFactoryEnabled = configParser.getBoolean(
+ TEMPLATE_INTENT_FACTORY_ENABLED,
+ TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT);
}
/** Load from a settings string. */
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index d047c55..868cbb1 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -20,9 +20,11 @@
import android.annotation.Nullable;
import android.annotation.SystemService;
import android.annotation.UnsupportedAppUsage;
+import android.app.ActivityThread;
import android.content.Context;
import android.database.ContentObserver;
import android.os.ServiceManager;
+import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.textclassifier.TextClassifierService;
import android.view.textclassifier.TextClassifier.TextClassifierType;
@@ -195,6 +197,7 @@
if (mSettingsObserver != null) {
getApplicationContext().getContentResolver()
.unregisterContentObserver(mSettingsObserver);
+ DeviceConfig.removeOnPropertyChangedListener(mSettingsObserver);
}
} finally {
super.finalize();
@@ -277,7 +280,8 @@
}
}
- private static final class SettingsObserver extends ContentObserver {
+ private static final class SettingsObserver extends ContentObserver
+ implements DeviceConfig.OnPropertyChangedListener {
private final WeakReference<TextClassificationManager> mTcm;
@@ -288,10 +292,23 @@
Settings.Global.getUriFor(Settings.Global.TEXT_CLASSIFIER_CONSTANTS),
false /* notifyForDescendants */,
this);
+ DeviceConfig.addOnPropertyChangedListener(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ ActivityThread.currentApplication().getMainExecutor(),
+ this);
}
@Override
public void onChange(boolean selfChange) {
+ invalidateSettings();
+ }
+
+ @Override
+ public void onPropertyChanged(String namespace, String name, String value) {
+ invalidateSettings();
+ }
+
+ private void invalidateSettings() {
final TextClassificationManager tcm = mTcm.get();
if (tcm != null) {
tcm.invalidate();
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index c1cbd52..62df6e7 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -1043,7 +1043,9 @@
optional SettingProto app_ops_constants = 148 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto text_classifier_action_model_params = 145 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 145 then 149; // (145 was removed)
+ // Next tag = 149;
}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index ebc6be7..3da7f72 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -467,6 +467,7 @@
Settings.Global.TETHER_SUPPORTED,
Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER,
Settings.Global.TEXT_CLASSIFIER_CONSTANTS,
+ Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS,
Settings.Global.THEATER_MODE_ON,
Settings.Global.TIME_ONLY_MODE_CONSTANTS,
Settings.Global.TRANSITION_ANIMATION_SCALE,
diff --git a/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java b/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java
new file mode 100644
index 0000000..1b3c724
--- /dev/null
+++ b/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.textclassifier;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.provider.DeviceConfig;
+import android.support.test.uiautomator.UiDevice;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ConfigParserTest {
+ private static final String SETTINGS = "int=42,float=12.3,boolean=true,string=abc";
+ private static final String CLEAR_DEVICE_CONFIG_KEY_CMD =
+ "device_config delete " + DeviceConfig.NAMESPACE_TEXTCLASSIFIER;
+ private static final String[] DEVICE_CONFIG_KEYS = new String[]{
+ "boolean",
+ "string",
+ "int",
+ "float"
+ };
+
+ private ConfigParser mConfigParser;
+
+ @Before
+ public void setup() throws IOException {
+ mConfigParser = new ConfigParser(SETTINGS);
+ clearDeviceConfig();
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ clearDeviceConfig();
+ }
+
+ @Test
+ public void getBoolean_deviceConfig() {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ "boolean",
+ "false",
+ false);
+ boolean value = mConfigParser.getBoolean("boolean", true);
+ assertThat(value).isFalse();
+ }
+
+ @Test
+ public void getBoolean_settings() {
+ boolean value = mConfigParser.getBoolean(
+ "boolean",
+ false);
+ assertThat(value).isTrue();
+ }
+
+ @Test
+ public void getInt_deviceConfig() {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ "int",
+ "1",
+ false);
+ int value = mConfigParser.getInt("int", 0);
+ assertThat(value).isEqualTo(1);
+ }
+
+ @Test
+ public void getInt_settings() {
+ int value = mConfigParser.getInt("int", 0);
+ assertThat(value).isEqualTo(42);
+ }
+
+ @Test
+ public void getFloat_deviceConfig() {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ "float",
+ "3.14",
+ false);
+ float value = mConfigParser.getFloat("float", 0);
+ assertThat(value).isWithin(0.0001f).of(3.14f);
+ }
+
+ @Test
+ public void getFloat_settings() {
+ float value = mConfigParser.getFloat("float", 0);
+ assertThat(value).isWithin(0.0001f).of(12.3f);
+ }
+
+ @Test
+ public void getString_deviceConfig() {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ "string",
+ "hello",
+ false);
+ String value = mConfigParser.getString("string", "");
+ assertThat(value).isEqualTo("hello");
+ }
+
+ @Test
+ public void getString_settings() {
+ String value = mConfigParser.getString("string", "");
+ assertThat(value).isEqualTo("abc");
+ }
+
+ private static void clearDeviceConfig() throws IOException {
+ UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ for (String key : DEVICE_CONFIG_KEYS) {
+ uiDevice.executeShellCommand(CLEAR_DEVICE_CONFIG_KEY_CMD + " " + key);
+ }
+ }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 0f8fd92..f7f34f6 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1382,6 +1382,9 @@
Settings.Global.TEXT_CLASSIFIER_CONSTANTS,
GlobalSettingsProto.TEXT_CLASSIFIER_CONSTANTS);
dumpSetting(s, p,
+ Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS,
+ GlobalSettingsProto.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS);
+ dumpSetting(s, p,
Settings.Global.THEATER_MODE_ON,
GlobalSettingsProto.THEATER_MODE_ON);
dumpSetting(s, p,