Merge "Fix bug 5037642 - Refine back button behavior for action bar modes."
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 6bb40a4..678751c 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -370,6 +370,19 @@
         mMenuView = menuView;
     }
 
+    public boolean hasExpandedActionView() {
+        return mExpandedMenuPresenter != null &&
+                mExpandedMenuPresenter.mCurrentExpandedItem != null;
+    }
+
+    public void collapseActionView() {
+        final MenuItemImpl item = mExpandedMenuPresenter == null ? null :
+                mExpandedMenuPresenter.mCurrentExpandedItem;
+        if (item != null) {
+            item.collapseActionView();
+        }
+    }
+
     public void setCustomNavigationView(View view) {
         final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0;
         if (mCustomNavView != null && showCustom) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 4be00c5..b963b13 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -1668,14 +1668,6 @@
                 }
             }
 
-            // Back cancels action modes first.
-            if (mActionMode != null && keyCode == KeyEvent.KEYCODE_BACK) {
-                if (action == KeyEvent.ACTION_UP) {
-                    mActionMode.finish();
-                }
-                return true;
-            }
-
             if (!isDestroyed()) {
                 final Callback cb = getCallback();
                 final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event)
@@ -1684,6 +1676,7 @@
                     return true;
                 }
             }
+
             return isDown ? PhoneWindow.this.onKeyDown(mFeatureId, event.getKeyCode(), event)
                     : PhoneWindow.this.onKeyUp(mFeatureId, event.getKeyCode(), event);
         }
@@ -1730,7 +1723,32 @@
         }
 
         public boolean superDispatchKeyEvent(KeyEvent event) {
-            return super.dispatchKeyEvent(event);
+            if (super.dispatchKeyEvent(event)) {
+                return true;
+            }
+
+            // Not handled by the view hierarchy, does the action bar want it
+            // to cancel out of something special?
+            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+                final int action = event.getAction();
+                // Back cancels action modes first.
+                if (mActionMode != null) {
+                    if (action == KeyEvent.ACTION_UP) {
+                        mActionMode.finish();
+                    }
+                    return true;
+                }
+
+                // Next collapse any expanded action views.
+                if (mActionBar != null && mActionBar.hasExpandedActionView()) {
+                    if (action == KeyEvent.ACTION_UP) {
+                        mActionBar.collapseActionView();
+                    }
+                    return true;
+                }
+            }
+
+            return false;
         }
 
         public boolean superDispatchKeyShortcutEvent(KeyEvent event) {