From 66c162730190db1079987ff456c7f1c0d522a20e Mon Sep 17 00:00:00 2001 From: Abodunrinwa Toki Date: Wed, 3 May 2017 20:22:55 +0100 Subject: [PATCH] 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 --- core/java/android/widget/Editor.java | 46 ++++++++++--------- .../widget/SelectionActionModeHelper.java | 14 +++--- core/java/android/widget/TextView.java | 2 +- 3 files changed, 32 insertions(+), 30 deletions(-) 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; }