Merge "Fix bug 5078498 - Icons jump around on split action bar"
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 06f753f..aaae691 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -162,7 +162,6 @@
         final ActionMenuView menuView = (ActionMenuView) mMenuView;
         ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
         actionItemView.setItemInvoker(menuView);
-        if (false) actionItemView.setExpandedFormat(menuView.isExpandedFormat());
     }
 
     @Override
@@ -174,7 +173,8 @@
     public void updateMenuView(boolean cleared) {
         super.updateMenuView(cleared);
 
-        if (mReserveOverflow && mMenu.getNonActionItems().size() > 0) {
+        final boolean hasOverflow = mReserveOverflow && mMenu.getNonActionItems().size() > 0;
+        if (hasOverflow) {
             if (mOverflowButton == null) {
                 mOverflowButton = new OverflowMenuButton(mContext);
             }
@@ -189,6 +189,8 @@
         } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) {
             ((ViewGroup) mMenuView).removeView(mOverflowButton);
         }
+
+        ((ActionMenuView) mMenuView).setOverflowReserved(mReserveOverflow);
     }
 
     @Override
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
index bff621c..267221b 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -115,17 +115,26 @@
         int maxChildHeight = 0;
         int maxCellsUsed = 0;
         int expandableItemCount = 0;
+        int visibleItemCount = 0;
+        boolean hasOverflow = false;
 
-        if (mReserveOverflow) cellsRemaining--;
+        // This is used as a bitfield to locate the smallest items present. Assumes childCount < 64.
+        long smallestItemsAt = 0;
 
         final int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             final View child = getChildAt(i);
+            if (child.getVisibility() == GONE) continue;
+
+            visibleItemCount++;
+
             final LayoutParams lp = (LayoutParams) child.getLayoutParams();
             lp.expanded = false;
             lp.extraPixels = 0;
             lp.cellsUsed = 0;
             lp.expandable = false;
+            lp.leftMargin = 0;
+            lp.rightMargin = 0;
 
             // Overflow always gets 1 cell. No more, no less.
             final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining;
@@ -135,16 +144,17 @@
 
             maxCellsUsed = Math.max(maxCellsUsed, cellsUsed);
             if (lp.expandable) expandableItemCount++;
+            if (lp.isOverflowButton) hasOverflow = true;
 
             cellsRemaining -= cellsUsed;
             maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
+            if (cellsUsed == 1) smallestItemsAt |= (1 << i);
         }
 
         // Divide space for remaining cells if we have items that can expand.
         // Try distributing whole leftover cells to smaller items first.
 
         boolean needsExpansion = false;
-        long smallestExpandableItemsAt = 0;
         while (expandableItemCount > 0 && cellsRemaining > 0) {
             int minCells = Integer.MAX_VALUE;
             long minCellsAt = 0; // Bit locations are indices of relevant child views
@@ -170,7 +180,7 @@
             if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop.
 
             // Items that get expanded will always be in the set of smallest items when we're done.
-            smallestExpandableItemsAt |= minCellsAt;
+            smallestItemsAt |= minCellsAt;
 
             for (int i = 0; i < childCount; i++) {
                 if ((minCellsAt & (1 << i)) == 0) continue;
@@ -186,22 +196,58 @@
         }
 
         // Divide any space left that wouldn't divide along cell boundaries
-        // evenly among the smallest multi-cell (expandable) items.
+        // evenly among the smallest items
 
-        if (cellsRemaining > 0 && smallestExpandableItemsAt != 0) {
-            final int expandCount = Long.bitCount(smallestExpandableItemsAt);
-            final int extraPixels = cellsRemaining * cellSize / expandCount;
+        final boolean singleItem = !hasOverflow && visibleItemCount == 1;
+        if (cellsRemaining > 0 && smallestItemsAt != 0 &&
+                (cellsRemaining < visibleItemCount - 1 || singleItem)) {
+            float expandCount = Long.bitCount(smallestItemsAt);
+
+            if (!singleItem) {
+                // The items at the far edges may only expand by half in order to pin to either side.
+                if ((smallestItemsAt & 1) != 0) {
+                    expandCount -= 0.5f;
+                }
+                if ((smallestItemsAt & (1 << (childCount - 1))) != 0) {
+                    expandCount -= 0.5f;
+                }
+            }
+
+            final int extraPixels = (int) (cellsRemaining * cellSize / expandCount);
 
             for (int i = 0; i < childCount; i++) {
-                if ((smallestExpandableItemsAt & (1 << i)) == 0) continue;
+                if ((smallestItemsAt & (1 << i)) == 0) continue;
 
                 final View child = getChildAt(i);
                 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-                lp.extraPixels = extraPixels;
-                lp.expanded = true;
+                if (child instanceof ActionMenuItemView) {
+                    // If this is one of our views, expand and measure at the larger size.
+                    lp.extraPixels = extraPixels;
+                    lp.expanded = true;
+                    if (i == 0) {
+                        // First item gets part of its new padding pushed out of sight.
+                        // The last item will get this implicitly from layout.
+                        lp.leftMargin = -extraPixels / 2;
+                    }
+                    needsExpansion = true;
+                } else if (lp.isOverflowButton) {
+                    lp.extraPixels = extraPixels;
+                    lp.expanded = true;
+                    lp.rightMargin = -extraPixels / 2;
+                    needsExpansion = true;
+                } else {
+                    // If we don't know what it is, give it some margins instead
+                    // and let it center within its space. We still want to pin
+                    // against the edges.
+                    if (i != 0) {
+                        lp.leftMargin = extraPixels / 2;
+                    }
+                    if (i != childCount - 1) {
+                        lp.rightMargin = extraPixels / 2;
+                    }
+                }
             }
 
-            needsExpansion = true;
             cellsRemaining = 0;
         }
 
@@ -301,7 +347,7 @@
                 }
 
                 int height = v.getMeasuredHeight();
-                int r = getWidth() - getPaddingRight();
+                int r = getWidth() - getPaddingRight() - p.rightMargin;
                 int l = r - overflowWidth;
                 int t = midVertical - (height / 2);
                 int b = t + height;
@@ -320,8 +366,20 @@
             }
         }
 
