Loading core/java/android/provider/Settings.java +5 −1 Original line number Diff line number Diff line Loading @@ -10471,7 +10471,8 @@ public final class Settings { /** * TextClassifier specific settings. * This is encoded as a key=value list, separated by commas. Ex: * This is encoded as a key=value list, separated by commas. String[] types like * entity_list_default use ":" as delimiter for values. Ex: * * <pre> * smart_selection_dark_launch (boolean) Loading @@ -10480,6 +10481,9 @@ public final class Settings { * 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[]) * </pre> * * <p> Loading core/java/android/view/textclassifier/TextClassifierConstants.java +62 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ import android.annotation.Nullable; import android.util.KeyValueListParser; import android.util.Slog; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.StringJoiner; /** * TextClassifier specific settings. * This is encoded as a key=value list, separated by commas. Ex: Loading @@ -27,6 +32,12 @@ import android.util.Slog; * <pre> * smart_selection_dark_launch (boolean) * smart_selection_enabled_for_edit_text (boolean) * suggest_selection_max_range_length (int) * classify_text_max_range_length (int) * generate_links_max_text_length (int) * entity_list_default (String[]) * entity_list_not_editable (String[]) * entity_list_editable (String[]) * </pre> * * <p> Loading @@ -34,7 +45,9 @@ import android.util.Slog; * see also android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS * * Example of setting the values for testing. * adb shell settings put global text_classifier_constants smart_selection_dark_launch=true,smart_selection_enabled_for_edit_text=true * adb shell settings put global text_classifier_constants \ * smart_selection_dark_launch=true,smart_selection_enabled_for_edit_text=true,\ * entity_list_default=phone:address * @hide */ public final class TextClassifierConstants { Loading @@ -55,6 +68,12 @@ public final class TextClassifierConstants { "generate_links_max_text_length"; 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"; private static final boolean SMART_SELECTION_DARK_LAUNCH_DEFAULT = false; private static final boolean SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT = true; Loading @@ -63,6 +82,15 @@ public final class TextClassifierConstants { private static final int CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000; private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000; private static final int GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT = 100; private static final String ENTITY_LIST_DELIMITER = ":"; private static final String ENTITY_LIST_DEFAULT_VALUE = new StringJoiner(ENTITY_LIST_DELIMITER) .add(TextClassifier.TYPE_ADDRESS) .add(TextClassifier.TYPE_EMAIL) .add(TextClassifier.TYPE_PHONE) .add(TextClassifier.TYPE_URL) .add(TextClassifier.TYPE_DATE) .add(TextClassifier.TYPE_DATE_TIME) .add(TextClassifier.TYPE_FLIGHT_NUMBER).toString(); /** Default settings. */ static final TextClassifierConstants DEFAULT = new TextClassifierConstants(); Loading @@ -74,6 +102,9 @@ public final class TextClassifierConstants { private final int mClassifyTextMaxRangeLength; private final int mGenerateLinksMaxTextLength; private final int mGenerateLinksLogSampleRate; private final List<String> mEntityListDefault; private final List<String> mEntityListNotEditable; private final List<String> mEntityListEditable; private TextClassifierConstants() { mDarkLaunch = SMART_SELECTION_DARK_LAUNCH_DEFAULT; Loading @@ -83,6 +114,9 @@ public final class TextClassifierConstants { mClassifyTextMaxRangeLength = CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT; mGenerateLinksMaxTextLength = GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT; mGenerateLinksLogSampleRate = GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT; mEntityListDefault = parseEntityList(ENTITY_LIST_DEFAULT_VALUE); mEntityListNotEditable = mEntityListDefault; mEntityListEditable = mEntityListDefault; } private TextClassifierConstants(@Nullable String settings) { Loading Loading @@ -114,9 +148,19 @@ public final class TextClassifierConstants { mGenerateLinksLogSampleRate = parser.getInt( GENERATE_LINKS_LOG_SAMPLE_RATE, GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT); mEntityListDefault = parseEntityList(parser.getString( ENTITY_LIST_DEFAULT, ENTITY_LIST_DEFAULT_VALUE)); mEntityListNotEditable = parseEntityList(parser.getString( ENTITY_LIST_NOT_EDITABLE, ENTITY_LIST_DEFAULT_VALUE)); mEntityListEditable = parseEntityList(parser.getString( ENTITY_LIST_EDITABLE, ENTITY_LIST_DEFAULT_VALUE)); } static TextClassifierConstants loadFromString(String settings) { /** Load from a settings string. */ public static TextClassifierConstants loadFromString(String settings) { return new TextClassifierConstants(settings); } Loading Loading @@ -147,4 +191,20 @@ public final class TextClassifierConstants { public int getGenerateLinksLogSampleRate() { return mGenerateLinksLogSampleRate; } public List<String> getEntityListDefault() { return mEntityListDefault; } public List<String> getEntityListNotEditable() { return mEntityListNotEditable; } public List<String> getEntityListEditable() { return mEntityListEditable; } private static List<String> parseEntityList(String listStr) { return Collections.unmodifiableList(Arrays.asList(listStr.split(ENTITY_LIST_DELIMITER))); } } core/java/android/view/textclassifier/TextClassifierImpl.java +13 −11 Original line number Diff line number Diff line Loading @@ -79,15 +79,6 @@ public final class TextClassifierImpl implements TextClassifier { private static final String MODEL_FILE_REGEX = "textclassifier\\.(.*)\\.model"; private static final String UPDATED_MODEL_FILE_PATH = "/data/misc/textclassifier/textclassifier.model"; private static final List<String> ENTITY_TYPES_ALL = Collections.unmodifiableList(Arrays.asList( TextClassifier.TYPE_ADDRESS, TextClassifier.TYPE_EMAIL, TextClassifier.TYPE_PHONE, TextClassifier.TYPE_URL, TextClassifier.TYPE_DATE, TextClassifier.TYPE_DATE_TIME, TextClassifier.TYPE_FLIGHT_NUMBER)); private final Context mContext; private final TextClassifier mFallback; Loading Loading @@ -235,7 +226,7 @@ public final class TextClassifierImpl implements TextClassifier { options != null && options.getEntityConfig() != null ? options.getEntityConfig().resolveEntityListModifications( getEntitiesForHints(options.getEntityConfig().getHints())) : ENTITY_TYPES_ALL; : getSettings().getEntityListDefault(); final TextClassifierImplNative nativeImpl = getNative(defaultLocales); final TextClassifierImplNative.AnnotatedSpan[] annotations = Loading Loading @@ -281,7 +272,18 @@ public final class TextClassifierImpl implements TextClassifier { } private Collection<String> getEntitiesForHints(Collection<String> hints) { return ENTITY_TYPES_ALL; final boolean editable = hints.contains(HINT_TEXT_IS_EDITABLE); final boolean notEditable = hints.contains(HINT_TEXT_IS_NOT_EDITABLE); // Use the default if there is no hint, or conflicting ones. final boolean useDefault = editable == notEditable; if (useDefault) { return getSettings().getEntityListDefault(); } else if (editable) { return getSettings().getEntityListEditable(); } else { // notEditable return getSettings().getEntityListNotEditable(); } } @Override Loading core/tests/coretests/src/android/view/textclassifier/TextClassifierConstantsTest.java 0 → 100644 +46 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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 org.junit.Assert.assertEquals; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidJUnit4.class) public class TextClassifierConstantsTest { @Test public void testEntityListParsing() { final TextClassifierConstants constants = TextClassifierConstants.loadFromString( "entity_list_default=phone," + "entity_list_not_editable=address:flight," + "entity_list_editable=date:datetime"); assertEquals(1, constants.getEntityListDefault().size()); assertEquals("phone", constants.getEntityListDefault().get(0)); assertEquals(2, constants.getEntityListNotEditable().size()); assertEquals("address", constants.getEntityListNotEditable().get(0)); assertEquals("flight", constants.getEntityListNotEditable().get(1)); assertEquals(2, constants.getEntityListEditable().size()); assertEquals("date", constants.getEntityListEditable().get(0)); assertEquals("datetime", constants.getEntityListEditable().get(1)); } } Loading
core/java/android/provider/Settings.java +5 −1 Original line number Diff line number Diff line Loading @@ -10471,7 +10471,8 @@ public final class Settings { /** * TextClassifier specific settings. * This is encoded as a key=value list, separated by commas. Ex: * This is encoded as a key=value list, separated by commas. String[] types like * entity_list_default use ":" as delimiter for values. Ex: * * <pre> * smart_selection_dark_launch (boolean) Loading @@ -10480,6 +10481,9 @@ public final class Settings { * 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[]) * </pre> * * <p> Loading
core/java/android/view/textclassifier/TextClassifierConstants.java +62 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ import android.annotation.Nullable; import android.util.KeyValueListParser; import android.util.Slog; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.StringJoiner; /** * TextClassifier specific settings. * This is encoded as a key=value list, separated by commas. Ex: Loading @@ -27,6 +32,12 @@ import android.util.Slog; * <pre> * smart_selection_dark_launch (boolean) * smart_selection_enabled_for_edit_text (boolean) * suggest_selection_max_range_length (int) * classify_text_max_range_length (int) * generate_links_max_text_length (int) * entity_list_default (String[]) * entity_list_not_editable (String[]) * entity_list_editable (String[]) * </pre> * * <p> Loading @@ -34,7 +45,9 @@ import android.util.Slog; * see also android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS * * Example of setting the values for testing. * adb shell settings put global text_classifier_constants smart_selection_dark_launch=true,smart_selection_enabled_for_edit_text=true * adb shell settings put global text_classifier_constants \ * smart_selection_dark_launch=true,smart_selection_enabled_for_edit_text=true,\ * entity_list_default=phone:address * @hide */ public final class TextClassifierConstants { Loading @@ -55,6 +68,12 @@ public final class TextClassifierConstants { "generate_links_max_text_length"; 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"; private static final boolean SMART_SELECTION_DARK_LAUNCH_DEFAULT = false; private static final boolean SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT = true; Loading @@ -63,6 +82,15 @@ public final class TextClassifierConstants { private static final int CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000; private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000; private static final int GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT = 100; private static final String ENTITY_LIST_DELIMITER = ":"; private static final String ENTITY_LIST_DEFAULT_VALUE = new StringJoiner(ENTITY_LIST_DELIMITER) .add(TextClassifier.TYPE_ADDRESS) .add(TextClassifier.TYPE_EMAIL) .add(TextClassifier.TYPE_PHONE) .add(TextClassifier.TYPE_URL) .add(TextClassifier.TYPE_DATE) .add(TextClassifier.TYPE_DATE_TIME) .add(TextClassifier.TYPE_FLIGHT_NUMBER).toString(); /** Default settings. */ static final TextClassifierConstants DEFAULT = new TextClassifierConstants(); Loading @@ -74,6 +102,9 @@ public final class TextClassifierConstants { private final int mClassifyTextMaxRangeLength; private final int mGenerateLinksMaxTextLength; private final int mGenerateLinksLogSampleRate; private final List<String> mEntityListDefault; private final List<String> mEntityListNotEditable; private final List<String> mEntityListEditable; private TextClassifierConstants() { mDarkLaunch = SMART_SELECTION_DARK_LAUNCH_DEFAULT; Loading @@ -83,6 +114,9 @@ public final class TextClassifierConstants { mClassifyTextMaxRangeLength = CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT; mGenerateLinksMaxTextLength = GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT; mGenerateLinksLogSampleRate = GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT; mEntityListDefault = parseEntityList(ENTITY_LIST_DEFAULT_VALUE); mEntityListNotEditable = mEntityListDefault; mEntityListEditable = mEntityListDefault; } private TextClassifierConstants(@Nullable String settings) { Loading Loading @@ -114,9 +148,19 @@ public final class TextClassifierConstants { mGenerateLinksLogSampleRate = parser.getInt( GENERATE_LINKS_LOG_SAMPLE_RATE, GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT); mEntityListDefault = parseEntityList(parser.getString( ENTITY_LIST_DEFAULT, ENTITY_LIST_DEFAULT_VALUE)); mEntityListNotEditable = parseEntityList(parser.getString( ENTITY_LIST_NOT_EDITABLE, ENTITY_LIST_DEFAULT_VALUE)); mEntityListEditable = parseEntityList(parser.getString( ENTITY_LIST_EDITABLE, ENTITY_LIST_DEFAULT_VALUE)); } static TextClassifierConstants loadFromString(String settings) { /** Load from a settings string. */ public static TextClassifierConstants loadFromString(String settings) { return new TextClassifierConstants(settings); } Loading Loading @@ -147,4 +191,20 @@ public final class TextClassifierConstants { public int getGenerateLinksLogSampleRate() { return mGenerateLinksLogSampleRate; } public List<String> getEntityListDefault() { return mEntityListDefault; } public List<String> getEntityListNotEditable() { return mEntityListNotEditable; } public List<String> getEntityListEditable() { return mEntityListEditable; } private static List<String> parseEntityList(String listStr) { return Collections.unmodifiableList(Arrays.asList(listStr.split(ENTITY_LIST_DELIMITER))); } }
core/java/android/view/textclassifier/TextClassifierImpl.java +13 −11 Original line number Diff line number Diff line Loading @@ -79,15 +79,6 @@ public final class TextClassifierImpl implements TextClassifier { private static final String MODEL_FILE_REGEX = "textclassifier\\.(.*)\\.model"; private static final String UPDATED_MODEL_FILE_PATH = "/data/misc/textclassifier/textclassifier.model"; private static final List<String> ENTITY_TYPES_ALL = Collections.unmodifiableList(Arrays.asList( TextClassifier.TYPE_ADDRESS, TextClassifier.TYPE_EMAIL, TextClassifier.TYPE_PHONE, TextClassifier.TYPE_URL, TextClassifier.TYPE_DATE, TextClassifier.TYPE_DATE_TIME, TextClassifier.TYPE_FLIGHT_NUMBER)); private final Context mContext; private final TextClassifier mFallback; Loading Loading @@ -235,7 +226,7 @@ public final class TextClassifierImpl implements TextClassifier { options != null && options.getEntityConfig() != null ? options.getEntityConfig().resolveEntityListModifications( getEntitiesForHints(options.getEntityConfig().getHints())) : ENTITY_TYPES_ALL; : getSettings().getEntityListDefault(); final TextClassifierImplNative nativeImpl = getNative(defaultLocales); final TextClassifierImplNative.AnnotatedSpan[] annotations = Loading Loading @@ -281,7 +272,18 @@ public final class TextClassifierImpl implements TextClassifier { } private Collection<String> getEntitiesForHints(Collection<String> hints) { return ENTITY_TYPES_ALL; final boolean editable = hints.contains(HINT_TEXT_IS_EDITABLE); final boolean notEditable = hints.contains(HINT_TEXT_IS_NOT_EDITABLE); // Use the default if there is no hint, or conflicting ones. final boolean useDefault = editable == notEditable; if (useDefault) { return getSettings().getEntityListDefault(); } else if (editable) { return getSettings().getEntityListEditable(); } else { // notEditable return getSettings().getEntityListNotEditable(); } } @Override Loading
core/tests/coretests/src/android/view/textclassifier/TextClassifierConstantsTest.java 0 → 100644 +46 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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 org.junit.Assert.assertEquals; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidJUnit4.class) public class TextClassifierConstantsTest { @Test public void testEntityListParsing() { final TextClassifierConstants constants = TextClassifierConstants.loadFromString( "entity_list_default=phone," + "entity_list_not_editable=address:flight," + "entity_list_editable=date:datetime"); assertEquals(1, constants.getEntityListDefault().size()); assertEquals("phone", constants.getEntityListDefault().get(0)); assertEquals(2, constants.getEntityListNotEditable().size()); assertEquals("address", constants.getEntityListNotEditable().get(0)); assertEquals("flight", constants.getEntityListNotEditable().get(1)); assertEquals(2, constants.getEntityListEditable().size()); assertEquals("date", constants.getEntityListEditable().get(0)); assertEquals("datetime", constants.getEntityListEditable().get(1)); } }