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

Commit 66c16273 authored by Abodunrinwa Toki's avatar Abodunrinwa Toki
Browse files

Only classify text when the toolbar is shown.

classifyText() is used to generate a menu item in the selection toolbar
to handle the selected text. In this cl we avoid calling classifyText()
when the selection is changing but instead call it when we are about to
show the toolbar.

Previously, we depended on invalidateActionModeAsync() to classify text
after a call to startActionMode(). Now that we've introduced
invalidateActionMode() we need to be able to tell
startSelectionActionMode() that we also want the text to be classified,
hence the introduction of an input parameter, "adjustSelection", to
startSelectionActionModeAysnc().

Test: bit FrameworksCoreTests:android.widget.TextViewActivityTest
Bug: 34966796
Change-Id: I5b9fc9e8ab443f024f8ca461df5a4bcc6485d26b
parent df9b2e8d
Loading
Loading
Loading
Loading
+23 −21
Original line number Diff line number Diff line
@@ -1404,6 +1404,11 @@ public class Editor {
            // or double-clicks that could "dismiss" the floating toolbar.
            int delay = ViewConfiguration.getDoubleTapTimeout();
            mTextView.postDelayed(mShowFloatingToolbar, delay);

            // This classifies the text and most likely returns before the toolbar is actually
            // shown. If not, it will update the toolbar with the result when classification
            // returns. We would rather not wait for a long running classification process.
            invalidateActionModeAsync();
        }
    }

@@ -1853,7 +1858,7 @@ public class Editor {
            mInsertionPointCursorController.invalidateHandle();
        }
        if (mTextActionMode != null) {
            invalidateActionModeAsync();
            invalidateActionMode();
        }
    }

@@ -1945,12 +1950,12 @@ public class Editor {
                if (mRestartActionModeOnNextRefresh) {
                    // To avoid distraction, newly start action mode only when selection action
                    // mode is being restarted.
                    startSelectionActionMode();
                    startSelectionActionModeAsync(false);
                }
            } else if (selectionController == null || !selectionController.isActive()) {
                // Insertion action mode is active. Avoid dismissing the selection.
                stopTextActionModeWithPreservingSelection();
                startSelectionActionMode();
                startSelectionActionModeAsync(false);
            } else {
                mTextActionMode.invalidateContentRect();
            }
@@ -2004,22 +2009,24 @@ public class Editor {
    /**
     * Asynchronously starts a selection action mode using the TextClassifier.
     */
    void startSelectionActionModeAsync() {
        getSelectionActionModeHelper().startActionModeAsync();
    void startSelectionActionModeAsync(boolean adjustSelection) {
        getSelectionActionModeHelper().startActionModeAsync(adjustSelection);
    }

    /**
     * Synchronously starts a selection action mode without the TextClassifier.
     * Asynchronously invalidates an action mode using the TextClassifier.
     */
    void startSelectionActionMode() {
        getSelectionActionModeHelper().startActionMode();
    private void invalidateActionModeAsync() {
        getSelectionActionModeHelper().invalidateActionModeAsync();
    }

    /**
     * Asynchronously invalidates an action mode using the TextClassifier.
     * Synchronously invalidates an action mode without the TextClassifier.
     */
    private void invalidateActionModeAsync() {
        getSelectionActionModeHelper().invalidateActionModeAsync();
    private void invalidateActionMode() {
        if (mTextActionMode != null) {
            mTextActionMode.invalidate();
        }
    }

    private SelectionActionModeHelper getSelectionActionModeHelper() {
@@ -2075,7 +2082,7 @@ public class Editor {
        }
        if (mTextActionMode != null) {
            // Text action mode is already started
            invalidateActionModeAsync();
            invalidateActionMode();
            return false;
        }

@@ -4703,7 +4710,7 @@ public class Editor {
            }
            positionAtCursorOffset(offset, false);
            if (mTextActionMode != null) {
                invalidateActionModeAsync();
                invalidateActionMode();
            }
        }

@@ -4787,7 +4794,7 @@ public class Editor {
            }
            updateDrawable();
            if (mTextActionMode != null) {
                invalidateActionModeAsync();
                invalidateActionMode();
            }
        }

@@ -5414,13 +5421,8 @@ public class Editor {
                    resetDragAcceleratorState();

                    if (mTextView.hasSelection()) {
                        // Do not invoke the text assistant if this was a drag selection.
                        if (mHaventMovedEnoughToStartDrag) {
                            startSelectionActionModeAsync();
                        } else {
                            startSelectionActionMode();
                        }

                        // Drag selection should not be adjusted by the text classifier.
                        startSelectionActionModeAsync(mHaventMovedEnoughToStartDrag);
                    }
                    break;
            }
+7 −7
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ final class SelectionActionModeHelper {
                textView.getTextClassifier(), textView.getText(), 0, 1, textView.getTextLocales());
    }

    public void startActionModeAsync() {
    public void startActionModeAsync(boolean adjustSelection) {
        cancelAsyncTask();
        if (isNoOpTextClassifier() || !hasSelection()) {
            // No need to make an async call for a no-op TextClassifier.
@@ -74,16 +74,16 @@ final class SelectionActionModeHelper {
        } else {
            resetTextClassificationHelper();
            mTextClassificationAsyncTask = new TextClassificationAsyncTask(
                    mEditor.getTextView(), TIMEOUT_DURATION,
                    mTextClassificationHelper::suggestSelection, this::startActionMode)
                    mEditor.getTextView(),
                    TIMEOUT_DURATION,
                    adjustSelection
                            ? mTextClassificationHelper::suggestSelection
                            : mTextClassificationHelper::classifyText,
                    this::startActionMode)
                    .execute();
        }
    }

    public void startActionMode() {
        startActionMode(null);
    }

    public void invalidateActionModeAsync() {
        cancelAsyncTask();
        if (isNoOpTextClassifier() || !hasSelection()) {
+1 −1
Original line number Diff line number Diff line
@@ -10579,7 +10579,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                        Selection.setSelection((Spannable) text, start, end);
                        // Make sure selection mode is engaged.
                        if (mEditor != null) {
                            mEditor.startSelectionActionMode();
                            mEditor.startSelectionActionModeAsync(false);
                        }
                        return true;
                    }