Merge "Make SelectionActionModeHelper hardcoded constants configurable." into sc-dev

This commit is contained in:
Joanne Chung
2021-03-04 02:30:32 +00:00
committed by Android (Google) Code Review
5 changed files with 79 additions and 10 deletions

View File

@@ -310,6 +310,18 @@ public class ViewConfiguration {
*/ */
private static final float AMBIGUOUS_GESTURE_MULTIPLIER = 2f; private static final float AMBIGUOUS_GESTURE_MULTIPLIER = 2f;
/**
* The timeout value in milliseconds to adjust the selection span and actions for the selected
* text when TextClassifier has been initialized.
*/
private static final int SMART_SELECTION_INITIALIZED_TIMEOUT_IN_MILLISECOND = 200;
/**
* The timeout value in milliseconds to adjust the selection span and actions for the selected
* text when TextClassifier has not been initialized.
*/
private static final int SMART_SELECTION_INITIALIZING_TIMEOUT_IN_MILLISECOND = 500;
private final boolean mConstructedWithContext; private final boolean mConstructedWithContext;
private final int mEdgeSlop; private final int mEdgeSlop;
private final int mFadingEdgeLength; private final int mFadingEdgeLength;
@@ -335,6 +347,8 @@ public class ViewConfiguration {
private final float mHorizontalScrollFactor; private final float mHorizontalScrollFactor;
private final boolean mShowMenuShortcutsWhenKeyboardPresent; private final boolean mShowMenuShortcutsWhenKeyboardPresent;
private final long mScreenshotChordKeyTimeout; private final long mScreenshotChordKeyTimeout;
private final int mSmartSelectionInitializedTimeout;
private final int mSmartSelectionInitializingTimeout;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768915) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768915)
private boolean sHasPermanentMenuKey; private boolean sHasPermanentMenuKey;
@@ -378,6 +392,8 @@ public class ViewConfiguration {
// Getter throws if mConstructedWithContext is false so doesn't matter what // Getter throws if mConstructedWithContext is false so doesn't matter what
// this value is. // this value is.
mMinScalingSpan = 0; mMinScalingSpan = 0;
mSmartSelectionInitializedTimeout = SMART_SELECTION_INITIALIZED_TIMEOUT_IN_MILLISECOND;
mSmartSelectionInitializingTimeout = SMART_SELECTION_INITIALIZING_TIMEOUT_IN_MILLISECOND;
} }
/** /**
@@ -488,6 +504,11 @@ public class ViewConfiguration {
mScreenshotChordKeyTimeout = res.getInteger( mScreenshotChordKeyTimeout = res.getInteger(
com.android.internal.R.integer.config_screenshotChordKeyTimeout); com.android.internal.R.integer.config_screenshotChordKeyTimeout);
mSmartSelectionInitializedTimeout = res.getInteger(
com.android.internal.R.integer.config_smartSelectionInitializedTimeoutMillis);
mSmartSelectionInitializingTimeout = res.getInteger(
com.android.internal.R.integer.config_smartSelectionInitializingTimeoutMillis);
} }
/** /**
@@ -1068,6 +1089,24 @@ public class ViewConfiguration {
return mFadingMarqueeEnabled; return mFadingMarqueeEnabled;
} }
/**
* @return the timeout value in milliseconds to adjust the selection span and actions for the
* selected text when TextClassifier has been initialized.
* @hide
*/
public int getSmartSelectionInitializedTimeout() {
return mSmartSelectionInitializedTimeout;
}
/**
* @return the timeout value in milliseconds to adjust the selection span and actions for the
* selected text when TextClassifier has not been initialized.
* @hide
*/
public int getSmartSelectionInitializingTimeout() {
return mSmartSelectionInitializingTimeout;
}
/** /**
* @return the duration in milliseconds before an end of a long press causes a tooltip to be * @return the duration in milliseconds before an end of a long press causes a tooltip to be
* hidden * hidden

View File

@@ -90,6 +90,12 @@ public final class TextClassificationConstants {
static final String SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND = static final String SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND =
"system_textclassifier_api_timeout_in_second"; "system_textclassifier_api_timeout_in_second";
/**
* The max amount of characters before and after the selected text that are passed to the
* TextClassifier for the smart selection.
*/
private static final String SMART_SELECTION_TRIM_DELTA = "smart_selection_trim_delta";
private static final String DEFAULT_TEXT_CLASSIFIER_SERVICE_PACKAGE_OVERRIDE = null; private static final String DEFAULT_TEXT_CLASSIFIER_SERVICE_PACKAGE_OVERRIDE = null;
private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true; private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true; private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
@@ -100,6 +106,7 @@ public final class TextClassificationConstants {
private static final boolean SMART_SELECT_ANIMATION_ENABLED_DEFAULT = true; private static final boolean SMART_SELECT_ANIMATION_ENABLED_DEFAULT = true;
private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000; private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000;
private static final long SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND_DEFAULT = 60; private static final long SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND_DEFAULT = 60;
private static final int SMART_SELECTION_TRIM_DELTA_DEFAULT = 120;
@Nullable @Nullable
public String getTextClassifierServicePackageOverride() { public String getTextClassifierServicePackageOverride() {
@@ -155,6 +162,12 @@ public final class TextClassificationConstants {
SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND_DEFAULT); SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND_DEFAULT);
} }
public int getSmartSelectionTrimDelta() {
return DeviceConfig.getInt(DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
SMART_SELECTION_TRIM_DELTA,
SMART_SELECTION_TRIM_DELTA_DEFAULT);
}
void dump(IndentingPrintWriter pw) { void dump(IndentingPrintWriter pw) {
pw.println("TextClassificationConstants:"); pw.println("TextClassificationConstants:");
pw.increaseIndent(); pw.increaseIndent();
@@ -170,6 +183,7 @@ public final class TextClassificationConstants {
getTextClassifierServicePackageOverride()).println(); getTextClassifierServicePackageOverride()).println();
pw.print(SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND, pw.print(SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND,
getSystemTextClassifierApiTimeoutInSecond()).println(); getSystemTextClassifierApiTimeoutInSecond()).println();
pw.print(SMART_SELECTION_TRIM_DELTA, getSmartSelectionTrimDelta()).println();
pw.decreaseIndent(); pw.decreaseIndent();
} }
} }

