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

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

Merge "Refresh TCM settings when they change" into pi-dev

am: 3fa56403

Change-Id: Ia8c3f5844dc908f2fb7671182bcc683850cf69d0
parents 20e63f96 3fa56403
Loading
Loading
Loading
Loading
+77 −21
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.annotation.SystemService;
import android.annotation.SystemService;
import android.content.Context;
import android.content.Context;
import android.database.ContentObserver;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.provider.Settings;
import android.provider.Settings;
import android.service.textclassifier.TextClassifierService;
import android.service.textclassifier.TextClassifierService;
@@ -28,6 +29,8 @@ import android.view.textclassifier.TextClassifier.TextClassifierType;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import com.android.internal.util.Preconditions;


import java.lang.ref.WeakReference;

/**
/**
 * Interface to the text classification service.
 * Interface to the text classification service.
 */
 */
@@ -42,23 +45,27 @@ public final class TextClassificationManager {
                    classificationContext, getTextClassifier());
                    classificationContext, getTextClassifier());


    private final Context mContext;
    private final Context mContext;
    private final TextClassificationConstants mSettings;
    private final SettingsObserver mSettingsObserver;


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private TextClassifier mTextClassifier;
    @Nullable
    private TextClassifier mCustomTextClassifier;
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    @Nullable
    private TextClassifier mLocalTextClassifier;
    private TextClassifier mLocalTextClassifier;
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    @Nullable
    private TextClassifier mSystemTextClassifier;
    private TextClassifier mSystemTextClassifier;
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private TextClassificationSessionFactory mSessionFactory;
    private TextClassificationSessionFactory mSessionFactory;
    @GuardedBy("mLock")
    private TextClassificationConstants mSettings;


    /** @hide */
    /** @hide */
    public TextClassificationManager(Context context) {
    public TextClassificationManager(Context context) {
        mContext = Preconditions.checkNotNull(context);
        mContext = Preconditions.checkNotNull(context);
        mSettings = TextClassificationConstants.loadFromString(Settings.Global.getString(
                context.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
        mSessionFactory = mDefaultSessionFactory;
        mSessionFactory = mDefaultSessionFactory;
        mSettingsObserver = new SettingsObserver(this);
    }
    }


    /**
    /**
@@ -71,14 +78,13 @@ public final class TextClassificationManager {
    @NonNull
    @NonNull
    public TextClassifier getTextClassifier() {
    public TextClassifier getTextClassifier() {
        synchronized (mLock) {
        synchronized (mLock) {
            if (mTextClassifier == null) {
            if (mCustomTextClassifier != null) {
                if (isSystemTextClassifierEnabled()) {
                return mCustomTextClassifier;
                    mTextClassifier = getSystemTextClassifier();
            } else if (isSystemTextClassifierEnabled()) {
                return getSystemTextClassifier();
            } else {
            } else {
                    mTextClassifier = getLocalTextClassifier();
                return getLocalTextClassifier();
                }
            }
            }
            return mTextClassifier;
        }
        }
    }
    }


@@ -89,7 +95,7 @@ public final class TextClassificationManager {
     */
     */
    public void setTextClassifier(@Nullable TextClassifier textClassifier) {
    public void setTextClassifier(@Nullable TextClassifier textClassifier) {
        synchronized (mLock) {
        synchronized (mLock) {
            mTextClassifier = textClassifier;
            mCustomTextClassifier = textClassifier;
        }
        }
    }
    }


@@ -110,10 +116,16 @@ public final class TextClassificationManager {
        }
        }
    }
    }


    /** @hide */
    private TextClassificationConstants getSettings() {
    public TextClassificationConstants getSettings() {
        synchronized (mLock) {
            if (mSettings == null) {
                mSettings = TextClassificationConstants.loadFromString(Settings.Global.getString(
                        mContext.getApplicationContext().getContentResolver(),
                        Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
            }
            return mSettings;
            return mSettings;
        }
        }
    }


    /**
    /**
     * Call this method to start a text classification session with the given context.
     * Call this method to start a text classification session with the given context.
@@ -170,11 +182,24 @@ public final class TextClassificationManager {
        }
        }
    }
    }


    @Override
    protected void finalize() throws Throwable {
        try {
            // Note that fields could be null if the constructor threw.
            if (mContext != null && mSettingsObserver != null) {
                mContext.getApplicationContext().getContentResolver()
                        .unregisterContentObserver(mSettingsObserver);
            }
        } finally {
            super.finalize();
        }
    }

    private TextClassifier getSystemTextClassifier() {
    private TextClassifier getSystemTextClassifier() {
        synchronized (mLock) {
        synchronized (mLock) {
            if (mSystemTextClassifier == null && isSystemTextClassifierEnabled()) {
            if (mSystemTextClassifier == null && isSystemTextClassifierEnabled()) {
                try {
                try {
                    mSystemTextClassifier = new SystemTextClassifier(mContext, mSettings);
                    mSystemTextClassifier = new SystemTextClassifier(mContext, getSettings());
                    Log.d(LOG_TAG, "Initialized SystemTextClassifier");
                    Log.d(LOG_TAG, "Initialized SystemTextClassifier");
                } catch (ServiceManager.ServiceNotFoundException e) {
                } catch (ServiceManager.ServiceNotFoundException e) {
                    Log.e(LOG_TAG, "Could not initialize SystemTextClassifier", e);
                    Log.e(LOG_TAG, "Could not initialize SystemTextClassifier", e);
@@ -190,9 +215,9 @@ public final class TextClassificationManager {
    private TextClassifier getLocalTextClassifier() {
    private TextClassifier getLocalTextClassifier() {
        synchronized (mLock) {
        synchronized (mLock) {
            if (mLocalTextClassifier == null) {
            if (mLocalTextClassifier == null) {
                if (mSettings.isLocalTextClassifierEnabled()) {
                if (getSettings().isLocalTextClassifierEnabled()) {
                    mLocalTextClassifier =
                    mLocalTextClassifier =
                            new TextClassifierImpl(mContext, mSettings, TextClassifier.NO_OP);
                            new TextClassifierImpl(mContext, getSettings(), TextClassifier.NO_OP);
                } else {
                } else {
                    Log.d(LOG_TAG, "Local TextClassifier disabled");
                    Log.d(LOG_TAG, "Local TextClassifier disabled");
                    mLocalTextClassifier = TextClassifier.NO_OP;
                    mLocalTextClassifier = TextClassifier.NO_OP;
@@ -203,20 +228,51 @@ public final class TextClassificationManager {
    }
    }


    private boolean isSystemTextClassifierEnabled() {
    private boolean isSystemTextClassifierEnabled() {
        return mSettings.isSystemTextClassifierEnabled()
        return getSettings().isSystemTextClassifierEnabled()
                && TextClassifierService.getServiceComponentName(mContext) != null;
                && TextClassifierService.getServiceComponentName(mContext) != null;
    }
    }


    private void invalidate() {
        synchronized (mLock) {
            mSettings = null;
            mLocalTextClassifier = null;
            mSystemTextClassifier = null;
        }
    }

    /** @hide */
    /** @hide */
    public static TextClassificationConstants getSettings(Context context) {
    public static TextClassificationConstants getSettings(Context context) {
        Preconditions.checkNotNull(context);
        Preconditions.checkNotNull(context);
        final TextClassificationManager tcm =
        final TextClassificationManager tcm =
                context.getSystemService(TextClassificationManager.class);
                context.getSystemService(TextClassificationManager.class);
        if (tcm != null) {
        if (tcm != null) {
            return tcm.mSettings;
            return tcm.getSettings();
        } else {
        } else {
            return TextClassificationConstants.loadFromString(Settings.Global.getString(
            return TextClassificationConstants.loadFromString(Settings.Global.getString(
                    context.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
                    context.getApplicationContext().getContentResolver(),
                    Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
        }
    }

    private static final class SettingsObserver extends ContentObserver {

        private final WeakReference<TextClassificationManager> mTcm;

        SettingsObserver(TextClassificationManager tcm) {
            super(null);
            mTcm = new WeakReference<>(tcm);
            tcm.mContext.getApplicationContext().getContentResolver().registerContentObserver(
                    Settings.Global.getUriFor(Settings.Global.TEXT_CLASSIFIER_CONSTANTS),
                    false /* notifyForDescendants */,
                    this);
        }

        @Override
        public void onChange(boolean selfChange) {
            final TextClassificationManager tcm = mTcm.get();
            if (tcm != null) {
                tcm.invalidate();
            }
        }
        }
    }
    }
}
}
+12 −9
Original line number Original line Diff line number Diff line
@@ -70,7 +70,6 @@ public final class SelectionActionModeHelper {
    private final Editor mEditor;
    private final Editor mEditor;
    private final TextView mTextView;
    private final TextView mTextView;
    private final TextClassificationHelper mTextClassificationHelper;
    private final TextClassificationHelper mTextClassificationHelper;
    private final TextClassificationConstants mTextClassificationSettings;


    @Nullable private TextClassification mTextClassification;
    @Nullable private TextClassification mTextClassification;
    private AsyncTask mTextClassificationAsyncTask;
    private AsyncTask mTextClassificationAsyncTask;
@@ -84,7 +83,6 @@ public final class SelectionActionModeHelper {
    SelectionActionModeHelper(@NonNull Editor editor) {
    SelectionActionModeHelper(@NonNull Editor editor) {
        mEditor = Preconditions.checkNotNull(editor);
        mEditor = Preconditions.checkNotNull(editor);
        mTextView = mEditor.getTextView();
        mTextView = mEditor.getTextView();
        mTextClassificationSettings = TextClassificationManager.getSettings(mTextView.getContext());
        mTextClassificationHelper = new TextClassificationHelper(
        mTextClassificationHelper = new TextClassificationHelper(
                mTextView.getContext(),
                mTextView.getContext(),
                mTextView::getTextClassifier,
                mTextView::getTextClassifier,
@@ -92,7 +90,7 @@ public final class SelectionActionModeHelper {
                0, 1, mTextView.getTextLocales());
                0, 1, mTextView.getTextLocales());
        mSelectionTracker = new SelectionTracker(mTextView);
        mSelectionTracker = new SelectionTracker(mTextView);


        if (mTextClassificationSettings.isSmartSelectionAnimationEnabled()) {
        if (getTextClassificationSettings().isSmartSelectionAnimationEnabled()) {
            mSmartSelectSprite = new SmartSelectSprite(mTextView.getContext(),
            mSmartSelectSprite = new SmartSelectSprite(mTextView.getContext(),
                    editor.getTextView().mHighlightColor, mTextView::invalidate);
                    editor.getTextView().mHighlightColor, mTextView::invalidate);
        } else {
        } else {
@@ -105,7 +103,7 @@ public final class SelectionActionModeHelper {
     */
     */
    public void startSelectionActionModeAsync(boolean adjustSelection) {
    public void startSelectionActionModeAsync(boolean adjustSelection) {
        // Check if the smart selection should run for editable text.
        // Check if the smart selection should run for editable text.
        adjustSelection &= mTextClassificationSettings.isSmartSelectionEnabled();
        adjustSelection &= getTextClassificationSettings().isSmartSelectionEnabled();


        mSelectionTracker.onOriginalSelection(
        mSelectionTracker.onOriginalSelection(
                getText(mTextView),
                getText(mTextView),
@@ -212,6 +210,10 @@ public final class SelectionActionModeHelper {
        return mSmartSelectSprite != null && mSmartSelectSprite.isAnimationActive();
        return mSmartSelectSprite != null && mSmartSelectSprite.isAnimationActive();
    }
    }


    private TextClassificationConstants getTextClassificationSettings() {
        return TextClassificationManager.getSettings(mTextView.getContext());
    }

    private void cancelAsyncTask() {
    private void cancelAsyncTask() {
        if (mTextClassificationAsyncTask != null) {
        if (mTextClassificationAsyncTask != null) {
            mTextClassificationAsyncTask.cancel(true);
            mTextClassificationAsyncTask.cancel(true);
@@ -245,7 +247,7 @@ public final class SelectionActionModeHelper {
        if (result != null && text instanceof Spannable
        if (result != null && text instanceof Spannable
                && (mTextView.isTextSelectable() || mTextView.isTextEditable())) {
                && (mTextView.isTextSelectable() || mTextView.isTextEditable())) {
            // Do not change the selection if TextClassifier should be dark launched.
            // Do not change the selection if TextClassifier should be dark launched.
            if (!mTextClassificationSettings.isModelDarkLaunchEnabled()) {
            if (!getTextClassificationSettings().isModelDarkLaunchEnabled()) {
                Selection.setSelection((Spannable) text, result.mStart, result.mEnd);
                Selection.setSelection((Spannable) text, result.mStart, result.mEnd);
                mTextView.invalidate();
                mTextView.invalidate();
            }
            }
@@ -906,7 +908,6 @@ public final class SelectionActionModeHelper {
        private static final int TRIM_DELTA = 120;  // characters
        private static final int TRIM_DELTA = 120;  // characters


        private final Context mContext;
        private final Context mContext;
        private final boolean mDarkLaunchEnabled;
        private Supplier<TextClassifier> mTextClassifier;
        private Supplier<TextClassifier> mTextClassifier;


        /** The original TextView text. **/
        /** The original TextView text. **/
@@ -942,8 +943,6 @@ public final class SelectionActionModeHelper {
                CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
                CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
            init(textClassifier, text, selectionStart, selectionEnd, locales);
            init(textClassifier, text, selectionStart, selectionEnd, locales);
            mContext = Preconditions.checkNotNull(context);
            mContext = Preconditions.checkNotNull(context);
            mDarkLaunchEnabled = TextClassificationManager.getSettings(mContext)
                    .isModelDarkLaunchEnabled();
        }
        }


        @UiThread
        @UiThread
@@ -982,7 +981,7 @@ public final class SelectionActionModeHelper {
                        mTrimmedText, mRelativeStart, mRelativeEnd, mDefaultLocales);
                        mTrimmedText, mRelativeStart, mRelativeEnd, mDefaultLocales);
            }
            }
            // Do not classify new selection boundaries if TextClassifier should be dark launched.
            // Do not classify new selection boundaries if TextClassifier should be dark launched.
            if (!mDarkLaunchEnabled) {
            if (!isDarkLaunchEnabled()) {
                mSelectionStart = Math.max(0, selection.getSelectionStartIndex() + mTrimStart);
                mSelectionStart = Math.max(0, selection.getSelectionStartIndex() + mTrimStart);
                mSelectionEnd = Math.min(
                mSelectionEnd = Math.min(
                        mText.length(), selection.getSelectionEndIndex() + mTrimStart);
                        mText.length(), selection.getSelectionEndIndex() + mTrimStart);
@@ -1010,6 +1009,10 @@ public final class SelectionActionModeHelper {
            }
            }
        }
        }


        private boolean isDarkLaunchEnabled() {
            return TextClassificationManager.getSettings(mContext).isModelDarkLaunchEnabled();
        }

        private SelectionResult performClassification(@Nullable TextSelection selection) {
        private SelectionResult performClassification(@Nullable TextSelection selection) {
            if (!Objects.equals(mText, mLastClassificationText)
            if (!Objects.equals(mText, mLastClassificationText)
                    || mSelectionStart != mLastClassificationSelectionStart
                    || mSelectionStart != mLastClassificationSelectionStart