diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index ad3a99d3610ff..b0d63951971bd 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -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,15 +2009,8 @@ public class Editor { /** * Asynchronously starts a selection action mode using the TextClassifier. */ - void startSelectionActionModeAsync() { - getSelectionActionModeHelper().startActionModeAsync(); - } - - /** - * Synchronously starts a selection action mode without the TextClassifier. - */ - void startSelectionActionMode() { - getSelectionActionModeHelper().startActionMode(); + void startSelectionActionModeAsync(boolean adjustSelection) { + getSelectionActionModeHelper().startActionModeAsync(adjustSelection); } /** @@ -2022,6 +2020,15 @@ public class Editor { getSelectionActionModeHelper().invalidateActionModeAsync(); } + /** + * Synchronously invalidates an action mode without the TextClassifier. + */ + private void invalidateActionMode() { + if (mTextActionMode != null) { + mTextActionMode.invalidate(); + } + } + private SelectionActionModeHelper getSelectionActionModeHelper() { if (mSelectionActionModeHelper == null) { mSelectionActionModeHelper = new SelectionActionModeHelper(this); @@ -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; } diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index c9d172fa78b5a..16a1087510d3f 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -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()) { diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 242dcf535d327..eaf1115215744 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -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; }