Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0aacdb66 authored by Jan Althaus's avatar Jan Althaus
Browse files

Make default entity lists flag configurable

Bug: 73277686
Test: bit CtsViewTestCases:android.view.textclassifier.cts
CtsTextTestCases:android.text.util.cts
FrameworksCoreTests:android.view.textclassifier
Change-Id: I84be54fb407088ee25c3ba2d4d62708a898621ad
parent b3d049c2
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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)
@@ -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>
+62 −2
Original line number Diff line number Diff line
@@ -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:
@@ -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>
@@ -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 {
@@ -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;
@@ -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();
@@ -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;
@@ -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) {
@@ -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);
    }

@@ -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)));
    }
}
+13 −11
Original line number Diff line number Diff line
@@ -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;
@@ -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 =
@@ -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
+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));
    }
}