Loading core/java/android/view/textclassifier/intent/ClassificationIntentFactory.java +1 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ public interface ClassificationIntentFactory { context.getString(com.android.internal.R.string.translate), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.translate_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_TRANSLATE) // TODO: Probably better to introduce a "translate" scheme instead of // using EXTRA_TEXT. Loading core/java/android/view/textclassifier/intent/LabeledIntent.java +33 −1 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ public final class LabeledIntent { @Nullable public final String titleWithEntity; public final String description; @Nullable public final String descriptionWithAppName; // Do not update this intent. public final Intent intent; public final int requestCode; Loading @@ -75,6 +77,7 @@ public final class LabeledIntent { @Nullable String titleWithoutEntity, @Nullable String titleWithEntity, String description, @Nullable String descriptionWithAppName, Intent intent, int requestCode) { if (TextUtils.isEmpty(titleWithEntity) && TextUtils.isEmpty(titleWithoutEntity)) { Loading @@ -84,6 +87,7 @@ public final class LabeledIntent { this.titleWithoutEntity = titleWithoutEntity; this.titleWithEntity = titleWithEntity; this.description = Preconditions.checkNotNull(description); this.descriptionWithAppName = descriptionWithAppName; this.intent = Preconditions.checkNotNull(intent); this.requestCode = requestCode; } Loading Loading @@ -141,11 +145,39 @@ public final class LabeledIntent { Log.w(TAG, "Custom titleChooser return null, fallback to the default titleChooser"); title = DEFAULT_TITLE_CHOOSER.chooseTitle(this, resolveInfo); } final RemoteAction action = new RemoteAction(icon, title, description, pendingIntent); final RemoteAction action = new RemoteAction(icon, title, resolveDescription(resolveInfo, pm), pendingIntent); action.setShouldShowIcon(shouldShowIcon); return new Result(resolvedIntent, action); } private String resolveDescription(ResolveInfo resolveInfo, PackageManager packageManager) { if (!TextUtils.isEmpty(descriptionWithAppName)) { // Example string format of descriptionWithAppName: "Use %1$s to open map". String applicationName = getApplicationName(resolveInfo, packageManager); if (!TextUtils.isEmpty(applicationName)) { return String.format(descriptionWithAppName, applicationName); } } return description; } @Nullable private String getApplicationName( ResolveInfo resolveInfo, PackageManager packageManager) { if (resolveInfo.activityInfo == null) { return null; } if ("android".equals(resolveInfo.activityInfo.packageName)) { return null; } if (resolveInfo.activityInfo.applicationInfo == null) { return null; } return (String) packageManager.getApplicationLabel( resolveInfo.activityInfo.applicationInfo); } private Bundle getFromTextClassifierExtra(@Nullable Bundle textLanguagesBundle) { if (textLanguagesBundle != null) { final Bundle bundle = new Bundle(); Loading core/java/android/view/textclassifier/intent/LegacyClassificationIntentFactory.java +12 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import java.util.concurrent.TimeUnit; * Creates intents based on the classification type. * @hide */ // TODO: Consider to support {@code descriptionWithAppName}. public final class LegacyClassificationIntentFactory implements ClassificationIntentFactory { private static final String TAG = "LegacyClassificationIntentFactory"; Loading Loading @@ -108,6 +109,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.email), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.email_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_SENDTO) .setData(Uri.parse(String.format("mailto:%s", text))), LabeledIntent.DEFAULT_REQUEST_CODE)); Loading @@ -115,6 +117,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.add_contact), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.add_contact_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_INSERT_OR_EDIT) .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE) .putExtra(ContactsContract.Intents.Insert.EMAIL, text), Loading @@ -133,6 +136,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.dial), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.dial_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_DIAL).setData( Uri.parse(String.format("tel:%s", text))), LabeledIntent.DEFAULT_REQUEST_CODE)); Loading @@ -141,6 +145,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.add_contact), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.add_contact_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_INSERT_OR_EDIT) .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE) .putExtra(ContactsContract.Intents.Insert.PHONE, text), Loading @@ -150,6 +155,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.sms), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.sms_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_SENDTO) .setData(Uri.parse(String.format("smsto:%s", text))), LabeledIntent.DEFAULT_REQUEST_CODE)); Loading @@ -166,6 +172,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.map), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.map_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_VIEW) .setData(Uri.parse(String.format("geo:0,0?q=%s", encText))), LabeledIntent.DEFAULT_REQUEST_CODE)); Loading @@ -185,6 +192,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.browse), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.browse_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_VIEW) .setDataAndNormalize(Uri.parse(text)) .putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()), Loading Loading @@ -216,6 +224,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.view_flight), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.view_flight_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_WEB_SEARCH) .putExtra(SearchManager.QUERY, text), text.hashCode())); Loading @@ -231,6 +240,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.view_calendar), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.view_calendar_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_VIEW).setData(builder.build()), LabeledIntent.DEFAULT_REQUEST_CODE); } Loading @@ -243,6 +253,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.add_calendar_event), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.add_calendar_event_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_INSERT) .setData(CalendarContract.Events.CONTENT_URI) .putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, isAllDay) Loading @@ -260,6 +271,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.define), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.define_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_DEFINE) .putExtra(Intent.EXTRA_TEXT, text), text.hashCode())); Loading core/java/android/view/textclassifier/intent/TemplateIntentFactory.java +1 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ public final class TemplateIntentFactory { remoteActionTemplate.titleWithoutEntity, remoteActionTemplate.titleWithEntity, remoteActionTemplate.description, remoteActionTemplate.descriptionWithAppName, createIntent(remoteActionTemplate), remoteActionTemplate.requestCode == null ? LabeledIntent.DEFAULT_REQUEST_CODE Loading core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -263,6 +263,7 @@ public class ActionsSuggestionsHelperTest { "title", null, "description", null, Intent.ACTION_VIEW, Uri.parse("http://www.android.com").toString(), null, Loading Loading
core/java/android/view/textclassifier/intent/ClassificationIntentFactory.java +1 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ public interface ClassificationIntentFactory { context.getString(com.android.internal.R.string.translate), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.translate_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_TRANSLATE) // TODO: Probably better to introduce a "translate" scheme instead of // using EXTRA_TEXT. Loading
core/java/android/view/textclassifier/intent/LabeledIntent.java +33 −1 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ public final class LabeledIntent { @Nullable public final String titleWithEntity; public final String description; @Nullable public final String descriptionWithAppName; // Do not update this intent. public final Intent intent; public final int requestCode; Loading @@ -75,6 +77,7 @@ public final class LabeledIntent { @Nullable String titleWithoutEntity, @Nullable String titleWithEntity, String description, @Nullable String descriptionWithAppName, Intent intent, int requestCode) { if (TextUtils.isEmpty(titleWithEntity) && TextUtils.isEmpty(titleWithoutEntity)) { Loading @@ -84,6 +87,7 @@ public final class LabeledIntent { this.titleWithoutEntity = titleWithoutEntity; this.titleWithEntity = titleWithEntity; this.description = Preconditions.checkNotNull(description); this.descriptionWithAppName = descriptionWithAppName; this.intent = Preconditions.checkNotNull(intent); this.requestCode = requestCode; } Loading Loading @@ -141,11 +145,39 @@ public final class LabeledIntent { Log.w(TAG, "Custom titleChooser return null, fallback to the default titleChooser"); title = DEFAULT_TITLE_CHOOSER.chooseTitle(this, resolveInfo); } final RemoteAction action = new RemoteAction(icon, title, description, pendingIntent); final RemoteAction action = new RemoteAction(icon, title, resolveDescription(resolveInfo, pm), pendingIntent); action.setShouldShowIcon(shouldShowIcon); return new Result(resolvedIntent, action); } private String resolveDescription(ResolveInfo resolveInfo, PackageManager packageManager) { if (!TextUtils.isEmpty(descriptionWithAppName)) { // Example string format of descriptionWithAppName: "Use %1$s to open map". String applicationName = getApplicationName(resolveInfo, packageManager); if (!TextUtils.isEmpty(applicationName)) { return String.format(descriptionWithAppName, applicationName); } } return description; } @Nullable private String getApplicationName( ResolveInfo resolveInfo, PackageManager packageManager) { if (resolveInfo.activityInfo == null) { return null; } if ("android".equals(resolveInfo.activityInfo.packageName)) { return null; } if (resolveInfo.activityInfo.applicationInfo == null) { return null; } return (String) packageManager.getApplicationLabel( resolveInfo.activityInfo.applicationInfo); } private Bundle getFromTextClassifierExtra(@Nullable Bundle textLanguagesBundle) { if (textLanguagesBundle != null) { final Bundle bundle = new Bundle(); Loading
core/java/android/view/textclassifier/intent/LegacyClassificationIntentFactory.java +12 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import java.util.concurrent.TimeUnit; * Creates intents based on the classification type. * @hide */ // TODO: Consider to support {@code descriptionWithAppName}. public final class LegacyClassificationIntentFactory implements ClassificationIntentFactory { private static final String TAG = "LegacyClassificationIntentFactory"; Loading Loading @@ -108,6 +109,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.email), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.email_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_SENDTO) .setData(Uri.parse(String.format("mailto:%s", text))), LabeledIntent.DEFAULT_REQUEST_CODE)); Loading @@ -115,6 +117,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.add_contact), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.add_contact_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_INSERT_OR_EDIT) .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE) .putExtra(ContactsContract.Intents.Insert.EMAIL, text), Loading @@ -133,6 +136,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.dial), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.dial_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_DIAL).setData( Uri.parse(String.format("tel:%s", text))), LabeledIntent.DEFAULT_REQUEST_CODE)); Loading @@ -141,6 +145,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.add_contact), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.add_contact_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_INSERT_OR_EDIT) .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE) .putExtra(ContactsContract.Intents.Insert.PHONE, text), Loading @@ -150,6 +155,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.sms), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.sms_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_SENDTO) .setData(Uri.parse(String.format("smsto:%s", text))), LabeledIntent.DEFAULT_REQUEST_CODE)); Loading @@ -166,6 +172,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.map), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.map_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_VIEW) .setData(Uri.parse(String.format("geo:0,0?q=%s", encText))), LabeledIntent.DEFAULT_REQUEST_CODE)); Loading @@ -185,6 +192,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.browse), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.browse_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_VIEW) .setDataAndNormalize(Uri.parse(text)) .putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()), Loading Loading @@ -216,6 +224,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.view_flight), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.view_flight_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_WEB_SEARCH) .putExtra(SearchManager.QUERY, text), text.hashCode())); Loading @@ -231,6 +240,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.view_calendar), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.view_calendar_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_VIEW).setData(builder.build()), LabeledIntent.DEFAULT_REQUEST_CODE); } Loading @@ -243,6 +253,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.add_calendar_event), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.add_calendar_event_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_INSERT) .setData(CalendarContract.Events.CONTENT_URI) .putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, isAllDay) Loading @@ -260,6 +271,7 @@ public final class LegacyClassificationIntentFactory implements ClassificationIn context.getString(com.android.internal.R.string.define), /* titleWithEntity */ null, context.getString(com.android.internal.R.string.define_desc), /* descriptionWithAppName */ null, new Intent(Intent.ACTION_DEFINE) .putExtra(Intent.EXTRA_TEXT, text), text.hashCode())); Loading
core/java/android/view/textclassifier/intent/TemplateIntentFactory.java +1 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ public final class TemplateIntentFactory { remoteActionTemplate.titleWithoutEntity, remoteActionTemplate.titleWithEntity, remoteActionTemplate.description, remoteActionTemplate.descriptionWithAppName, createIntent(remoteActionTemplate), remoteActionTemplate.requestCode == null ? LabeledIntent.DEFAULT_REQUEST_CODE Loading
core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -263,6 +263,7 @@ public class ActionsSuggestionsHelperTest { "title", null, "description", null, Intent.ACTION_VIEW, Uri.parse("http://www.android.com").toString(), null, Loading