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

Commit 2a86655b authored by Abodunrinwa Toki's avatar Abodunrinwa Toki Committed by android-build-merger
Browse files

Merge "Flags to enable/disable smart selection in EditText" into oc-mr1-dev

am: 14ba6e10

Change-Id: I0ddb7b827ad8b0be37c7e1adc5a95493bd35d61f
parents ba714b38 14ba6e10
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -9543,6 +9543,22 @@ public final class Settings {
         */
        public static final String DEVICE_POLICY_CONSTANTS = "device_policy_constants";

        /**
         * TextClassifier specific settings.
         * This is encoded as a key=value list, separated by commas. Ex:
         *
         * <pre>
         * smart_selection_dark_launch              (boolean)
         * smart_selection_enabled_for_edit_text    (boolean)
         * </pre>
         *
         * <p>
         * Type: string
         * @hide
         * see also android.view.textclassifier.TextClassifierConstants
         */
        public static final String TEXT_CLASSIFIER_CONSTANTS = "text_classifier_constants";

        /**
         * Get the key that retrieves a bluetooth headset's priority.
         * @hide
+8 −0
Original line number Diff line number Diff line
@@ -152,4 +152,12 @@ public interface TextClassifier {
     */
    @WorkerThread
    default void logEvent(String source, String event) {}

    /**
     * Returns this TextClassifier's settings.
     * @hide
     */
    default TextClassifierConstants getSettings() {
        return TextClassifierConstants.DEFAULT;
    }
}
+90 −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 android.annotation.Nullable;
import android.util.KeyValueListParser;
import android.util.Slog;

/**
 * TextClassifier specific settings.
 * This is encoded as a key=value list, separated by commas. Ex:
 *
 * <pre>
 * smart_selection_dark_launch              (boolean)
 * smart_selection_enabled_for_edit_text    (boolean)
 * </pre>
 *
 * <p>
 * Type: string
 * 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
 * @hide
 */
public final class TextClassifierConstants {

    private static final String LOG_TAG = "TextClassifierConstants";

    private static final String SMART_SELECTION_DARK_LAUNCH =
            "smart_selection_dark_launch";
    private static final String SMART_SELECTION_ENABLED_FOR_EDIT_TEXT =
            "smart_selection_enabled_for_edit_text";

    private static final boolean SMART_SELECTION_DARK_LAUNCH_DEFAULT = false;
    private static final boolean SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT = true;

    /** Default settings. */
    static final TextClassifierConstants DEFAULT = new TextClassifierConstants();

    private final boolean mDarkLaunch;
    private final boolean mSuggestSelectionEnabledForEditableText;

    private TextClassifierConstants() {
        mDarkLaunch = SMART_SELECTION_DARK_LAUNCH_DEFAULT;
        mSuggestSelectionEnabledForEditableText = SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT;
    }

