Merge "Only handle Context submenus as dialogs when parent is a dialog"
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index e405564..f6b8e91 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -17,11 +17,13 @@
package com.android.internal.policy;
import com.android.internal.R;
+import com.android.internal.policy.PhoneWindow.PhoneWindowMenuCallback;
import com.android.internal.view.FloatingActionMode;
import com.android.internal.view.RootViewSurfaceTaker;
import com.android.internal.view.StandaloneActionMode;
import com.android.internal.view.menu.ContextMenuBuilder;
import com.android.internal.view.menu.MenuHelper;
+import com.android.internal.view.menu.MenuPresenter;
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.BackgroundFallback;
import com.android.internal.widget.DecorCaptionView;
@@ -684,9 +686,10 @@
}
// Reuse the context menu builder.
+ final PhoneWindowMenuCallback callback = mWindow.mContextMenuCallback;
if (mWindow.mContextMenu == null) {
mWindow.mContextMenu = new ContextMenuBuilder(getContext());
- mWindow.mContextMenu.setCallback(mWindow.mContextMenuCallback);
+ mWindow.mContextMenu.setCallback(callback);
} else {
mWindow.mContextMenu.clearAll();
}
@@ -698,9 +701,11 @@
helper = mWindow.mContextMenu.showDialog(originalView, originalView.getWindowToken());
}
- if (helper != null) {
- helper.setPresenterCallback(mWindow.mContextMenuCallback);
- }
+ // If it's a dialog, the callback needs to handle showing sub-menus.
+ // Either way, the callback is required for propagating selection to
+ // Context.onContextMenuItemSelected().
+ callback.setShowDialogForSubmenu(!isPopup);
+ helper.setPresenterCallback(callback);
mWindow.mContextMenuHelper = helper;
return helper != null;
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 86bd782..1e9035b 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -127,7 +127,7 @@
* Simple callback used by the context menu and its submenus. The options
* menu submenus do not use this (their behavior is more complex).
*/
- final DialogMenuCallback mContextMenuCallback = new DialogMenuCallback(FEATURE_CONTEXT_MENU);
+ final PhoneWindowMenuCallback mContextMenuCallback = new PhoneWindowMenuCallback(this);
final TypedValue mMinWidthMajor = new TypedValue();
final TypedValue mMinWidthMinor = new TypedValue();
@@ -3592,27 +3592,34 @@
* <li> Calls back to the callback's onMenuItemSelected when an item is
* selected.
*/
- private final class DialogMenuCallback implements MenuBuilder.Callback, MenuPresenter.Callback {
- private int mFeatureId;
+ public static final class PhoneWindowMenuCallback
+ implements MenuBuilder.Callback, MenuPresenter.Callback {
+ private static final int FEATURE_ID = FEATURE_CONTEXT_MENU;
+
+ private final PhoneWindow mWindow;
+
private MenuDialogHelper mSubMenuHelper;
- public DialogMenuCallback(int featureId) {
- mFeatureId = featureId;
+ private boolean mShowDialogForSubmenu;
+
+ public PhoneWindowMenuCallback(PhoneWindow window) {
+ mWindow = window;
}
+ @Override
public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
if (menu.getRootMenu() != menu) {
onCloseSubMenu(menu);
}
if (allMenusAreClosing) {
- Callback callback = getCallback();
- if (callback != null && !isDestroyed()) {
- callback.onPanelClosed(mFeatureId, menu);
+ final Callback callback = mWindow.getCallback();
+ if (callback != null && !mWindow.isDestroyed()) {
+ callback.onPanelClosed(FEATURE_ID, menu);
}
- if (menu == mContextMenu) {
- dismissContextMenu();
+ if (menu == mWindow.mContextMenu) {
+ mWindow.dismissContextMenu();
}
// Dismiss the submenu, if it is showing
@@ -3623,33 +3630,45 @@
}
}
- public void onCloseSubMenu(MenuBuilder menu) {
- Callback callback = getCallback();
- if (callback != null && !isDestroyed()) {
- callback.onPanelClosed(mFeatureId, menu.getRootMenu());
+ private void onCloseSubMenu(MenuBuilder menu) {
+ final Callback callback = mWindow.getCallback();
+ if (callback != null && !mWindow.isDestroyed()) {
+ callback.onPanelClosed(FEATURE_ID, menu.getRootMenu());
}
}
+ @Override
public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
- Callback callback = getCallback();
- return (callback != null && !isDestroyed())
- && callback.onMenuItemSelected(mFeatureId, item);
+ final Callback callback = mWindow.getCallback();
+ return callback != null && !mWindow.isDestroyed()
+ && callback.onMenuItemSelected(FEATURE_ID, item);
}
+ @Override
public void onMenuModeChange(MenuBuilder menu) {
}
+ @Override
public boolean onOpenSubMenu(MenuBuilder subMenu) {
- if (subMenu == null) return false;
+ if (subMenu == null) {
+ return false;
+ }
// Set a simple callback for the submenu
subMenu.setCallback(this);
- // The window manager will give us a valid window token
- mSubMenuHelper = new MenuDialogHelper(subMenu);
- mSubMenuHelper.show(null);
+ if (mShowDialogForSubmenu) {
+ // The window manager will give us a valid window token
+ mSubMenuHelper = new MenuDialogHelper(subMenu);
+ mSubMenuHelper.show(null);
+ return true;
+ }
- return true;
+ return false;
+ }
+
+ public void setShowDialogForSubmenu(boolean enabled) {
+ mShowDialogForSubmenu = enabled;
}
}
diff --git a/core/java/com/android/internal/view/menu/StandardMenuPopup.java b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
index 6a5f6d8..c2adc42 100644
--- a/core/java/com/android/internal/view/menu/StandardMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
@@ -242,13 +242,13 @@
@Override
public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
if (subMenu.hasVisibleItems()) {
- MenuPopupHelper subPopup = new MenuPopupHelper(
- mContext, subMenu, mShownAnchorView, mOverflowOnly, mPopupStyleAttr,
- mPopupStyleRes);
+ final MenuPopupHelper subPopup = new MenuPopupHelper(mContext, subMenu,
+ mShownAnchorView, mOverflowOnly, mPopupStyleAttr, mPopupStyleRes);
subPopup.setPresenterCallback(mPresenterCallback);
subPopup.setForceShowIcon(mAdapter.getForceShowIcon());
- if (subPopup.tryShow()) {
+ // Show the new sub-menu popup at the same location as this popup.
+ if (subPopup.tryShow(mXOffset, mYOffset)) {
if (mPresenterCallback != null) {
mPresenterCallback.onOpenSubMenu(subMenu);
}