diff options
7 files changed, 75 insertions, 6 deletions
diff --git a/core/java/android/view/textclassifier/ConversationAction.java b/core/java/android/view/textclassifier/ConversationAction.java index 2b952a3fad34..f2d878a8bf54 100644 --- a/core/java/android/view/textclassifier/ConversationAction.java +++ b/core/java/android/view/textclassifier/ConversationAction.java @@ -92,10 +92,15 @@ public final class ConversationAction implements Parcelable { */ public static final String TYPE_SHARE_LOCATION = "share_location"; + // TODO: Make this public API /** @hide **/ public static final String TYPE_ADD_CONTACT = "add_contact"; - public static final @android.annotation.NonNull Creator<ConversationAction> CREATOR = + // TODO: Make this public API + /** @hide **/ + public static final String TYPE_COPY = "copy"; + + public static final @NonNull Creator<ConversationAction> CREATOR = new Creator<ConversationAction>() { @Override public ConversationAction createFromParcel(Parcel in) { diff --git a/core/java/android/view/textclassifier/ExtrasUtils.java b/core/java/android/view/textclassifier/ExtrasUtils.java index df548ae5329d..05702bf08bd7 100644 --- a/core/java/android/view/textclassifier/ExtrasUtils.java +++ b/core/java/android/view/textclassifier/ExtrasUtils.java @@ -29,6 +29,7 @@ import java.util.ArrayList; */ public final class ExtrasUtils { + private static final String ENTITIES_EXTRAS = "entities-extras"; private static final String ACTION_INTENT = "action-intent"; private static final String ACTIONS_INTENTS = "actions-intents"; private static final String FOREIGN_LANGUAGE = "foreign-language"; @@ -94,6 +95,30 @@ public final class ExtrasUtils { } /** + * Stores {@code entities} information in TextClassifier response object's extras + * {@code container}. + * + * @see {@link #getCopyText(Bundle)} + */ + public static void putEntitiesExtras(Bundle container, @Nullable Bundle entitiesExtras) { + container.putParcelable(ENTITIES_EXTRAS, entitiesExtras); + } + + /** + * Returns {@code entities} information contained in a TextClassifier response object. + * + * @see {@link #putEntitiesExtras(Bundle, Bundle)} + */ + @Nullable + public static String getCopyText(Bundle container) { + Bundle entitiesExtras = container.getParcelable(ENTITIES_EXTRAS); + if (entitiesExtras == null) { + return null; + } + return entitiesExtras.getString("text"); + } + + /** * Returns {@code actionIntents} information contained in the TextClassification object. */ @Nullable diff --git a/core/java/android/view/textclassifier/TextClassificationConstants.java b/core/java/android/view/textclassifier/TextClassificationConstants.java index 38e72e34facf..2627ae655f9a 100644 --- a/core/java/android/view/textclassifier/TextClassificationConstants.java +++ b/core/java/android/view/textclassifier/TextClassificationConstants.java @@ -193,6 +193,7 @@ public final class TextClassificationConstants { .add(ConversationAction.TYPE_VIEW_CALENDAR) .add(ConversationAction.TYPE_VIEW_MAP) .add(ConversationAction.TYPE_ADD_CONTACT) + .add(ConversationAction.TYPE_COPY) .toString(); /** * < 0 : Not set. Use value from LangId model. diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java index 8b9f189e6f60..76d03132e0d4 100644 --- a/core/java/android/view/textclassifier/TextClassifierImpl.java +++ b/core/java/android/view/textclassifier/TextClassifierImpl.java @@ -451,6 +451,9 @@ public final class TextClassifierImpl implements TextClassifier { remoteAction = labeledIntentResult.remoteAction; ExtrasUtils.putActionIntent(extras, labeledIntentResult.resolvedIntent); } + ExtrasUtils.putEntitiesExtras( + extras, + TemplateIntentFactory.nameVariantsToBundle(nativeSuggestion.getEntityData())); conversationActions.add( new ConversationAction.Builder(actionType) .setConfidenceScore(nativeSuggestion.getScore()) diff --git a/core/java/android/view/textclassifier/intent/TemplateIntentFactory.java b/core/java/android/view/textclassifier/intent/TemplateIntentFactory.java index 39e91200b3cc..e630f61a9f6a 100644 --- a/core/java/android/view/textclassifier/intent/TemplateIntentFactory.java +++ b/core/java/android/view/textclassifier/intent/TemplateIntentFactory.java @@ -41,6 +41,9 @@ import java.util.List; public final class TemplateIntentFactory { private static final String TAG = TextClassifier.DEFAULT_LOG_TAG; + /** + * Constructs and returns a list of {@link LabeledIntent} based on the given templates. + */ @Nullable public List<LabeledIntent> create( @NonNull RemoteActionTemplate[] remoteActionTemplates) { @@ -108,11 +111,14 @@ public final class TemplateIntentFactory { } } } - intent.putExtras(createExtras(remoteActionTemplate.extras)); + intent.putExtras(nameVariantsToBundle(remoteActionTemplate.extras)); return intent; } - private static Bundle createExtras(NamedVariant[] namedVariants) { + /** + * Converts an array of {@link NamedVariant} to a Bundle and returns it. + */ + public static Bundle nameVariantsToBundle(@Nullable NamedVariant[] namedVariants) { if (namedVariants == null) { return Bundle.EMPTY; } @@ -142,7 +148,8 @@ public final class TemplateIntentFactory { break; default: Log.w(TAG, - "Unsupported type found in createExtras : " + namedVariant.getType()); + "Unsupported type found in nameVariantsToBundle : " + + namedVariant.getType()); } } return bundle; diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java index fe2a6608c781..066076ce5d12 100644 --- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java @@ -196,12 +196,12 @@ public class TextClassificationConstantsTest { .that(constants.getInAppConversationActionTypes()) .containsExactly("text_reply", "create_reminder", "call_phone", "open_url", "send_email", "send_sms", "track_flight", "view_calendar", "view_map", - "add_contact"); + "add_contact", "copy"); assertWithMessage("notification_conversation_action_types_default") .that(constants.getNotificationConversationActionTypes()) .containsExactly("text_reply", "create_reminder", "call_phone", "open_url", "send_email", "send_sms", "track_flight", "view_calendar", "view_map", - "add_contact"); + "add_contact", "copy"); assertWithMessage("lang_id_threshold_override") .that(constants.getLangIdThresholdOverride()).isWithin(EPSILON).of(-1f); } diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java index bcaf6631c97f..9ceb989474bd 100644 --- a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java @@ -468,6 +468,34 @@ public class TextClassifierTest { Truth.assertThat(actionIntent.getData()).isEqualTo(Uri.parse("https://www.android.com")); } + @Test + public void testSuggestConversationActions_copy() { + if (isTextClassifierDisabled()) return; + ConversationActions.Message message = + new ConversationActions.Message.Builder( + ConversationActions.Message.PERSON_USER_OTHERS) + .setText("Authentication code: 12345") + .build(); + TextClassifier.EntityConfig typeConfig = + new TextClassifier.EntityConfig.Builder().includeTypesFromTextClassifier(false) + .setIncludedTypes( + Collections.singletonList(ConversationAction.TYPE_COPY)) + .build(); + ConversationActions.Request request = + new ConversationActions.Request.Builder(Collections.singletonList(message)) + .setMaxSuggestions(1) + .setTypeConfig(typeConfig) + .build(); + + ConversationActions conversationActions = mClassifier.suggestConversationActions(request); + Truth.assertThat(conversationActions.getConversationActions()).hasSize(1); + ConversationAction conversationAction = conversationActions.getConversationActions().get(0); + Truth.assertThat(conversationAction.getType()).isEqualTo(ConversationAction.TYPE_COPY); + Truth.assertThat(conversationAction.getTextReply()).isAnyOf(null, ""); + Truth.assertThat(conversationAction.getAction()).isNull(); + String code = ExtrasUtils.getCopyText(conversationAction.getExtras()); + Truth.assertThat(code).isEqualTo("12345"); + } private boolean isTextClassifierDisabled() { return mClassifier == null || mClassifier == TextClassifier.NO_OP; |