    private TextClassifierConstants(@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);
        }
        mDarkLaunch = parser.getBoolean(
                SMART_SELECTION_DARK_LAUNCH,
                SMART_SELECTION_DARK_LAUNCH_DEFAULT);
        mSuggestSelectionEnabledForEditableText = parser.getBoolean(
                SMART_SELECTION_ENABLED_FOR_EDIT_TEXT,
                SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT);
    }

    static TextClassifierConstants loadFromString(String settings) {
        return new TextClassifierConstants(settings);
    }

    public boolean isDarkLaunch() {
        return mDarkLaunch;
    }

    public boolean isSuggestSelectionEnabledForEditableText() {
        return mSuggestSelectionEnabledForEditableText;
    }
}
+13 −1
Original line number Diff line number Diff line
@@ -24,11 +24,11 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.icu.text.BreakIterator;
import android.net.Uri;
import android.os.LocaleList;
import android.os.ParcelFileDescriptor;
import android.provider.Browser;
import android.provider.Settings;
import android.text.Spannable;
import android.text.TextUtils;
import android.text.method.WordIterator;
@@ -46,6 +46,7 @@ import com.android.internal.util.Preconditions;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -90,6 +91,8 @@ final class TextClassifierImpl implements TextClassifier {
    @GuardedBy("mSmartSelectionLock") // Do not access outside this lock.
    private SmartSelection mSmartSelection;

    private TextClassifierConstants mSettings;

    TextClassifierImpl(Context context) {
        mContext = Preconditions.checkNotNull(context);
    }
@@ -188,6 +191,15 @@ final class TextClassifierImpl implements TextClassifier {
        }
    }

    @Override
    public TextClassifierConstants getSettings() {
        if (mSettings == null) {
            mSettings = TextClassifierConstants.loadFromString(Settings.Global.getString(
                    mContext.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
        }
        return mSettings;
    }

    private SmartSelection getSmartSelection(LocaleList localeList) throws FileNotFoundException {
        synchronized (mSmartSelectionLock) {
            localeList = localeList == null ? LocaleList.getEmptyLocaleList() : localeList;
+20 −10
Original line number Diff line number Diff line
@@ -71,11 +71,15 @@ final class SelectionActionModeHelper {
    }

    public void startActionModeAsync(boolean adjustSelection) {
        // Check if the smart selection should run for editable text.
        adjustSelection &= !mTextView.isTextEditable()
                || mTextView.getTextClassifier().getSettings()
                        .isSuggestSelectionEnabledForEditableText();

        mSelectionTracker.onOriginalSelection(
                getText(mTextView),
                mTextView.getSelectionStart(),
                mTextView.getSelectionEnd(),
                mTextView.isTextEditable());
                mTextView.getSelectionEnd());
        cancelAsyncTask();
        if (skipTextClassification()) {
            startActionMode(null);
@@ -163,7 +167,10 @@ final class SelectionActionModeHelper {
    private void startActionMode(@Nullable SelectionResult result) {
        final CharSequence text = getText(mTextView);
        if (result != null && text instanceof Spannable) {
            // Do not change the selection if TextClassifier should be dark launched.
            if (!mTextView.getTextClassifier().getSettings().isDarkLaunch()) {
                Selection.setSelection((Spannable) text, result.mStart, result.mEnd);
            }
            mTextClassification = result.mClassification;
        } else {
            mTextClassification = null;
@@ -193,7 +200,7 @@ final class SelectionActionModeHelper {
    }

    private void resetTextClassificationHelper() {
        mTextClassificationHelper.reset(
        mTextClassificationHelper.init(
                mTextView.getTextClassifier(),
                getText(mTextView),
                mTextView.getSelectionStart(), mTextView.getSelectionEnd(),
@@ -225,8 +232,7 @@ final class SelectionActionModeHelper {
        /**
         * Called when the original selection happens, before smart selection is triggered.
         */
        public void onOriginalSelection(
                CharSequence text, int selectionStart, int selectionEnd, boolean editableText) {
        public void onOriginalSelection(CharSequence text, int selectionStart, int selectionEnd) {
            // If we abandoned a selection and created a new one very shortly after, we may still
            // have a pending request to log ABANDON, which we flush here.
            mDelayedLogAbandon.flush();
@@ -622,11 +628,11 @@ final class SelectionActionModeHelper {

        TextClassificationHelper(TextClassifier textClassifier,
                CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
            reset(textClassifier, text, selectionStart, selectionEnd, locales);
            init(textClassifier, text, selectionStart, selectionEnd, locales);
        }

        @UiThread
        public void reset(TextClassifier textClassifier,
        public void init(TextClassifier textClassifier,
                CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
            mTextClassifier = Preconditions.checkNotNull(textClassifier);
            mText = Preconditions.checkNotNull(text).toString();
@@ -649,8 +655,12 @@ final class SelectionActionModeHelper {
            trimText();
            final TextSelection selection = mTextClassifier.suggestSelection(
                    mTrimmedText, mRelativeStart, mRelativeEnd, mLocales);
            // Do not classify new selection boundaries if TextClassifier should be dark launched.
            if (!mTextClassifier.getSettings().isDarkLaunch()) {
                mSelectionStart = Math.max(0, selection.getSelectionStartIndex() + mTrimStart);
            mSelectionEnd = Math.min(mText.length(), selection.getSelectionEndIndex() + mTrimStart);
                mSelectionEnd = Math.min(
                        mText.length(), selection.getSelectionEndIndex() + mTrimStart);
            }
            return performClassification(selection);
        }

Loading