diff options
| author | 2020-11-17 17:23:00 +0000 | |
|---|---|---|
| committer | 2020-12-02 21:28:04 +0000 | |
| commit | 2e853aa13965b8b79d3bc76b326223bc24585c73 (patch) | |
| tree | dbf56431f723e0224bb5594b3f276b164ac2dfb6 | |
| parent | 68a3422b492234ca3a89c6606685d3641fd849d9 (diff) | |
Introduce TextSelection.Builder.setIncludeTextClassification and TextSelection.getTextClassification()
This small API change enables us to optimize the latnecy of smart
selection.
To enable smart selection, TextView/WebView always call
textClassifier.suggestSelection and textClassifier.classifyText back to
back. There are a lot of overlaps between suggestSelection and
classifyText, e.g. both API calls classify the entity type of the text.
This optimization is important to make smart selection working
responsively, especially that we enforce a 200ms timeout in TextView.
This small API change allows the TextClassifier to implement smart
selection with just one single API call.
This change is backward-compatible.
If the text classifier is not updated to return the text classification
result in suggestSelection yet, clients can learn that by checking if
textSelection.getTextClassification() returns null. If so, the client
can then fallback to call ClassifyText().
You may find the textview integration in ag/13092679
Design doc: go/android-s-suggestselection
Bug: 173512834
Test: atest TextSelectionTest
Change-Id: If4cc827aa19d6d14c885cf10cd5ba16aa3041cf6
| -rw-r--r-- | core/api/current.txt | 4 | ||||
| -rw-r--r-- | core/java/android/view/textclassifier/TextSelection.java | 71 |
2 files changed, 72 insertions, 3 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index b61bc2fde0e9..2e913b554284 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -56539,6 +56539,7 @@ package android.view.textclassifier { method @Nullable public String getId(); method public int getSelectionEndIndex(); method public int getSelectionStartIndex(); + method @Nullable public android.view.textclassifier.TextClassification getTextClassification(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.view.textclassifier.TextSelection> CREATOR; } @@ -56549,6 +56550,7 @@ package android.view.textclassifier { method @NonNull public android.view.textclassifier.TextSelection.Builder setEntityType(@NonNull String, @FloatRange(from=0.0, to=1.0) float); method @NonNull public android.view.textclassifier.TextSelection.Builder setExtras(@Nullable android.os.Bundle); method @NonNull public android.view.textclassifier.TextSelection.Builder setId(@Nullable String); + method @NonNull public android.view.textclassifier.TextSelection.Builder setTextClassification(@Nullable android.view.textclassifier.TextClassification); } public static final class TextSelection.Request implements android.os.Parcelable { @@ -56559,6 +56561,7 @@ package android.view.textclassifier { method @NonNull public android.os.Bundle getExtras(); method @IntRange(from=0) public int getStartIndex(); method @NonNull public CharSequence getText(); + method public boolean shouldIncludeTextClassification(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.view.textclassifier.TextSelection.Request> CREATOR; } @@ -56568,6 +56571,7 @@ package android.view.textclassifier { method @NonNull public android.view.textclassifier.TextSelection.Request build(); method @NonNull public android.view.textclassifier.TextSelection.Request.Builder setDefaultLocales(@Nullable android.os.LocaleList); method @NonNull public android.view.textclassifier.TextSelection.Request.Builder setExtras(@Nullable android.os.Bundle); + method @NonNull public android.view.textclassifier.TextSelection.Request.Builder setIncludeTextClassification(boolean); } } diff --git a/core/java/android/view/textclassifier/TextSelection.java b/core/java/android/view/textclassifier/TextSelection.java index d8a632d10bc3..5b32649ac55b 100644 --- a/core/java/android/view/textclassifier/TextSelection.java +++ b/core/java/android/view/textclassifier/TextSelection.java @@ -45,15 +45,19 @@ public final class TextSelection implements Parcelable { private final int mEndIndex; private final EntityConfidence mEntityConfidence; @Nullable private final String mId; + @Nullable + private final TextClassification mTextClassification; private final Bundle mExtras; private TextSelection( int startIndex, int endIndex, Map<String, Float> entityConfidence, String id, + @Nullable TextClassification textClassification, Bundle extras) { mStartIndex = startIndex; mEndIndex = endIndex; mEntityConfidence = new EntityConfidence(entityConfidence); mId = id; + mTextClassification = textClassification; mExtras = extras; } @@ -111,6 +115,19 @@ public final class TextSelection implements Parcelable { } /** + * Returns the text classification result of the suggested selection span. Enables the text + * classification by calling + * {@link TextSelection.Request.Builder#setIncludeTextClassification(boolean)}. If the text + * classifier does not support it, a {@code null} is returned. + * + * @see TextSelection.Request.Builder#setIncludeTextClassification(boolean) + */ + @Nullable + public TextClassification getTextClassification() { + return mTextClassification; + } + + /** * Returns the extended data. * * <p><b>NOTE: </b>Do not modify this bundle. @@ -138,6 +155,8 @@ public final class TextSelection implements Parcelable { private final Map<String, Float> mEntityConfidence = new ArrayMap<>(); @Nullable private String mId; @Nullable + private TextClassification mTextClassification; + @Nullable private Bundle mExtras; /** @@ -179,6 +198,21 @@ public final class TextSelection implements Parcelable { } /** + * Sets the text classification result of the suggested selection. If + * {@link Request#shouldIncludeTextClassification()} is {@code true}, set this value. + * Otherwise this value may be set to null. The intention of this method is to avoid + * doing expensive work if the client is not interested in such result. + * + * @return this builder + * @see Request#shouldIncludeTextClassification() + */ + @NonNull + public Builder setTextClassification(@Nullable TextClassification textClassification) { + mTextClassification = textClassification; + return this; + } + + /** * Sets the extended data. * * @return this builder @@ -196,7 +230,7 @@ public final class TextSelection implements Parcelable { public TextSelection build() { return new TextSelection( mStartIndex, mEndIndex, mEntityConfidence, mId, - mExtras == null ? Bundle.EMPTY : mExtras); + mTextClassification, mExtras == null ? Bundle.EMPTY : mExtras); } } @@ -210,6 +244,7 @@ public final class TextSelection implements Parcelable { private final int mEndIndex; @Nullable private final LocaleList mDefaultLocales; private final boolean mDarkLaunchAllowed; + private final boolean mIncludeTextClassification; private final Bundle mExtras; @Nullable private SystemTextClassifierMetadata mSystemTcMetadata; @@ -219,12 +254,14 @@ public final class TextSelection implements Parcelable { int endIndex, LocaleList defaultLocales, boolean darkLaunchAllowed, + boolean includeTextClassification, Bundle extras) { mText = text; mStartIndex = startIndex; mEndIndex = endIndex; mDefaultLocales = defaultLocales; mDarkLaunchAllowed = darkLaunchAllowed; + mIncludeTextClassification = includeTextClassification; mExtras = extras; } @@ -303,6 +340,14 @@ public final class TextSelection implements Parcelable { } /** + * Returns true if the client wants the text classifier to classify the text as well and + * include a {@link TextClassification} object in the result. + */ + public boolean shouldIncludeTextClassification() { + return mIncludeTextClassification; + } + + /** * Returns the extended data. * * <p><b>NOTE: </b>Do not modify this bundle. @@ -320,9 +365,9 @@ public final class TextSelection implements Parcelable { private final CharSequence mText; private final int mStartIndex; private final int mEndIndex; - @Nullable private LocaleList mDefaultLocales; private boolean mDarkLaunchAllowed; + private boolean mIncludeTextClassification; private Bundle mExtras; /** @@ -372,6 +417,21 @@ public final class TextSelection implements Parcelable { } /** + * @param includeTextClassification If true, suggests the TextClassifier to classify the + * text in the suggested selection span and include a TextClassification object in + * the result. The TextClassifier may not support this and in which case, + * {@link TextSelection#getTextClassification()} returns {@code null}. + * + * @return this builder. + * @see TextSelection#getTextClassification() + */ + @NonNull + public Builder setIncludeTextClassification(boolean includeTextClassification) { + mIncludeTextClassification = includeTextClassification; + return this; + } + + /** * Sets the extended data. * * @return this builder @@ -389,6 +449,7 @@ public final class TextSelection implements Parcelable { public Request build() { return new Request(new SpannedString(mText), mStartIndex, mEndIndex, mDefaultLocales, mDarkLaunchAllowed, + mIncludeTextClassification, mExtras == null ? Bundle.EMPTY : mExtras); } } @@ -406,6 +467,7 @@ public final class TextSelection implements Parcelable { dest.writeParcelable(mDefaultLocales, flags); dest.writeBundle(mExtras); dest.writeParcelable(mSystemTcMetadata, flags); + dest.writeBoolean(mIncludeTextClassification); } private static Request readFromParcel(Parcel in) { @@ -415,9 +477,10 @@ public final class TextSelection implements Parcelable { final LocaleList defaultLocales = in.readParcelable(null); final Bundle extras = in.readBundle(); final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null); + final boolean includeTextClassification = in.readBoolean(); final Request request = new Request(text, startIndex, endIndex, defaultLocales, - /* darkLaunchAllowed= */ false, extras); + /* darkLaunchAllowed= */ false, includeTextClassification, extras); request.setSystemTextClassifierMetadata(systemTcMetadata); return request; } @@ -448,6 +511,7 @@ public final class TextSelection implements Parcelable { mEntityConfidence.writeToParcel(dest, flags); dest.writeString(mId); dest.writeBundle(mExtras); + dest.writeParcelable(mTextClassification, flags); } public static final @android.annotation.NonNull Parcelable.Creator<TextSelection> CREATOR = @@ -469,5 +533,6 @@ public final class TextSelection implements Parcelable { mEntityConfidence = EntityConfidence.CREATOR.createFromParcel(in); mId = in.readString(); mExtras = in.readBundle(); + mTextClassification = in.readParcelable(TextClassification.class.getClassLoader()); } } |