diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2017-10-25 00:03:21 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-10-25 00:03:21 +0000 |
| commit | 5a6a5417ec5fe2a9f18577abc6e6906e8377b066 (patch) | |
| tree | 82dd59cba25ddc7674eefd757fe317c5b5e73e8c /core/java | |
| parent | 0fcdd716e0c3c435493fdad3b20d4bdff09d26df (diff) | |
| parent | 3049d8c1c0d9cee17ca1f55d2caa749deb93e337 (diff) | |
Merge "TextView: Support multiple textAssist menu items."
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/widget/Editor.java | 159 |
1 files changed, 118 insertions, 41 deletions
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 68ee19737fd0..e6da69dc95c7 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -129,7 +129,7 @@ import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.List; - +import java.util.Map; /** * Helper class used by TextView to handle editable text views. @@ -163,6 +163,7 @@ public class Editor { private static final int MENU_ITEM_ORDER_REPLACE = 9; private static final int MENU_ITEM_ORDER_AUTOFILL = 10; private static final int MENU_ITEM_ORDER_PASTE_AS_PLAIN_TEXT = 11; + private static final int MENU_ITEM_ORDER_SECONDARY_ASSIST_ACTIONS_START = 50; private static final int MENU_ITEM_ORDER_PROCESS_TEXT_INTENT_ACTIONS_START = 100; @IntDef({MagnifierHandleTrigger.SELECTION_START, @@ -3792,6 +3793,7 @@ public class Editor { private final RectF mSelectionBounds = new RectF(); private final boolean mHasSelection; private final int mHandleHeight; + private final Map<MenuItem, OnClickListener> mAssistClickHandlers = new HashMap<>(); public TextActionModeCallback(boolean hasSelection) { mHasSelection = hasSelection; @@ -3819,6 +3821,8 @@ public class Editor { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { + mAssistClickHandlers.clear(); + mode.setTitle(null); mode.setSubtitle(null); mode.setTitleOptionalHint(true); @@ -3902,14 +3906,14 @@ public class Editor { updateSelectAllItem(menu); updateReplaceItem(menu); - updateAssistMenuItem(menu); + updateAssistMenuItems(menu); } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { updateSelectAllItem(menu); updateReplaceItem(menu); - updateAssistMenuItem(menu); + updateAssistMenuItems(menu); Callback customCallback = getCustomCallback(); if (customCallback != null) { @@ -3942,32 +3946,118 @@ public class Editor { } } - private void updateAssistMenuItem(Menu menu) { - menu.removeItem(TextView.ID_ASSIST); + private void updateAssistMenuItems(Menu menu) { + clearAssistMenuItems(menu); + if (!mTextView.isDeviceProvisioned()) { + return; + } final TextClassification textClassification = getSelectionActionModeHelper().getTextClassification(); - if (canAssist()) { - menu.add(TextView.ID_ASSIST, TextView.ID_ASSIST, MENU_ITEM_ORDER_ASSIST, - textClassification.getLabel()) - .setIcon(textClassification.getIcon()) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - mMetricsLogger.write( - new LogMaker(MetricsEvent.TEXT_SELECTION_MENU_ITEM_ASSIST) - .setType(MetricsEvent.TYPE_OPEN) - .setSubtype(textClassification.getLogType())); + final int count = textClassification != null ? textClassification.getActionCount() : 0; + for (int i = 0; i < count; i++) { + if (!isValidAssistMenuItem(i)) { + continue; + } + final int groupId = TextView.ID_ASSIST; + final int order = (i == 0) + ? MENU_ITEM_ORDER_ASSIST + : MENU_ITEM_ORDER_SECONDARY_ASSIST_ACTIONS_START + i; + final int id = (i == 0) ? TextView.ID_ASSIST : Menu.NONE; + final int showAsFlag = (i == 0) + ? MenuItem.SHOW_AS_ACTION_ALWAYS + : MenuItem.SHOW_AS_ACTION_NEVER; + final MenuItem item = menu.add( + groupId, id, order, textClassification.getLabel(i)) + .setIcon(textClassification.getIcon(i)) + .setIntent(textClassification.getIntent(i)); + item.setShowAsAction(showAsFlag); + mAssistClickHandlers.put(item, textClassification.getOnClickListener(i)); + if (id == TextView.ID_ASSIST) { + mMetricsLogger.write( + new LogMaker(MetricsEvent.TEXT_SELECTION_MENU_ITEM_ASSIST) + .setType(MetricsEvent.TYPE_OPEN) + .setSubtype(textClassification.getLogType())); + } + } + } + + private void clearAssistMenuItems(Menu menu) { + int i = 0; + while (i < menu.size()) { + final MenuItem menuItem = menu.getItem(i); + if (menuItem.getGroupId() == TextView.ID_ASSIST) { + menu.removeItem(menuItem.getItemId()); + continue; + } + i++; + } + } + + private boolean isValidAssistMenuItem(int index) { + final TextClassification textClassification = + getSelectionActionModeHelper().getTextClassification(); + if (!mTextView.isDeviceProvisioned() || textClassification == null + || index < 0 || index >= textClassification.getActionCount()) { + return false; + } + final Drawable icon = textClassification.getIcon(index); + final CharSequence label = textClassification.getLabel(index); + final boolean hasUi = icon != null || !TextUtils.isEmpty(label); + final OnClickListener onClick = textClassification.getOnClickListener(index); + final Intent intent = textClassification.getIntent(index); + final boolean hasAction = onClick != null || isSupportedIntent(intent); + return hasUi && hasAction; + } + + private boolean isSupportedIntent(Intent intent) { + if (intent == null) { + return false; + } + final Context context = mTextView.getContext(); + final ResolveInfo info = context.getPackageManager().resolveActivity(intent, 0); + final boolean samePackage = context.getPackageName().equals( + info.activityInfo.packageName); + if (samePackage) { + return true; } + + final boolean exported = info.activityInfo.exported; + final boolean requiresPermission = info.activityInfo.permission != null; + final boolean hasPermission = !requiresPermission + || context.checkSelfPermission(info.activityInfo.permission) + == PackageManager.PERMISSION_GRANTED; + return exported && hasPermission; } - private boolean canAssist() { + private boolean onAssistMenuItemClicked(MenuItem assistMenuItem) { + Preconditions.checkArgument(assistMenuItem.getGroupId() == TextView.ID_ASSIST); + final TextClassification textClassification = getSelectionActionModeHelper().getTextClassification(); - return mTextView.isDeviceProvisioned() - && textClassification != null - && (textClassification.getIcon() != null - || !TextUtils.isEmpty(textClassification.getLabel())) - && (textClassification.getOnClickListener() != null - || (textClassification.getIntent() != null - && mTextView.getContext().canStartActivityForResult())); + if (!mTextView.isDeviceProvisioned() || textClassification == null) { + // No textClassification result to handle the click. Eat the click. + return true; + } + + OnClickListener onClickListener = mAssistClickHandlers.get(assistMenuItem); + if (onClickListener == null) { + final Intent intent = assistMenuItem.getIntent(); + if (intent != null) { + onClickListener = TextClassification.createStartActivityOnClickListener( + mTextView.getContext(), intent); + } + } + if (onClickListener != null) { + onClickListener.onClick(mTextView); + stopTextActionMode(); + if (assistMenuItem.getItemId() == TextView.ID_ASSIST) { + mMetricsLogger.action( + MetricsEvent.ACTION_TEXT_SELECTION_MENU_ITEM_ASSIST, + textClassification.getLogType()); + } + } + // We tried our best. + return true; } @Override @@ -3981,25 +4071,7 @@ public class Editor { if (customCallback != null && customCallback.onActionItemClicked(mode, item)) { return true; } - final TextClassification textClassification = - getSelectionActionModeHelper().getTextClassification(); - if (TextView.ID_ASSIST == item.getItemId() && textClassification != null) { - final OnClickListener onClickListener = - textClassification.getOnClickListener(); - if (onClickListener != null) { - onClickListener.onClick(mTextView); - } else { - final Intent intent = textClassification.getIntent(); - if (intent != null) { - TextClassification.createStartActivityOnClickListener( - mTextView.getContext(), intent) - .onClick(mTextView); - } - } - mMetricsLogger.action( - MetricsEvent.ACTION_TEXT_SELECTION_MENU_ITEM_ASSIST, - textClassification.getLogType()); - stopTextActionMode(); + if (item.getGroupId() == TextView.ID_ASSIST && onAssistMenuItemClicked(item)) { return true; } return mTextView.onTextContextMenuItem(item.getItemId()); @@ -4028,6 +4100,8 @@ public class Editor { if (mSelectionModifierCursorController != null) { mSelectionModifierCursorController.hide(); } + + mAssistClickHandlers.clear(); } @Override @@ -6559,6 +6633,9 @@ public class Editor { private void loadSupportedActivities() { mSupportedActivities.clear(); + if (!mContext.canStartActivityForResult()) { + return; + } PackageManager packageManager = mTextView.getContext().getPackageManager(); List<ResolveInfo> unfiltered = packageManager.queryIntentActivities(createProcessTextIntent(), 0); |
