From be60f06a1beb4f1f8050dc975e76232cc9bde652 Mon Sep 17 00:00:00 2001 From: Abodunrinwa Toki Date: Wed, 27 Sep 2017 02:38:55 +0100 Subject: [PATCH] Increase the duration allowed for a TC result. Increase the duration allowed for a TextClassifier (TC) result when it is being initialized for the first time. Initialization typically takes more time that other calls to the TC. A timeout during initialization means the user doesn't see the effect of running the TC the first time. Subsequent calls typically work fine as they're less likely to timeout. We increase this value only slightly because we don't want the user waiting too long for a slow TC's result. Finding the right balance is an art and most likely depends on the TC being used. Note that although a TextView's TC can change for each individual call to the TC, such a situation does not benefit from the bump in the timeout. Again, we really want to discourage larger timeouts. Fixes: 66217281 Test: bit FrameworksCoreTests:android.widget.TextViewActivityTest Test: bit CtsWidgetTestCases:android.widget.cts.TextViewTest Test: Manual test: - Delayed TextClassifier response by about 150ms (allowing only 50ms for initialization) - Before cl: Sometimes the result is not shown to the user the first time the textclassifier runs - After cl: Results consistently show for even for first textclassifier call Merged-In: Iabc8279fa57ef6a9a2db0c7e9c7e3ab8c131bf02 Change-Id: Iabc8279fa57ef6a9a2db0c7e9c7e3ab8c131bf02 --- .../widget/SelectionActionModeHelper.java | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index 6c13e0c51a466..513a18cdaf308 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -51,12 +51,6 @@ final class SelectionActionModeHelper { private static final String LOG_TAG = "SelectActionModeHelper"; - /** - * Maximum time (in milliseconds) to wait for a result before timing out. - */ - // TODO: Consider making this a ViewConfiguration. - private static final int TIMEOUT_DURATION = 200; - private final Editor mEditor; private final TextView mTextView; private final TextClassificationHelper mTextClassificationHelper; @@ -89,7 +83,7 @@ final class SelectionActionModeHelper { resetTextClassificationHelper(); mTextClassificationAsyncTask = new TextClassificationAsyncTask( mTextView, - TIMEOUT_DURATION, + mTextClassificationHelper.getTimeoutDuration(), adjustSelection ? mTextClassificationHelper::suggestSelection : mTextClassificationHelper::classifyText, @@ -106,7 +100,7 @@ final class SelectionActionModeHelper { resetTextClassificationHelper(); mTextClassificationAsyncTask = new TextClassificationAsyncTask( mTextView, - TIMEOUT_DURATION, + mTextClassificationHelper.getTimeoutDuration(), mTextClassificationHelper::classifyText, this::invalidateActionMode) .execute(); @@ -538,7 +532,7 @@ final class SelectionActionModeHelper { private static final class TextClassificationAsyncTask extends AsyncTask { - private final int mTimeOutDuration; + private final long mTimeOutDuration; private final Supplier mSelectionResultSupplier; private final Consumer mSelectionResultCallback; private final TextView mTextView; @@ -551,7 +545,7 @@ final class SelectionActionModeHelper { * @param selectionResultCallback receives the selection results. Runs on the UiThread */ TextClassificationAsyncTask( - @NonNull TextView textView, int timeOut, + @NonNull TextView textView, long timeOut, @NonNull Supplier selectionResultSupplier, @NonNull Consumer selectionResultCallback) { super(textView != null ? textView.getHandler() : null); @@ -623,6 +617,9 @@ final class SelectionActionModeHelper { private LocaleList mLastClassificationLocales; private SelectionResult mLastClassificationResult; + /** Whether the TextClassifier has been initialized. */ + private boolean mHot; + TextClassificationHelper(TextClassifier textClassifier, CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) { reset(textClassifier, text, selectionStart, selectionEnd, locales); @@ -642,11 +639,13 @@ final class SelectionActionModeHelper { @WorkerThread public SelectionResult classifyText() { - return performClassification(null); + mHot = true; + return performClassification(null /* selection */); } @WorkerThread public SelectionResult suggestSelection() { + mHot = true; trimText(); final TextSelection selection = mTextClassifier.suggestSelection( mTrimmedText, mRelativeStart, mRelativeEnd, mLocales); @@ -655,6 +654,22 @@ final class SelectionActionModeHelper { return performClassification(selection); } + /** + * Maximum time (in milliseconds) to wait for a textclassifier result before timing out. + */ + // TODO: Consider making this a ViewConfiguration. + public long getTimeoutDuration() { + if (mHot) { + return 200; + } else { + // Return a slightly larger number than usual when the TextClassifier is first + // initialized. Initialization would usually take longer than subsequent calls to + // the TextClassifier. The impact of this on the UI is that we do not show the + // selection handles or toolbar until after this timeout. + return 500; + } + } + private SelectionResult performClassification(@Nullable TextSelection selection) { if (!Objects.equals(mText, mLastClassificationText) || mSelectionStart != mLastClassificationSelectionStart