Loading apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java +2 −2 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ public class TextClassificationManagerPerfTest { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { textClassificationManager.getTextClassifier(); textClassificationManager.invalidate(); textClassificationManager.invalidateForTesting(); } } Loading @@ -68,7 +68,7 @@ public class TextClassificationManagerPerfTest { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { textClassificationManager.getTextClassifier(); textClassificationManager.invalidate(); textClassificationManager.invalidateForTesting(); } } } core/java/android/provider/DeviceConfig.java +1 −0 Original line number Diff line number Diff line Loading @@ -271,6 +271,7 @@ public final class DeviceConfig { * Namespace for TextClassifier related features. * * @hide * @see android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS */ @SystemApi public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier"; Loading core/java/android/provider/Settings.java +14 −13 Original line number Diff line number Diff line Loading @@ -12034,26 +12034,27 @@ 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) * 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) * detect_language_from_text_enabled (boolean) * entity_list_default (String[]) * entity_list_not_editable (String[]) * entity_list_editable (String[]) * entity_list_not_editable (String[]) * generate_links_log_sample_rate (int) * generate_links_max_text_length (int) * in_app_conversation_action_types_default (String[]) * notification_conversation_action_types_default (String[]) * lang_id_context_settings (float[]) * lang_id_threshold_override (float) * local_textclassifier_enabled (boolean) * model_dark_launch_enabled (boolean) * notification_conversation_action_types_default (String[]) * smart_linkify_enabled (boolean) * smart_select_animation_enabled (boolean) * smart_selection_enabled (boolean) * smart_text_share_enabled (boolean) * suggest_selection_max_range_length (int) * system_textclassifier_enabled (boolean) * template_intent_factory_enabled (boolean) * translate_in_classification_enabled (boolean) * detect_language_from_text_enabled (boolean) * </pre> * * <p> Loading core/java/android/view/textclassifier/ConfigParser.java +202 −44 Original line number Diff line number Diff line Loading @@ -17,9 +17,19 @@ package android.view.textclassifier; import android.annotation.Nullable; import android.provider.DeviceConfig; import android.util.ArrayMap; import android.util.KeyValueListParser; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; import com.android.internal.util.Preconditions; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Supplier; /** * Retrieves settings from {@link DeviceConfig} and {@link android.provider.Settings}. Loading @@ -27,80 +37,228 @@ import com.android.internal.annotations.VisibleForTesting; * * @hide */ @VisibleForTesting @VisibleForTesting(visibility = Visibility.PACKAGE) public final class ConfigParser { private static final String TAG = "ConfigParser"; private final KeyValueListParser mParser; static final boolean ENABLE_DEVICE_CONFIG = true; private static final String STRING_LIST_DELIMITER = ":"; // TODO: Re-enable DeviceConfig when it has reasonable performance or just delete the // option of using DeviceConfig entirely. static final boolean ENABLE_DEVICE_CONFIG = false; private final Supplier<String> mLegacySettingsSupplier; private final Object mLock = new Object(); @GuardedBy("mLock") private final Map<String, Object> mCache = new ArrayMap<>(); @GuardedBy("mLock") private @Nullable KeyValueListParser mSettingsParser; // Call getLegacySettings() instead. public ConfigParser(Supplier<String> legacySettingsSupplier) { mLegacySettingsSupplier = Preconditions.checkNotNull(legacySettingsSupplier); } public ConfigParser(@Nullable String textClassifierConstants) { final KeyValueListParser parser = new KeyValueListParser(','); private KeyValueListParser getLegacySettings() { synchronized (mLock) { if (mSettingsParser == null) { final String legacySettings = mLegacySettingsSupplier.get(); try { parser.setString(textClassifierConstants); mSettingsParser = new KeyValueListParser(','); mSettingsParser.setString(legacySettings); } catch (IllegalArgumentException e) { // Failed to parse the settings string, log this and move on with defaults. Log.w(TAG, "Bad text_classifier_constants: " + textClassifierConstants); Log.w(TAG, "Bad text_classifier_constants: " + legacySettings); } } return mSettingsParser; } mParser = parser; } /** * Reads a boolean flag. * Reads a boolean setting through the cache. */ public boolean getBoolean(String key, boolean defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof Boolean) { return (boolean) cached; } final boolean value; if (ENABLE_DEVICE_CONFIG) { return DeviceConfig.getBoolean( value = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, mParser.getBoolean(key, defaultValue)); getLegacySettings().getBoolean(key, defaultValue)); } else { return mParser.getBoolean(key, defaultValue); value = getLegacySettings().getBoolean(key, defaultValue); } mCache.put(key, value); return value; } } /** * Reads an integer flag. * Reads an integer setting through the cache. */ public int getInt(String key, int defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof Integer) { return (int) cached; } final int value; if (ENABLE_DEVICE_CONFIG) { return DeviceConfig.getInt( value = DeviceConfig.getInt( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, mParser.getInt(key, defaultValue)); getLegacySettings().getInt(key, defaultValue)); } else { return mParser.getInt(key, defaultValue); value = getLegacySettings().getInt(key, defaultValue); } mCache.put(key, value); return value; } } /** * Reads a float flag. * Reads a float setting through the cache. */ public float getFloat(String key, float defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof Float) { return (float) cached; } final float value; if (ENABLE_DEVICE_CONFIG) { return DeviceConfig.getFloat( value = DeviceConfig.getFloat( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, mParser.getFloat(key, defaultValue)); getLegacySettings().getFloat(key, defaultValue)); } else { return mParser.getFloat(key, defaultValue); value = getLegacySettings().getFloat(key, defaultValue); } mCache.put(key, value); return value; } } /** * Reads a string flag. * Reads a string setting through the cache. */ public String getString(String key, String defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof String) { return (String) cached; } final String value; if (ENABLE_DEVICE_CONFIG) { return DeviceConfig.getString( value = DeviceConfig.getString( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, mParser.getString(key, defaultValue)); getLegacySettings().getString(key, defaultValue)); } else { value = getLegacySettings().getString(key, defaultValue); } mCache.put(key, value); return value; } } /** * Reads a string list setting through the cache. */ public List<String> getStringList(String key, List<String> defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof List) { final List asList = (List) cached; if (asList.isEmpty()) { return Collections.emptyList(); } else if (asList.get(0) instanceof String) { return (List<String>) cached; } } final List<String> value; if (ENABLE_DEVICE_CONFIG) { value = getDeviceConfigStringList( key, getSettingsStringList(key, defaultValue)); } else { value = getSettingsStringList(key, defaultValue); } mCache.put(key, value); return value; } } /** * Reads a float array through the cache. The returned array should be expected to be of the * same length as that of the defaultValue. */ public float[] getFloatArray(String key, float[] defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof float[]) { return (float[]) cached; } final float[] value; if (ENABLE_DEVICE_CONFIG) { value = getDeviceConfigFloatArray( key, getSettingsFloatArray(key, defaultValue)); } else { value = getSettingsFloatArray(key, defaultValue); } mCache.put(key, value); return value; } } private List<String> getSettingsStringList(String key, List<String> defaultValue) { return parse(mSettingsParser.getString(key, null), defaultValue); } private static List<String> getDeviceConfigStringList(String key, List<String> defaultValue) { return parse( DeviceConfig.getString(DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, null), defaultValue); } private static float[] getDeviceConfigFloatArray(String key, float[] defaultValue) { return parse( DeviceConfig.getString(DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, null), defaultValue); } private float[] getSettingsFloatArray(String key, float[] defaultValue) { return parse(mSettingsParser.getString(key, null), defaultValue); } private static List<String> parse(@Nullable String listStr, List<String> defaultValue) { if (listStr != null) { return Collections.unmodifiableList( Arrays.asList(listStr.split(STRING_LIST_DELIMITER))); } return defaultValue; } private static float[] parse(@Nullable String arrayStr, float[] defaultValue) { if (arrayStr != null) { final String[] split = arrayStr.split(STRING_LIST_DELIMITER); if (split.length != defaultValue.length) { return defaultValue; } final float[] result = new float[split.length]; for (int i = 0; i < split.length; i++) { try { result[i] = Float.parseFloat(split[i]); } catch (NumberFormatException e) { return defaultValue; } } return result; } else { return mParser.getString(key, defaultValue); return defaultValue; } } } core/java/android/view/textclassifier/TextClassificationConstants.java +146 −242 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java +2 −2 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ public class TextClassificationManagerPerfTest { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { textClassificationManager.getTextClassifier(); textClassificationManager.invalidate(); textClassificationManager.invalidateForTesting(); } } Loading @@ -68,7 +68,7 @@ public class TextClassificationManagerPerfTest { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { textClassificationManager.getTextClassifier(); textClassificationManager.invalidate(); textClassificationManager.invalidateForTesting(); } } }
core/java/android/provider/DeviceConfig.java +1 −0 Original line number Diff line number Diff line Loading @@ -271,6 +271,7 @@ public final class DeviceConfig { * Namespace for TextClassifier related features. * * @hide * @see android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS */ @SystemApi public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier"; Loading
core/java/android/provider/Settings.java +14 −13 Original line number Diff line number Diff line Loading @@ -12034,26 +12034,27 @@ 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) * 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) * detect_language_from_text_enabled (boolean) * entity_list_default (String[]) * entity_list_not_editable (String[]) * entity_list_editable (String[]) * entity_list_not_editable (String[]) * generate_links_log_sample_rate (int) * generate_links_max_text_length (int) * in_app_conversation_action_types_default (String[]) * notification_conversation_action_types_default (String[]) * lang_id_context_settings (float[]) * lang_id_threshold_override (float) * local_textclassifier_enabled (boolean) * model_dark_launch_enabled (boolean) * notification_conversation_action_types_default (String[]) * smart_linkify_enabled (boolean) * smart_select_animation_enabled (boolean) * smart_selection_enabled (boolean) * smart_text_share_enabled (boolean) * suggest_selection_max_range_length (int) * system_textclassifier_enabled (boolean) * template_intent_factory_enabled (boolean) * translate_in_classification_enabled (boolean) * detect_language_from_text_enabled (boolean) * </pre> * * <p> Loading
core/java/android/view/textclassifier/ConfigParser.java +202 −44 Original line number Diff line number Diff line Loading @@ -17,9 +17,19 @@ package android.view.textclassifier; import android.annotation.Nullable; import android.provider.DeviceConfig; import android.util.ArrayMap; import android.util.KeyValueListParser; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; import com.android.internal.util.Preconditions; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Supplier; /** * Retrieves settings from {@link DeviceConfig} and {@link android.provider.Settings}. Loading @@ -27,80 +37,228 @@ import com.android.internal.annotations.VisibleForTesting; * * @hide */ @VisibleForTesting @VisibleForTesting(visibility = Visibility.PACKAGE) public final class ConfigParser { private static final String TAG = "ConfigParser"; private final KeyValueListParser mParser; static final boolean ENABLE_DEVICE_CONFIG = true; private static final String STRING_LIST_DELIMITER = ":"; // TODO: Re-enable DeviceConfig when it has reasonable performance or just delete the // option of using DeviceConfig entirely. static final boolean ENABLE_DEVICE_CONFIG = false; private final Supplier<String> mLegacySettingsSupplier; private final Object mLock = new Object(); @GuardedBy("mLock") private final Map<String, Object> mCache = new ArrayMap<>(); @GuardedBy("mLock") private @Nullable KeyValueListParser mSettingsParser; // Call getLegacySettings() instead. public ConfigParser(Supplier<String> legacySettingsSupplier) { mLegacySettingsSupplier = Preconditions.checkNotNull(legacySettingsSupplier); } public ConfigParser(@Nullable String textClassifierConstants) { final KeyValueListParser parser = new KeyValueListParser(','); private KeyValueListParser getLegacySettings() { synchronized (mLock) { if (mSettingsParser == null) { final String legacySettings = mLegacySettingsSupplier.get(); try { parser.setString(textClassifierConstants); mSettingsParser = new KeyValueListParser(','); mSettingsParser.setString(legacySettings); } catch (IllegalArgumentException e) { // Failed to parse the settings string, log this and move on with defaults. Log.w(TAG, "Bad text_classifier_constants: " + textClassifierConstants); Log.w(TAG, "Bad text_classifier_constants: " + legacySettings); } } return mSettingsParser; } mParser = parser; } /** * Reads a boolean flag. * Reads a boolean setting through the cache. */ public boolean getBoolean(String key, boolean defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof Boolean) { return (boolean) cached; } final boolean value; if (ENABLE_DEVICE_CONFIG) { return DeviceConfig.getBoolean( value = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, mParser.getBoolean(key, defaultValue)); getLegacySettings().getBoolean(key, defaultValue)); } else { return mParser.getBoolean(key, defaultValue); value = getLegacySettings().getBoolean(key, defaultValue); } mCache.put(key, value); return value; } } /** * Reads an integer flag. * Reads an integer setting through the cache. */ public int getInt(String key, int defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof Integer) { return (int) cached; } final int value; if (ENABLE_DEVICE_CONFIG) { return DeviceConfig.getInt( value = DeviceConfig.getInt( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, mParser.getInt(key, defaultValue)); getLegacySettings().getInt(key, defaultValue)); } else { return mParser.getInt(key, defaultValue); value = getLegacySettings().getInt(key, defaultValue); } mCache.put(key, value); return value; } } /** * Reads a float flag. * Reads a float setting through the cache. */ public float getFloat(String key, float defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof Float) { return (float) cached; } final float value; if (ENABLE_DEVICE_CONFIG) { return DeviceConfig.getFloat( value = DeviceConfig.getFloat( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, mParser.getFloat(key, defaultValue)); getLegacySettings().getFloat(key, defaultValue)); } else { return mParser.getFloat(key, defaultValue); value = getLegacySettings().getFloat(key, defaultValue); } mCache.put(key, value); return value; } } /** * Reads a string flag. * Reads a string setting through the cache. */ public String getString(String key, String defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof String) { return (String) cached; } final String value; if (ENABLE_DEVICE_CONFIG) { return DeviceConfig.getString( value = DeviceConfig.getString( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, mParser.getString(key, defaultValue)); getLegacySettings().getString(key, defaultValue)); } else { value = getLegacySettings().getString(key, defaultValue); } mCache.put(key, value); return value; } } /** * Reads a string list setting through the cache. */ public List<String> getStringList(String key, List<String> defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof List) { final List asList = (List) cached; if (asList.isEmpty()) { return Collections.emptyList(); } else if (asList.get(0) instanceof String) { return (List<String>) cached; } } final List<String> value; if (ENABLE_DEVICE_CONFIG) { value = getDeviceConfigStringList( key, getSettingsStringList(key, defaultValue)); } else { value = getSettingsStringList(key, defaultValue); } mCache.put(key, value); return value; } } /** * Reads a float array through the cache. The returned array should be expected to be of the * same length as that of the defaultValue. */ public float[] getFloatArray(String key, float[] defaultValue) { synchronized (mLock) { final Object cached = mCache.get(key); if (cached instanceof float[]) { return (float[]) cached; } final float[] value; if (ENABLE_DEVICE_CONFIG) { value = getDeviceConfigFloatArray( key, getSettingsFloatArray(key, defaultValue)); } else { value = getSettingsFloatArray(key, defaultValue); } mCache.put(key, value); return value; } } private List<String> getSettingsStringList(String key, List<String> defaultValue) { return parse(mSettingsParser.getString(key, null), defaultValue); } private static List<String> getDeviceConfigStringList(String key, List<String> defaultValue) { return parse( DeviceConfig.getString(DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, null), defaultValue); } private static float[] getDeviceConfigFloatArray(String key, float[] defaultValue) { return parse( DeviceConfig.getString(DeviceConfig.NAMESPACE_TEXTCLASSIFIER, key, null), defaultValue); } private float[] getSettingsFloatArray(String key, float[] defaultValue) { return parse(mSettingsParser.getString(key, null), defaultValue); } private static List<String> parse(@Nullable String listStr, List<String> defaultValue) { if (listStr != null) { return Collections.unmodifiableList( Arrays.asList(listStr.split(STRING_LIST_DELIMITER))); } return defaultValue; } private static float[] parse(@Nullable String arrayStr, float[] defaultValue) { if (arrayStr != null) { final String[] split = arrayStr.split(STRING_LIST_DELIMITER); if (split.length != defaultValue.length) { return defaultValue; } final float[] result = new float[split.length]; for (int i = 0; i < split.length; i++) { try { result[i] = Float.parseFloat(split[i]); } catch (NumberFormatException e) { return defaultValue; } } return result; } else { return mParser.getString(key, defaultValue); return defaultValue; } } }
core/java/android/view/textclassifier/TextClassificationConstants.java +146 −242 File changed.Preview size limit exceeded, changes collapsed. Show changes