View File

@@ -36,6 +36,7 @@ import android.text.TextUtils;
import android.text.util.Linkify; import android.text.util.Linkify;
import android.util.Log; import android.util.Log;
import android.view.ActionMode; import android.view.ActionMode;
import android.view.ViewConfiguration;
import android.view.textclassifier.ExtrasUtils; import android.view.textclassifier.ExtrasUtils;
import android.view.textclassifier.SelectionEvent; import android.view.textclassifier.SelectionEvent;
import android.view.textclassifier.SelectionEvent.InvocationMethod; import android.view.textclassifier.SelectionEvent.InvocationMethod;
@@ -1056,10 +1057,12 @@ public final class SelectionActionModeHelper {
*/ */
private static final class TextClassificationHelper { private static final class TextClassificationHelper {
private static final int TRIM_DELTA = 120; // characters // The fixed upper bound of context size.
private static final int TRIM_DELTA_UPPER_BOUND = 240;
private final Context mContext; private final Context mContext;
private Supplier<TextClassifier> mTextClassifier; private Supplier<TextClassifier> mTextClassifier;
private final ViewConfiguration mViewConfiguration;
/** The original TextView text. **/ /** The original TextView text. **/
private String mText; private String mText;
@@ -1088,12 +1091,13 @@ public final class SelectionActionModeHelper {
private SelectionResult mLastClassificationResult; private SelectionResult mLastClassificationResult;
/** Whether the TextClassifier has been initialized. */ /** Whether the TextClassifier has been initialized. */
private boolean mHot; private boolean mInitialized;
TextClassificationHelper(Context context, Supplier<TextClassifier> textClassifier, TextClassificationHelper(Context context, Supplier<TextClassifier> textClassifier,
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 = Objects.requireNonNull(context); mContext = Objects.requireNonNull(context);
mViewConfiguration = ViewConfiguration.get(mContext);
} }
@UiThread @UiThread
@@ -1110,13 +1114,13 @@ public final class SelectionActionModeHelper {
@WorkerThread @WorkerThread
public SelectionResult classifyText() { public SelectionResult classifyText() {
mHot = true; mInitialized = true;
return performClassification(null /* selection */); return performClassification(null /* selection */);
} }
@WorkerThread @WorkerThread
public SelectionResult suggestSelection() { public SelectionResult suggestSelection() {
mHot = true; mInitialized = true;
trimText(); trimText();
final TextSelection selection; final TextSelection selection;
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) { if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) {
@@ -1148,16 +1152,15 @@ public final class SelectionActionModeHelper {
/** /**
* Maximum time (in milliseconds) to wait for a textclassifier result before timing out. * Maximum time (in milliseconds) to wait for a textclassifier result before timing out.
*/ */
// TODO: Consider making this a ViewConfiguration.
public int getTimeoutDuration() { public int getTimeoutDuration() {
if (mHot) { if (mInitialized) {
return 200; return mViewConfiguration.getSmartSelectionInitializedTimeout();
} else { } else {
// Return a slightly larger number than usual when the TextClassifier is first // Return a slightly larger number than usual when the TextClassifier is first
// initialized. Initialization would usually take longer than subsequent calls to // 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 // the TextClassifier. The impact of this on the UI is that we do not show the
// selection handles or toolbar until after this timeout. // selection handles or toolbar until after this timeout.
return 500; return mViewConfiguration.getSmartSelectionInitializingTimeout();
} }
} }
@@ -1205,8 +1208,11 @@ public final class SelectionActionModeHelper {
} }
private void trimText() { private void trimText() {
mTrimStart = Math.max(0, mSelectionStart - TRIM_DELTA); final int trimDelta = Math.min(
final int referenceEnd = Math.min(mText.length(), mSelectionEnd + TRIM_DELTA); TextClassificationManager.getSettings(mContext).getSmartSelectionTrimDelta(),
TRIM_DELTA_UPPER_BOUND);
mTrimStart = Math.max(0, mSelectionStart - trimDelta);
final int referenceEnd = Math.min(mText.length(), mSelectionEnd + trimDelta);
mTrimmedText = mText.subSequence(mTrimStart, referenceEnd); mTrimmedText = mText.subSequence(mTrimStart, referenceEnd);
mRelativeStart = mSelectionStart - mTrimStart; mRelativeStart = mSelectionStart - mTrimStart;
mRelativeEnd = mSelectionEnd - mTrimStart; mRelativeEnd = mSelectionEnd - mTrimStart;

View File

@@ -4696,6 +4696,14 @@
<!-- If true, hide the display cutout with display area --> <!-- If true, hide the display cutout with display area -->
<bool name="config_hideDisplayCutoutWithDisplayArea">false</bool> <bool name="config_hideDisplayCutoutWithDisplayArea">false</bool>
<!-- The timeout value in milliseconds used by SelectionActionModeHelper for each selections
when TextClassifier has been initialized. -->
<integer name="config_smartSelectionInitializedTimeoutMillis">200</integer>
<!-- The timeout value in milliseconds used by SelectionActionModeHelper for each selections
when TextClassifier has not been initialized. -->
<integer name="config_smartSelectionInitializingTimeoutMillis">500</integer>
<!-- Indicates that default fitness tracker app needs to request sensor and location permissions. --> <!-- Indicates that default fitness tracker app needs to request sensor and location permissions. -->
<bool name="config_trackerAppNeedsPermissions">false</bool> <bool name="config_trackerAppNeedsPermissions">false</bool>

View File

@@ -482,6 +482,8 @@
<java-symbol type="array" name="config_integrityRuleProviderPackages" /> <java-symbol type="array" name="config_integrityRuleProviderPackages" />
<java-symbol type="bool" name="config_useAssistantVolume" /> <java-symbol type="bool" name="config_useAssistantVolume" />
<java-symbol type="string" name="config_bandwidthEstimateSource" /> <java-symbol type="string" name="config_bandwidthEstimateSource" />
<java-symbol type="integer" name="config_smartSelectionInitializedTimeoutMillis" />
<java-symbol type="integer" name="config_smartSelectionInitializingTimeoutMillis" />
<java-symbol type="color" name="tab_indicator_text_v4" /> <java-symbol type="color" name="tab_indicator_text_v4" />