diff options
| author | 2018-04-03 23:49:16 +0100 | |
|---|---|---|
| committer | 2018-04-04 14:10:51 +0200 | |
| commit | ae82e7ad280e55dca22014c6abc857372229f89c (patch) | |
| tree | f52fc107e700eba23c1824e817d7bb5dcc22e5bf | |
| parent | b2e6e45d009e7c9148e69bf2c1f0b46917bee7b0 (diff) | |
Fix TCS crash due to API changes.
- Brings by old deleted APIs and hides them
- Except parceling and hidden APIs that won't have been called anyway
- Option holds a reference to the Request object so we don't have to
rebuild it
Bug: 77523413
Test: bit FrameworksCoreTests:android.view.textclassifier.TextClassificationManagerTest
Test: bit CtsViewTestCases:android.view.textclassifier.cts.TextClassificationManagerTest
Test: bit CtsWidgetTestCases:android.widget.cts.TextViewTest
Test: bit FrameworksCoreTests:android.widget.TextViewActivityTest
Test: bit FrameworksCoreTests:android.view.textclassifier.TextClassificationTest
Test: bit FrameworksCoreTests:android.view.textclassifier.TextSelectionTest
Test: bit FrameworksCoreTests:android.view.textclassifier.TextLinksTest
Change-Id: I4277c48a950c3334439649373885ed7fe54f898e
5 files changed, 358 insertions, 3 deletions
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java index f1bb72cfacf1..7b9af087c100 100644 --- a/core/java/android/service/textclassifier/TextClassifierService.java +++ b/core/java/android/service/textclassifier/TextClassifierService.java @@ -17,6 +17,7 @@ package android.service.textclassifier; import android.Manifest; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -97,7 +98,8 @@ public abstract class TextClassifierService extends Service { Preconditions.checkNotNull(request); Preconditions.checkNotNull(callback); TextClassifierService.this.onSuggestSelection( - sessionId, request, mCancellationSignal, + request.getText(), request.getStartIndex(), request.getEndIndex(), + TextSelection.Options.from(sessionId, request), mCancellationSignal, new Callback<TextSelection>() { @Override public void onSuccess(TextSelection result) { @@ -130,7 +132,8 @@ public abstract class TextClassifierService extends Service { Preconditions.checkNotNull(request); Preconditions.checkNotNull(callback); TextClassifierService.this.onClassifyText( - sessionId, request, mCancellationSignal, + request.getText(), request.getStartIndex(), request.getEndIndex(), + TextClassification.Options.from(sessionId, request), mCancellationSignal, new Callback<TextClassification>() { @Override public void onSuccess(TextClassification result) { @@ -161,7 +164,8 @@ public abstract class TextClassifierService extends Service { Preconditions.checkNotNull(request); Preconditions.checkNotNull(callback); TextClassifierService.this.onGenerateLinks( - sessionId, request, mCancellationSignal, + request.getText(), TextLinks.Options.from(sessionId, request), + mCancellationSignal, new Callback<TextLinks>() { @Override public void onSuccess(TextLinks result) { @@ -234,6 +238,25 @@ public abstract class TextClassifierService extends Service { @NonNull CancellationSignal cancellationSignal, @NonNull Callback<TextSelection> callback); + // TODO: Remove once apps can build against the latest sdk. + /** @hide */ + public void onSuggestSelection( + @NonNull CharSequence text, + @IntRange(from = 0) int selectionStartIndex, + @IntRange(from = 0) int selectionEndIndex, + @Nullable TextSelection.Options options, + @NonNull CancellationSignal cancellationSignal, + @NonNull Callback<TextSelection> callback) { + final TextClassificationSessionId sessionId = options.getSessionId(); + final TextSelection.Request request = options.getRequest() != null + ? options.getRequest() + : new TextSelection.Request.Builder( + text, selectionStartIndex, selectionEndIndex) + .setDefaultLocales(options.getDefaultLocales()) + .build(); + onSuggestSelection(sessionId, request, cancellationSignal, callback); + } + /** * Classifies the specified text and returns a {@link TextClassification} object that can be * used to generate a widget for handling the classified text. @@ -249,6 +272,26 @@ public abstract class TextClassifierService extends Service { @NonNull CancellationSignal cancellationSignal, @NonNull Callback<TextClassification> callback); + // TODO: Remove once apps can build against the latest sdk. + /** @hide */ + public void onClassifyText( + @NonNull CharSequence text, + @IntRange(from = 0) int startIndex, + @IntRange(from = 0) int endIndex, + @Nullable TextClassification.Options options, + @NonNull CancellationSignal cancellationSignal, + @NonNull Callback<TextClassification> callback) { + final TextClassificationSessionId sessionId = options.getSessionId(); + final TextClassification.Request request = options.getRequest() != null + ? options.getRequest() + : new TextClassification.Request.Builder( + text, startIndex, endIndex) + .setDefaultLocales(options.getDefaultLocales()) + .setReferenceTime(options.getReferenceTime()) + .build(); + onClassifyText(sessionId, request, cancellationSignal, callback); + } + /** * Generates and returns a {@link TextLinks} that may be applied to the text to annotate it with * links information. @@ -264,6 +307,23 @@ public abstract class TextClassifierService extends Service { @NonNull CancellationSignal cancellationSignal, @NonNull Callback<TextLinks> callback); + // TODO: Remove once apps can build against the latest sdk. + /** @hide */ + public void onGenerateLinks( + @NonNull CharSequence text, + @Nullable TextLinks.Options options, + @NonNull CancellationSignal cancellationSignal, + @NonNull Callback<TextLinks> callback) { + final TextClassificationSessionId sessionId = options.getSessionId(); + final TextLinks.Request request = options.getRequest() != null + ? options.getRequest() + : new TextLinks.Request.Builder(text) + .setDefaultLocales(options.getDefaultLocales()) + .setEntityConfig(options.getEntityConfig()) + .build(); + onGenerateLinks(sessionId, request, cancellationSignal, callback); + } + /** * Writes the selection event. * This is called when a selection event occurs. e.g. user changed selection; or smart selection diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java index 37a5d9a10743..f80625f0f82f 100644 --- a/core/java/android/view/textclassifier/TextClassification.java +++ b/core/java/android/view/textclassifier/TextClassification.java @@ -721,4 +721,67 @@ public final class TextClassification implements Parcelable { mEntityConfidence = EntityConfidence.CREATOR.createFromParcel(in); mId = in.readString(); } + + // TODO: Remove once apps can build against the latest sdk. + /** + * Optional input parameters for generating TextClassification. + * @hide + */ + public static final class Options { + + @Nullable private final TextClassificationSessionId mSessionId; + @Nullable private final Request mRequest; + @Nullable private LocaleList mDefaultLocales; + @Nullable private ZonedDateTime mReferenceTime; + + public Options() { + this(null, null); + } + + private Options( + @Nullable TextClassificationSessionId sessionId, @Nullable Request request) { + mSessionId = sessionId; + mRequest = request; + } + + /** Helper to create Options from a Request. */ + public static Options from(TextClassificationSessionId sessionId, Request request) { + final Options options = new Options(sessionId, request); + options.setDefaultLocales(request.getDefaultLocales()); + options.setReferenceTime(request.getReferenceTime()); + return options; + } + + /** @param defaultLocales ordered list of locale preferences. */ + public Options setDefaultLocales(@Nullable LocaleList defaultLocales) { + mDefaultLocales = defaultLocales; + return this; + } + + /** @param referenceTime refrence time used for interpreting relatives dates */ + public Options setReferenceTime(@Nullable ZonedDateTime referenceTime) { + mReferenceTime = referenceTime; + return this; + } + + @Nullable + public LocaleList getDefaultLocales() { + return mDefaultLocales; + } + + @Nullable + public ZonedDateTime getReferenceTime() { + return mReferenceTime; + } + + @Nullable + public Request getRequest() { + return mRequest; + } + + @Nullable + public TextClassificationSessionId getSessionId() { + return mSessionId; + } + } } diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java index 54261be33607..4cfa9038aeaa 100644 --- a/core/java/android/view/textclassifier/TextClassifier.java +++ b/core/java/android/view/textclassifier/TextClassifier.java @@ -208,6 +208,22 @@ public interface TextClassifier { return suggestSelection(request); } + // TODO: Remove once apps can build against the latest sdk. + /** @hide */ + default TextSelection suggestSelection( + @NonNull CharSequence text, + @IntRange(from = 0) int selectionStartIndex, + @IntRange(from = 0) int selectionEndIndex, + @Nullable TextSelection.Options options) { + final TextSelection.Request request = options.getRequest() != null + ? options.getRequest() + : new TextSelection.Request.Builder( + text, selectionStartIndex, selectionEndIndex) + .setDefaultLocales(options.getDefaultLocales()) + .build(); + return suggestSelection(request); + } + /** * Classifies the specified text and returns a {@link TextClassification} object that can be * used to generate a widget for handling the classified text. @@ -267,6 +283,23 @@ public interface TextClassifier { return classifyText(request); } + // TODO: Remove once apps can build against the latest sdk. + /** @hide */ + default TextClassification classifyText( + @NonNull CharSequence text, + @IntRange(from = 0) int startIndex, + @IntRange(from = 0) int endIndex, + @Nullable TextClassification.Options options) { + final TextClassification.Request request = options.getRequest() != null + ? options.getRequest() + : new TextClassification.Request.Builder( + text, startIndex, endIndex) + .setDefaultLocales(options.getDefaultLocales()) + .setReferenceTime(options.getReferenceTime()) + .build(); + return classifyText(request); + } + /** * Generates and returns a {@link TextLinks} that may be applied to the text to annotate it with * links information. @@ -288,6 +321,19 @@ public interface TextClassifier { return new TextLinks.Builder(request.getText().toString()).build(); } + // TODO: Remove once apps can build against the latest sdk. + /** @hide */ + default TextLinks generateLinks( + @NonNull CharSequence text, @Nullable TextLinks.Options options) { + final TextLinks.Request request = options.getRequest() != null + ? options.getRequest() + : new TextLinks.Request.Builder(text) + .setDefaultLocales(options.getDefaultLocales()) + .setEntityConfig(options.getEntityConfig()) + .build(); + return generateLinks(request); + } + /** * Returns the maximal length of text that can be processed by generateLinks. * @@ -377,6 +423,12 @@ public interface TextClassifier { /* includedEntityTypes */null, /* excludedEntityTypes */ null); } + // TODO: Remove once apps can build against the latest sdk. + /** @hide */ + public static EntityConfig create(@Nullable Collection<String> hints) { + return createWithHints(hints); + } + /** * Creates an EntityConfig. * @@ -406,6 +458,12 @@ public interface TextClassifier { /* includedEntityTypes */ entityTypes, /* excludedEntityTypes */ null); } + // TODO: Remove once apps can build against the latest sdk. + /** @hide */ + public static EntityConfig createWithEntityList(@Nullable Collection<String> entityTypes) { + return createWithExplicitEntityList(entityTypes); + } + /** * Returns a list of the final set of entities to find. * diff --git a/core/java/android/view/textclassifier/TextLinks.java b/core/java/android/view/textclassifier/TextLinks.java index 17c7b13cdc85..3d503e2ab70b 100644 --- a/core/java/android/view/textclassifier/TextLinks.java +++ b/core/java/android/view/textclassifier/TextLinks.java @@ -28,6 +28,8 @@ import android.text.Spannable; import android.text.method.MovementMethod; import android.text.style.ClickableSpan; import android.text.style.URLSpan; +import android.text.util.Linkify; +import android.text.util.Linkify.LinkifyMask; import android.view.View; import android.view.textclassifier.TextClassifier.EntityType; import android.widget.TextView; @@ -607,4 +609,124 @@ public final class TextLinks implements Parcelable { return new TextLinks(mFullText, mLinks); } } + + // TODO: Remove once apps can build against the latest sdk. + /** + * Optional input parameters for generating TextLinks. + * @hide + */ + public static final class Options { + + @Nullable private final TextClassificationSessionId mSessionId; + @Nullable private final Request mRequest; + @Nullable private LocaleList mDefaultLocales; + @Nullable private TextClassifier.EntityConfig mEntityConfig; + private boolean mLegacyFallback; + + private @ApplyStrategy int mApplyStrategy; + private Function<TextLink, TextLinkSpan> mSpanFactory; + + private String mCallingPackageName; + + public Options() { + this(null, null); + } + + private Options( + @Nullable TextClassificationSessionId sessionId, @Nullable Request request) { + mSessionId = sessionId; + mRequest = request; + } + + /** Helper to create Options from a Request. */ + public static Options from(TextClassificationSessionId sessionId, Request request) { + final Options options = new Options(sessionId, request); + options.setDefaultLocales(request.getDefaultLocales()); + options.setEntityConfig(request.getEntityConfig()); + return options; + } + + /** Returns a new options object based on the specified link mask. */ + public static Options fromLinkMask(@LinkifyMask int mask) { + final List<String> entitiesToFind = new ArrayList<>(); + + if ((mask & Linkify.WEB_URLS) != 0) { + entitiesToFind.add(TextClassifier.TYPE_URL); + } + if ((mask & Linkify.EMAIL_ADDRESSES) != 0) { + entitiesToFind.add(TextClassifier.TYPE_EMAIL); + } + if ((mask & Linkify.PHONE_NUMBERS) != 0) { + entitiesToFind.add(TextClassifier.TYPE_PHONE); + } + if ((mask & Linkify.MAP_ADDRESSES) != 0) { + entitiesToFind.add(TextClassifier.TYPE_ADDRESS); + } + + return new Options().setEntityConfig( + TextClassifier.EntityConfig.createWithEntityList(entitiesToFind)); + } + + /** @param defaultLocales ordered list of locale preferences. */ + public Options setDefaultLocales(@Nullable LocaleList defaultLocales) { + mDefaultLocales = defaultLocales; + return this; + } + + /** @param entityConfig definition of which entity types to look for. */ + public Options setEntityConfig(@Nullable TextClassifier.EntityConfig entityConfig) { + mEntityConfig = entityConfig; + return this; + } + + /** @param applyStrategy strategy to use when resolving conflicts. */ + public Options setApplyStrategy(@ApplyStrategy int applyStrategy) { + checkValidApplyStrategy(applyStrategy); + mApplyStrategy = applyStrategy; + return this; + } + + /** @param spanFactory factory for converting TextLink to TextLinkSpan. */ + public Options setSpanFactory(@Nullable Function<TextLink, TextLinkSpan> spanFactory) { + mSpanFactory = spanFactory; + return this; + } + + @Nullable + public LocaleList getDefaultLocales() { + return mDefaultLocales; + } + + @Nullable + public TextClassifier.EntityConfig getEntityConfig() { + return mEntityConfig; + } + + @ApplyStrategy + public int getApplyStrategy() { + return mApplyStrategy; + } + + @Nullable + public Function<TextLink, TextLinkSpan> getSpanFactory() { + return mSpanFactory; + } + + @Nullable + public Request getRequest() { + return mRequest; + } + + @Nullable + public TextClassificationSessionId getSessionId() { + return mSessionId; + } + + private static void checkValidApplyStrategy(int applyStrategy) { + if (applyStrategy != APPLY_STRATEGY_IGNORE && applyStrategy != APPLY_STRATEGY_REPLACE) { + throw new IllegalArgumentException( + "Invalid apply strategy. See TextLinks.ApplyStrategy for options."); + } + } + } } diff --git a/core/java/android/view/textclassifier/TextSelection.java b/core/java/android/view/textclassifier/TextSelection.java index 939e71760dcd..17687c9e246e 100644 --- a/core/java/android/view/textclassifier/TextSelection.java +++ b/core/java/android/view/textclassifier/TextSelection.java @@ -375,4 +375,56 @@ public final class TextSelection implements Parcelable { mEntityConfidence = EntityConfidence.CREATOR.createFromParcel(in); mId = in.readString(); } + + + // TODO: Remove once apps can build against the latest sdk. + /** + * Optional input parameters for generating TextSelection. + * @hide + */ + public static final class Options { + + @Nullable private final TextClassificationSessionId mSessionId; + @Nullable private final Request mRequest; + @Nullable private LocaleList mDefaultLocales; + private boolean mDarkLaunchAllowed; + + public Options() { + this(null, null); + } + + private Options( + @Nullable TextClassificationSessionId sessionId, @Nullable Request request) { + mSessionId = sessionId; + mRequest = request; + } + + /** Helper to create Options from a Request. */ + public static Options from(TextClassificationSessionId sessionId, Request request) { + final Options options = new Options(sessionId, request); + options.setDefaultLocales(request.getDefaultLocales()); + return options; + } + + /** @param defaultLocales ordered list of locale preferences. */ + public Options setDefaultLocales(@Nullable LocaleList defaultLocales) { + mDefaultLocales = defaultLocales; + return this; + } + + @Nullable + public LocaleList getDefaultLocales() { + return mDefaultLocales; + } + + @Nullable + public Request getRequest() { + return mRequest; + } + + @Nullable + public TextClassificationSessionId getSessionId() { + return mSessionId; + } + } } |