Dispatch more menu events to window callbacks from ToolbarActionBar

Wire through the callbacks that result in onPrepareOptionsMenu being
called properly when an activity overflow menu is opened.

Bug 17326424

Change-Id: Ifc5b67af0d215f210bb00326f82f60ba55a36d52
diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java
index 96abf51..9b65232 100644
--- a/core/java/android/widget/ActionMenuView.java
+++ b/core/java/android/widget/ActionMenuView.java
@@ -29,6 +29,7 @@
 import com.android.internal.view.menu.ActionMenuItemView;
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.view.menu.MenuItemImpl;
+import com.android.internal.view.menu.MenuPresenter;
 import com.android.internal.view.menu.MenuView;
 
 /**
@@ -53,6 +54,7 @@
 
     private boolean mReserveOverflow;
     private ActionMenuPresenter mPresenter;
+    private MenuPresenter.Callback mActionMenuPresenterCallback;
     private boolean mFormatItems;
     private int mFormatItemsWidth;
     private int mMinCellSize;
@@ -608,7 +610,8 @@
             mMenu = new MenuBuilder(context);
             mMenu.setCallback(new MenuBuilderCallback());
             mPresenter = new ActionMenuPresenter(context);
-            mPresenter.setCallback(new ActionMenuPresenterCallback());
+            mPresenter.setCallback(mActionMenuPresenterCallback != null
+                    ? mActionMenuPresenterCallback : new ActionMenuPresenterCallback());
             mMenu.addMenuPresenter(mPresenter, mPopupContext);
             mPresenter.setMenuView(this);
         }
@@ -617,6 +620,14 @@
     }
 
     /**
+     * Must be called before the first call to getMenu()
+     * @hide
+     */
+    public void setActionMenuPresenterCallback(MenuPresenter.Callback cb) {
+        mActionMenuPresenterCallback = cb;
+    }
+
+    /**
      * Returns the current menu or null if one has not yet been configured.
      * @hide Internal use only for action bar integration
      */
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 3ba03b8..80309f7 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -37,6 +37,7 @@
 import android.view.ViewGroup;
 
 import com.android.internal.R;
+import com.android.internal.app.ToolbarActionBar;
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.view.menu.MenuItemImpl;
 import com.android.internal.view.menu.MenuPresenter;
@@ -153,6 +154,7 @@
     private ToolbarWidgetWrapper mWrapper;
     private ActionMenuPresenter mOuterActionMenuPresenter;
     private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
+    private MenuPresenter.Callback mActionMenuPresenterCallback;
 
     private boolean mCollapsible;
 
@@ -825,6 +827,7 @@
             mMenuView = new ActionMenuView(getContext());
             mMenuView.setPopupTheme(mPopupTheme);
             mMenuView.setOnMenuItemClickListener(mMenuViewItemClickListener);
+            mMenuView.setActionMenuPresenterCallback(mActionMenuPresenterCallback);
             final LayoutParams lp = generateDefaultLayoutParams();
             lp.gravity = Gravity.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
             mMenuView.setLayoutParams(lp);
@@ -1678,6 +1681,14 @@
     }
 
     /**
+     * Must be called before the menu is accessed
+     * @hide
+     */
+    public void setActionMenuPresenterCallback(MenuPresenter.Callback cb) {
+        mActionMenuPresenterCallback = cb;
+    }
+
+    /**
      * Interface responsible for receiving menu item click events if the items themselves
      * do not have individual item click listeners.
      */
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index 6f1c7ec..3b024e9 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -35,6 +35,7 @@
 import android.widget.Toolbar;
 import com.android.internal.R;
 import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuPresenter;
 import com.android.internal.widget.DecorToolbar;
 import com.android.internal.widget.ToolbarWidgetWrapper;
 
@@ -45,6 +46,7 @@
     private DecorToolbar mDecorToolbar;
     private boolean mToolbarMenuPrepared;
     private Window.Callback mWindowCallback;
+    private boolean mMenuCallbackSet;
 
     private CharSequence mHomeDescription;
 
@@ -453,6 +455,10 @@
     }
 
     void populateOptionsMenu() {
+        if (!mMenuCallbackSet) {
+            mToolbar.setActionMenuPresenterCallback(new ActionMenuPresenterCallback());
+            mMenuCallbackSet = true;
+        }
         final Menu menu = mToolbar.getMenu();
         final MenuBuilder mb = menu instanceof MenuBuilder ? (MenuBuilder) menu : null;
         if (mb != null) {
@@ -514,4 +520,31 @@
             return result;
         }
     }
+
+    private final class ActionMenuPresenterCallback implements MenuPresenter.Callback {
+        private boolean mClosingActionMenu;
+
+        @Override
+        public boolean onOpenSubMenu(MenuBuilder subMenu) {
+            if (mWindowCallback != null) {
+                mWindowCallback.onMenuOpened(Window.FEATURE_ACTION_BAR, subMenu);
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
+            if (mClosingActionMenu) {
+                return;
+            }
+
+            mClosingActionMenu = true;
+            mToolbar.dismissPopupMenus();
+            if (mWindowCallback != null) {
+                mWindowCallback.onPanelClosed(Window.FEATURE_ACTION_BAR, menu);
+            }
+            mClosingActionMenu = false;
+        }
+    }
 }