+        if (childCount == 1 && !hasOverflow) {
+            // Center a single child
+            final View v = getChildAt(0);
+            final int width = v.getMeasuredWidth();
+            final int height = v.getMeasuredHeight();
+            final int midHorizontal = (right - left) / 2;
+            final int l = midHorizontal - width / 2;
+            final int t = midVertical - height / 2;
+            v.layout(l, t, l + width, t + height);
+            return;
+        }
+
         final int spacerCount = nonOverflowCount - (hasOverflow ? 0 : 1);
-        final int spacerSize = spacerCount > 0 ? widthRemaining / spacerCount : 0;
+        final int spacerSize = Math.max(0, spacerCount > 0 ? widthRemaining / spacerCount : 0);
 
         int startLeft = getPaddingLeft();
         for (int i = 0; i < childCount; i++) {
@@ -334,7 +392,7 @@
             startLeft += lp.leftMargin;
             int width = v.getMeasuredWidth();
             int height = v.getMeasuredHeight();
-            int t = midVertical - (height / 2);
+            int t = midVertical - height / 2;
             v.layout(startLeft, t, startLeft + width, t + height);
             startLeft += width + lp.rightMargin + spacerSize;
         }
diff --git a/core/res/res/layout-large/action_mode_close_item.xml b/core/res/res/layout-large/action_mode_close_item.xml
index a7b3fbb..96aa451 100644
--- a/core/res/res/layout-large/action_mode_close_item.xml
+++ b/core/res/res/layout-large/action_mode_close_item.xml
@@ -18,7 +18,7 @@
         android:id="@+id/action_mode_close_button"
         android:focusable="true"
         android:clickable="true"
-        android:paddingLeft="16dip"
+        android:paddingLeft="8dip"
         style="?android:attr/actionModeCloseButtonStyle"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
@@ -31,8 +31,10 @@
     <TextView android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="center"
-              android:layout_marginLeft="8dip"
+              android:layout_marginLeft="4dip"
               android:layout_marginRight="16dip"
-              android:textAppearance="?android:attr/textAppearanceMedium"
+              android:textAppearance="?android:attr/textAppearanceSmall"
+              android:textSize="12sp"
+              android:textAllCaps="true"
               android:text="@string/action_mode_done" />
 </LinearLayout>
diff --git a/core/res/res/layout/action_mode_close_item.xml b/core/res/res/layout/action_mode_close_item.xml
index 57c0f1d..ac5af70 100644
--- a/core/res/res/layout/action_mode_close_item.xml
+++ b/core/res/res/layout/action_mode_close_item.xml
@@ -18,7 +18,7 @@
         android:id="@+id/action_mode_close_button"
         android:focusable="true"
         android:clickable="true"
-        android:paddingLeft="16dip"
+        android:paddingLeft="8dip"
         style="?android:attr/actionModeCloseButtonStyle"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 8ff9d46..d20d16c 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1516,7 +1516,7 @@
         <item name="android:paddingBottom">0dip</item>
         <item name="divider">?android:attr/dividerVertical</item>
         <item name="showDividers">middle</item>
-        <item name="dividerPadding">8dip</item>
+        <item name="dividerPadding">12dip</item>
         <item name="background">@null</item>
     </style>