From 2af189a0a7962501b808cd50499d978a7cd10d81 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Fri, 5 Feb 2016 15:52:02 -0800 Subject: [PATCH] Preserve compatibility for ViewGroup#showContextMenuForChild Have the new showContextMenuForChild(View, float, float) call through to the old showContextMenuForChild(View) before recursing up to its parent. This ensures that existing apps with custom views that override the old method still get called as expected if they implement custom behavior. Unlike some other similar circumstances we aren't implementing this to be bidirectional as the new behavior doesn't need to be triggered by invoking the old. If the older method is invoked explicitly we will still show old-style dialog context menus instead of the newer popup style since we won't have a good place to visually anchor a popup. Bug 26919262 Change-Id: Ie09f922d322b5a24789c7867820c4bc43824c385 (cherry picked from commit 759a4c54004af6ac9f42c9c42496a5eb73c461ff) --- core/java/android/view/ViewGroup.java | 26 +++++++++++++++++++++++ core/java/android/view/ViewParent.java | 5 ++++- core/java/android/widget/AbsListView.java | 3 +++ core/java/android/widget/Gallery.java | 3 +++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 3fe6b8e2e3f81..c54ce80631bd2 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -386,6 +386,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ private static final int FLAG_START_ACTION_MODE_FOR_CHILD_IS_NOT_TYPED = 0x10000000; + /** + * When set, indicates that a call to showContextMenuForChild was made with explicit + * coordinates within the initiating child view. + */ + private static final int FLAG_SHOW_CONTEXT_MENU_WITH_COORDS = 0x20000000; + /** * Indicates which types of drawing caches are to be kept in memory. * This field should be made private, so it is hidden from the SDK. @@ -756,11 +762,31 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @Override public boolean showContextMenuForChild(View originalView) { + if (isShowingContextMenuWithCoords()) { + // We're being called for compatibility. Return false and let the version + // with coordinates recurse up. + return false; + } return mParent != null && mParent.showContextMenuForChild(originalView); } + /** + * @hide used internally for compatibility with existing app code only + */ + public final boolean isShowingContextMenuWithCoords() { + return (mGroupFlags & FLAG_SHOW_CONTEXT_MENU_WITH_COORDS) != 0; + } + @Override public boolean showContextMenuForChild(View originalView, float x, float y) { + try { + mGroupFlags |= FLAG_SHOW_CONTEXT_MENU_WITH_COORDS; + if (showContextMenuForChild(originalView)) { + return true; + } + } finally { + mGroupFlags &= ~FLAG_SHOW_CONTEXT_MENU_WITH_COORDS; + } return mParent != null && mParent.showContextMenuForChild(originalView, x, y); } diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java index 1962be86ffb1c..06afef27cee5a 100644 --- a/core/java/android/view/ViewParent.java +++ b/core/java/android/view/ViewParent.java @@ -192,6 +192,9 @@ public interface ViewParent { * the subclass is added directly to the window manager (for example, * {@link ViewManager#addView(View, android.view.ViewGroup.LayoutParams)}) * then it should override this and show the context menu. + *

+ * If a subclass overrides this method it should also override + * {@link #showContextMenuForChild(View)}. * * @param originalView the source view where the context menu was first * invoked @@ -202,7 +205,7 @@ public interface ViewParent { * @return {@code true} if the context menu was shown, {@code false} * otherwise */ - public boolean showContextMenuForChild(View originalView, float x, float y); + boolean showContextMenuForChild(View originalView, float x, float y); /** * Have the parent populate the specified context menu if it has anything to diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 7b6fa6dab075b..b689564cfe589 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -3247,6 +3247,9 @@ public abstract class AbsListView extends AdapterView implements Te @Override public boolean showContextMenuForChild(View originalView) { + if (isShowingContextMenuWithCoords()) { + return false; + } return showContextMenuForChildInternal(originalView, 0, 0, false); } diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java index a6ef572a2e3a0..7655f3df93f30 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -1160,6 +1160,9 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList @Override public boolean showContextMenuForChild(View originalView) { + if (isShowingContextMenuWithCoords()) { + return false; + } return showContextMenuForChildInternal(originalView, 0, 0, false); }