summaryrefslogtreecommitdiff
path: root/android/widget
diff options
context:
space:
mode:
authorJustin Klaassen <justinklaassen@google.com>2017-10-30 17:25:37 -0400
committerJustin Klaassen <justinklaassen@google.com>2017-10-30 17:25:37 -0400
commit46c77c203439b3b37c99d09e326df4b1fe08c10b (patch)
tree70d29abbfbb1106cd0830b33bc7e69e6fb151b1e /android/widget
parent47ed54e5d312f899507d28d6e95ccc18a0de19fe (diff)
downloadandroid-28-46c77c203439b3b37c99d09e326df4b1fe08c10b.tar.gz
Import Android SDK Platform P [4423826]
/google/data/ro/projects/android/fetch_artifact \ --bid 4423826 \ --target sdk_phone_armv7-win_sdk \ sdk-repo-linux-sources-4423826.zip AndroidVersion.ApiLevel has been modified to appear as 28 Change-Id: I45f7bdc9b9c1cdcba75386623ae5f3ead6db4da8
Diffstat (limited to 'android/widget')
-rw-r--r--android/widget/AdapterView.java10
-rw-r--r--android/widget/Editor.java162
-rw-r--r--android/widget/ListPopupWindow.java2
-rw-r--r--android/widget/PopupWindow.java4
-rw-r--r--android/widget/RemoteViews.java31
5 files changed, 151 insertions, 58 deletions
diff --git a/android/widget/AdapterView.java b/android/widget/AdapterView.java
index dd01251c..6c192563 100644
--- a/android/widget/AdapterView.java
+++ b/android/widget/AdapterView.java
@@ -202,7 +202,7 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
* The last selected position we used when notifying
*/
int mOldSelectedPosition = INVALID_POSITION;
-
+
/**
* The id of the last selected position we used when notifying
*/
@@ -382,7 +382,7 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
* position is different from the previously selected position or if
* there was no selected item.</p>
*
- * Impelmenters can call getItemAtPosition(position) if they need to access the
+ * Implementers can call getItemAtPosition(position) if they need to access the
* data associated with the selected item.
*
* @param parent The AdapterView where the selection happened
@@ -778,8 +778,8 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
// We are now GONE, so pending layouts will not be dispatched.
// Force one here to make sure that the state of the list matches
// the state of the adapter.
- if (mDataChanged) {
- this.onLayout(false, mLeft, mTop, mRight, mBottom);
+ if (mDataChanged) {
+ this.onLayout(false, mLeft, mTop, mRight, mBottom);
}
} else {
if (mEmptyView != null) mEmptyView.setVisibility(View.GONE);
@@ -1304,4 +1304,4 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
structure.setAutofillOptions(options);
}
}
-} \ No newline at end of file
+}
diff --git a/android/widget/Editor.java b/android/widget/Editor.java
index 384f4f83..e6da69dc 100644
--- a/android/widget/Editor.java
+++ b/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,9 +163,9 @@ 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;
- private static final float MAGNIFIER_ZOOM = 1.25f;
@IntDef({MagnifierHandleTrigger.SELECTION_START,
MagnifierHandleTrigger.SELECTION_END,
MagnifierHandleTrigger.INSERTION})
@@ -3793,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;
@@ -3820,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);
@@ -3903,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) {
@@ -3943,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
@@ -3982,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());
@@ -4029,6 +4100,8 @@ public class Editor {
if (mSelectionModifierCursorController != null) {
mSelectionModifierCursorController.hide();
}
+
+ mAssistClickHandlers.clear();
}
@Override
@@ -4547,7 +4620,7 @@ public class Editor {
+ mTextView.getTotalPaddingTop() - mTextView.getScrollY();
suspendBlink();
- mMagnifier.show(xPosInView, yPosInView, MAGNIFIER_ZOOM);
+ mMagnifier.show(xPosInView, yPosInView);
}
protected final void dismissMagnifier() {
@@ -6560,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);
diff --git a/android/widget/ListPopupWindow.java b/android/widget/ListPopupWindow.java
index 0d676153..adf366a4 100644
--- a/android/widget/ListPopupWindow.java
+++ b/android/widget/ListPopupWindow.java
@@ -657,6 +657,7 @@ public class ListPopupWindow implements ShowableListMenu {
mPopup.update(getAnchorView(), mDropDownHorizontalOffset,
mDropDownVerticalOffset, (widthSpec < 0)? -1 : widthSpec,
(heightSpec < 0)? -1 : heightSpec);
+ mPopup.getContentView().restoreDefaultFocus();
} else {
final int widthSpec;
if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) {
@@ -695,6 +696,7 @@ public class ListPopupWindow implements ShowableListMenu {
mPopup.showAsDropDown(getAnchorView(), mDropDownHorizontalOffset,
mDropDownVerticalOffset, mDropDownGravity);
mDropDownList.setSelection(ListView.INVALID_POSITION);
+ mPopup.getContentView().restoreDefaultFocus();
if (!mModal || mDropDownList.isInTouchMode()) {
clearListSelection();
diff --git a/android/widget/PopupWindow.java b/android/widget/PopupWindow.java
index 23ebadb3..8dc8cab1 100644
--- a/android/widget/PopupWindow.java
+++ b/android/widget/PopupWindow.java
@@ -2461,14 +2461,14 @@ public class PopupWindow {
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
enterTransition.addTarget(child);
- child.setVisibility(View.INVISIBLE);
+ child.setTransitionVisibility(View.INVISIBLE);
}
TransitionManager.beginDelayedTransition(this, enterTransition);
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
- child.setVisibility(View.VISIBLE);
+ child.setTransitionVisibility(View.VISIBLE);
}
}
diff --git a/android/widget/RemoteViews.java b/android/widget/RemoteViews.java
index 631f3882..e3309161 100644
--- a/android/widget/RemoteViews.java
+++ b/android/widget/RemoteViews.java
@@ -81,6 +81,7 @@ import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
import java.util.Stack;
import java.util.concurrent.Executor;
@@ -185,6 +186,9 @@ public class RemoteViews implements Parcelable, Filter {
*/
private boolean mIsWidgetCollectionChild = false;
+ /** Class cookies of the Parcel this instance was read from. */
+ private final Map<Class, Object> mClassCookies;
+
private static final OnClickHandler DEFAULT_ON_CLICK_HANDLER = new OnClickHandler();
private static final ArrayMap<MethodKey, MethodArgs> sMethods = new ArrayMap<>();
@@ -1505,10 +1509,10 @@ public class RemoteViews implements Parcelable, Filter {
}
ViewGroupActionAdd(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info,
- int depth) {
+ int depth, Map<Class, Object> classCookies) {
viewId = parcel.readInt();
mIndex = parcel.readInt();
- mNestedViews = new RemoteViews(parcel, bitmapCache, info, depth);
+ mNestedViews = new RemoteViews(parcel, bitmapCache, info, depth, classCookies);
}
public void writeToParcel(Parcel dest, int flags) {
@@ -2120,6 +2124,7 @@ public class RemoteViews implements Parcelable, Filter {
mApplication = application;
mLayoutId = layoutId;
mBitmapCache = new BitmapCache();
+ mClassCookies = null;
}
private boolean hasLandscapeAndPortraitLayouts() {
@@ -2149,6 +2154,9 @@ public class RemoteViews implements Parcelable, Filter {
mBitmapCache = new BitmapCache();
configureRemoteViewsAsChild(landscape);
configureRemoteViewsAsChild(portrait);
+
+ mClassCookies = (portrait.mClassCookies != null)
+ ? portrait.mClassCookies : landscape.mClassCookies;
}
/**
@@ -2161,15 +2169,16 @@ public class RemoteViews implements Parcelable, Filter {
mLayoutId = src.mLayoutId;
mIsWidgetCollectionChild = src.mIsWidgetCollectionChild;
mReapplyDisallowed = src.mReapplyDisallowed;
+ mClassCookies = src.mClassCookies;
if (src.hasLandscapeAndPortraitLayouts()) {
mLandscape = new RemoteViews(src.mLandscape);
mPortrait = new RemoteViews(src.mPortrait);
-
}
if (src.mActions != null) {
Parcel p = Parcel.obtain();
+ p.putClassCookies(mClassCookies);
src.writeActionsToParcel(p);
p.setDataPosition(0);
// Since src is already in memory, we do not care about stack overflow as it has
@@ -2189,10 +2198,11 @@ public class RemoteViews implements Parcelable, Filter {
* @param parcel
*/
public RemoteViews(Parcel parcel) {
- this(parcel, null, null, 0);
+ this(parcel, null, null, 0, null);
}
- private RemoteViews(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info, int depth) {
+ private RemoteViews(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info, int depth,
+ Map<Class, Object> classCookies) {
if (depth > MAX_NESTED_VIEWS
&& (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID)) {
throw new IllegalArgumentException("Too many nested views.");
@@ -2204,8 +2214,11 @@ public class RemoteViews implements Parcelable, Filter {
// We only store a bitmap cache in the root of the RemoteViews.
if (bitmapCache == null) {
mBitmapCache = new BitmapCache(parcel);
+ // Store the class cookies such that they are available when we clone this RemoteView.
+ mClassCookies = parcel.copyClassCookies();
} else {
setBitmapCache(bitmapCache);
+ mClassCookies = classCookies;
setNotRoot();
}
@@ -2218,8 +2231,9 @@ public class RemoteViews implements Parcelable, Filter {
readActionsFromParcel(parcel, depth);
} else {
// MODE_HAS_LANDSCAPE_AND_PORTRAIT
- mLandscape = new RemoteViews(parcel, mBitmapCache, info, depth);
- mPortrait = new RemoteViews(parcel, mBitmapCache, mLandscape.mApplication, depth);
+ mLandscape = new RemoteViews(parcel, mBitmapCache, info, depth, mClassCookies);
+ mPortrait = new RemoteViews(parcel, mBitmapCache, mLandscape.mApplication, depth,
+ mClassCookies);
mApplication = mPortrait.mApplication;
mLayoutId = mPortrait.getLayoutId();
}
@@ -2246,7 +2260,8 @@ public class RemoteViews implements Parcelable, Filter {
case REFLECTION_ACTION_TAG:
return new ReflectionAction(parcel);
case VIEW_GROUP_ACTION_ADD_TAG:
- return new ViewGroupActionAdd(parcel, mBitmapCache, mApplication, depth);
+ return new ViewGroupActionAdd(parcel, mBitmapCache, mApplication, depth,
+ mClassCookies);
case VIEW_GROUP_ACTION_REMOVE_TAG:
return new ViewGroupActionRemove(parcel);
case VIEW_CONTENT_NAVIGATION_TAG: