Merge "Fix MenuInflater creation with no Action Bar" into klp-ub-dev
diff --git a/v4/java/android/support/v4/widget/SwipeProgressBar.java b/v4/java/android/support/v4/widget/SwipeProgressBar.java
index 5b50cd6..b3b04cd 100644
--- a/v4/java/android/support/v4/widget/SwipeProgressBar.java
+++ b/v4/java/android/support/v4/widget/SwipeProgressBar.java
@@ -138,6 +138,7 @@
         final int height = mBounds.height();
         final int cx = width / 2;
         final int cy = height / 2;
+        boolean drawTriggerWhileFinishing = false;
         int restoreCount = canvas.save();
         canvas.clipRect(mBounds);
 
@@ -167,6 +168,11 @@
                 float clearRadius = width / 2 * INTERPOLATOR.getInterpolation(pct);
                 mClipRect.set(cx - clearRadius, 0, cx + clearRadius, height);
                 canvas.saveLayerAlpha(mClipRect, 0, 0);
+                // Only draw the trigger if there is a space in the center of
+                // this refreshing view that needs to be filled in by the
+                // trigger. If the progress view is just still animating, let it
+                // continue animating.
+                drawTriggerWhileFinishing = true;
             }
 
             // First fill in with the last color that would have finished drawing.
@@ -210,7 +216,7 @@
                 float pct = (((rawProgress - 75) * 2) / 100f);
                 drawCircle(canvas, cx, cy, mColor1, pct);
             }
-            if (mTriggerPercentage > 0) {
+            if (mTriggerPercentage > 0 && drawTriggerWhileFinishing) {
                 // There is some portion of trigger to draw. Restore the canvas,
                 // then draw the trigger. Otherwise, the trigger does not appear
                 // until after the bar has finished animating and appears to
diff --git a/v4/java/android/support/v4/widget/SwipeRefreshLayout.java b/v4/java/android/support/v4/widget/SwipeRefreshLayout.java
index f34ee93..ca68acd 100644
--- a/v4/java/android/support/v4/widget/SwipeRefreshLayout.java
+++ b/v4/java/android/support/v4/widget/SwipeRefreshLayout.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
@@ -82,6 +83,9 @@
     private boolean mReturningToStart;
     private final DecelerateInterpolator mDecelerateInterpolator;
     private final AccelerateInterpolator mAccelerateInterpolator;
+    private static final int[] LAYOUT_ATTRS = new int[] {
+        android.R.attr.enabled
+    };
 
     private final Animation mAnimateToStartPosition = new Animation() {
         @Override
@@ -167,10 +171,10 @@
     /**
      * Constructor that is called when inflating SwipeRefreshLayout from XML.
      * @param context
-     * @param attr
+     * @param attrs
      */
-    public SwipeRefreshLayout(Context context, AttributeSet attr) {
-        super(context, attr);
+    public SwipeRefreshLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
 
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
 
@@ -183,6 +187,10 @@
         mProgressBarHeight = (int) (metrics.density * PROGRESS_BAR_HEIGHT);
         mDecelerateInterpolator = new DecelerateInterpolator(DECELERATE_INTERPOLATION_FACTOR);
         mAccelerateInterpolator = new AccelerateInterpolator(ACCELERATE_INTERPOLATION_FACTOR);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs, LAYOUT_ATTRS);
+        setEnabled(a.getBoolean(0, true));
+        a.recycle();
     }
 
     @Override
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBar.java b/v7/appcompat/src/android/support/v7/app/ActionBar.java
index 6521ff5..a8a6383 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBar.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBar.java
@@ -662,6 +662,86 @@
     }
 
     /**
+     * Set an alternate drawable to display next to the icon/logo/title
+     * when {@link #DISPLAY_HOME_AS_UP} is enabled. This can be useful if you are using
+     * this mode to display an alternate selection for up navigation, such as a sliding drawer.
+     *
+     * <p>If you pass <code>null</code> to this method, the default drawable from the theme
+     * will be used.</p>
+     *
+     * <p>If you implement alternate or intermediate behavior around Up, you should also
+     * call {@link #setHomeActionContentDescription(int) setHomeActionContentDescription()}
+     * to provide a correct description of the action for accessibility support.</p>
+     *
+     * @param indicator A drawable to use for the up indicator, or null to use the theme's default
+     *
+     * @see #setDisplayOptions(int, int)
+     * @see #setDisplayHomeAsUpEnabled(boolean)
+     * @see #setHomeActionContentDescription(int)
+     */
+    public void setHomeAsUpIndicator(Drawable indicator) {}
+
+    /**
+     * Set an alternate drawable to display next to the icon/logo/title
+     * when {@link #DISPLAY_HOME_AS_UP} is enabled. This can be useful if you are using
+     * this mode to display an alternate selection for up navigation, such as a sliding drawer.
+     *
+     * <p>If you pass <code>0</code> to this method, the default drawable from the theme
+     * will be used.</p>
+     *
+     * <p>If you implement alternate or intermediate behavior around Up, you should also
+     * call {@link #setHomeActionContentDescription(int) setHomeActionContentDescription()}
+     * to provide a correct description of the action for accessibility support.</p>
+     *
+     * @param resId Resource ID of a drawable to use for the up indicator, or null
+     *              to use the theme's default
+     *
+     * @see #setDisplayOptions(int, int)
+     * @see #setDisplayHomeAsUpEnabled(boolean)
+     * @see #setHomeActionContentDescription(int)
+     */
+    public void setHomeAsUpIndicator(int resId) {}
+
+    /**
+     * Set an alternate description for the Home/Up action, when enabled.
+     *
+     * <p>This description is commonly used for accessibility/screen readers when
+     * the Home action is enabled. (See {@link #setDisplayHomeAsUpEnabled(boolean)}.)
+     * Examples of this are, "Navigate Home" or "Navigate Up" depending on the
+     * {@link #DISPLAY_HOME_AS_UP} display option. If you have changed the home-as-up
+     * indicator using {@link #setHomeAsUpIndicator(int)} to indicate more specific
+     * functionality such as a sliding drawer, you should also set this to accurately
+     * describe the action.</p>
+     *
+     * <p>Setting this to <code>null</code> will use the system default description.</p>
+     *
+     * @param description New description for the Home action when enabled
+     * @see #setHomeAsUpIndicator(int)
+     * @see #setHomeAsUpIndicator(android.graphics.drawable.Drawable)
+     */
+    public void setHomeActionContentDescription(CharSequence description) {}
+
+    /**
+     * Set an alternate description for the Home/Up action, when enabled.
+     *
+     * <p>This description is commonly used for accessibility/screen readers when
+     * the Home action is enabled. (See {@link #setDisplayHomeAsUpEnabled(boolean)}.)
+     * Examples of this are, "Navigate Home" or "Navigate Up" depending on the
+     * {@link #DISPLAY_HOME_AS_UP} display option. If you have changed the home-as-up
+     * indicator using {@link #setHomeAsUpIndicator(int)} to indicate more specific
+     * functionality such as a sliding drawer, you should also set this to accurately
+     * describe the action.</p>
+     *
+     * <p>Setting this to <code>0</code> will use the system default description.</p>
+     *
+     * @param resId Resource ID of a string to use as the new description
+     *              for the Home action when enabled
+     * @see #setHomeAsUpIndicator(int)
+     * @see #setHomeAsUpIndicator(android.graphics.drawable.Drawable)
+     */
+    public void setHomeActionContentDescription(int resId) {}
+
+    /**
      * Listener for receiving {@link ActionBar} navigation events.
      *
      * <p class="note"><strong>Note:</strong> This interface is included in the <a
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegate.java b/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegate.java
index bd19329..798e359 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegate.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegate.java
@@ -21,6 +21,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Bundle;
 import android.support.v4.app.ActionBarDrawerToggle;
@@ -43,12 +44,13 @@
     private static final String TAG = "ActionBarActivityDelegate";
 
     static ActionBarActivityDelegate createDelegate(ActionBarActivity activity) {
-        final int version = Build.VERSION.SDK_INT;
-        if (version >= Build.VERSION_CODES.JELLY_BEAN) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+            return new ActionBarActivityDelegateJBMR2(activity);
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
             return new ActionBarActivityDelegateJB(activity);
-        } else if (version >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
             return new ActionBarActivityDelegateICS(activity);
-        } else if (version >= Build.VERSION_CODES.HONEYCOMB) {
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
             return new ActionBarActivityDelegateHC(activity);
         } else {
             return new ActionBarActivityDelegateBase(activity);
@@ -171,7 +173,11 @@
 
     abstract void setSupportProgress(int progress);
 
-    abstract ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
+    final ActionBarDrawerToggle.Delegate getDrawerToggleDelegate() {
+        return new ActionBarDrawableToggleImpl();
+    }
+
+    abstract int getHomeAsUpIndicatorAttrId();
 
     abstract void onContentChanged();
 
@@ -203,4 +209,32 @@
         }
         return context;
     }
+
+    private class ActionBarDrawableToggleImpl implements ActionBarDrawerToggle.Delegate {
+        @Override
+        public Drawable getThemeUpIndicator() {
+            final TypedArray a = mActivity
+                    .obtainStyledAttributes(new int[]{ getHomeAsUpIndicatorAttrId() });
+            final Drawable result = a.getDrawable(0);
+            a.recycle();
+            return result;
+        }
+
+        @Override
+        public void setActionBarUpIndicator(Drawable upDrawable, int contentDescRes) {
+            ActionBar ab = getSupportActionBar();
+            if (ab != null) {
+                ab.setHomeAsUpIndicator(upDrawable);
+                ab.setHomeActionContentDescription(contentDescRes);
+            }
+        }
+
+        @Override
+        public void setActionBarDescription(int contentDescRes) {
+            ActionBar ab = getSupportActionBar();
+            if (ab != null) {
+                ab.setHomeActionContentDescription(contentDescRes);
+            }
+        }
+    }
 }
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateBase.java b/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateBase.java
index 8670f94..ab5335a 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateBase.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateBase.java
@@ -502,8 +502,8 @@
     }
 
     @Override
-    ActionBarDrawerToggle.Delegate getDrawerToggleDelegate() {
-        return new ActionBarDrawableToggleImpl();
+    int getHomeAsUpIndicatorAttrId() {
+        return R.attr.homeAsUpIndicator;
     }
 
     /**
@@ -688,28 +688,4 @@
         }
     }
 
-    private class ActionBarDrawableToggleImpl
-            implements ActionBarDrawerToggle.Delegate {
-
-        @Override
-        public Drawable getThemeUpIndicator() {
-            final TypedArray a = mActivity.obtainStyledAttributes(ACTION_BAR_DRAWABLE_TOGGLE_ATTRS);
-            final Drawable result = a.getDrawable(0);
-            a.recycle();
-            return result;
-        }
-
-        @Override
-        public void setActionBarUpIndicator(Drawable upDrawable, int contentDescRes) {
-            if (mActionBarView != null) {
-                mActionBarView.setHomeAsUpIndicator(upDrawable);
-            }
-        }
-
-        @Override
-        public void setActionBarDescription(int contentDescRes) {
-            // No support for setting Action Bar content description
-        }
-    }
-
 }
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateICS.java b/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateICS.java
index ef505e3..22d23f9 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateICS.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateICS.java
@@ -20,7 +20,6 @@
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.os.Bundle;
-import android.support.v4.app.ActionBarDrawerToggle;
 import android.support.v4.view.WindowCompat;
 import android.support.v7.internal.view.ActionModeWrapper;
 import android.support.v7.internal.view.menu.MenuWrapperFactory;
@@ -178,14 +177,14 @@
 
         Context context = getActionBarThemedContext();
 
-        ActionModeWrapper.CallbackWrapper wrappedCallback = new ActionModeWrapper.CallbackWrapper(
+        ActionModeWrapper.CallbackWrapper wrappedCallback = createActionModeCallbackWrapper(
                 context, callback);
         ActionModeWrapper wrappedMode = null;
 
         android.view.ActionMode frameworkMode = mActivity.startActionMode(wrappedCallback);
 
         if (frameworkMode != null) {
-            wrappedMode = new ActionModeWrapper(context, frameworkMode);
+            wrappedMode = createActionModeWrapper(context, frameworkMode);
             wrappedCallback.setLastStartedActionMode(wrappedMode);
         }
 
@@ -194,7 +193,7 @@
 
     public void onActionModeStarted(android.view.ActionMode mode) {
         mActivity.onSupportActionModeStarted(
-                new ActionModeWrapper(getActionBarThemedContext(), mode));
+                createActionModeWrapper(getActionBarThemedContext(), mode));
     }
 
     @Override
@@ -219,7 +218,7 @@
 
     public void onActionModeFinished(android.view.ActionMode mode) {
         mActivity.onSupportActionModeFinished(
-                new ActionModeWrapper(getActionBarThemedContext(), mode));
+                createActionModeWrapper(getActionBarThemedContext(), mode));
     }
 
     @Override
@@ -233,9 +232,18 @@
     }
 
     @Override
-    public ActionBarDrawerToggle.Delegate getDrawerToggleDelegate() {
-        // Return null so that ActionBarDrawableToggle uses it's standard impl
-        return null;
+    int getHomeAsUpIndicatorAttrId() {
+        return android.R.attr.homeAsUpIndicator;
+    }
+
+    ActionModeWrapper.CallbackWrapper createActionModeCallbackWrapper(Context context,
+            ActionMode.Callback callback) {
+        return new ActionModeWrapper.CallbackWrapper(context, callback);
+    }
+
+    ActionModeWrapper createActionModeWrapper(Context context,
+            android.view.ActionMode frameworkMode) {
+        return new ActionModeWrapper(context, frameworkMode);
     }
 
     class WindowCallbackWrapper implements Window.Callback {
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateJB.java b/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateJB.java
index 7454cff..a0c955f 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateJB.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateJB.java
@@ -16,6 +16,11 @@
 
 package android.support.v7.app;
 
+import android.content.Context;
+import android.support.v7.internal.view.ActionModeWrapper;
+import android.support.v7.internal.view.ActionModeWrapperJB;
+import android.support.v7.view.ActionMode;
+
 class ActionBarActivityDelegateJB extends ActionBarActivityDelegateICS {
 
     ActionBarActivityDelegateJB(ActionBarActivity activity) {
@@ -26,4 +31,15 @@
     public ActionBar createSupportActionBar() {
         return new ActionBarImplJB(mActivity, mActivity);
     }
+
+    @Override
+    ActionModeWrapper.CallbackWrapper createActionModeCallbackWrapper(Context context,
+            ActionMode.Callback callback) {
+        return new ActionModeWrapperJB.CallbackWrapper(context, callback);
+    }
+
+    @Override
+    ActionModeWrapper createActionModeWrapper(Context context, android.view.ActionMode frameworkMode) {
+        return new ActionModeWrapperJB(context, frameworkMode);
+    }
 }
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateJBMR2.java b/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateJBMR2.java
new file mode 100644
index 0000000..996c8f1
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateJBMR2.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v7.app;
+
+class ActionBarActivityDelegateJBMR2 extends ActionBarActivityDelegateJB {
+
+    ActionBarActivityDelegateJBMR2(ActionBarActivity activity) {
+        super(activity);
+    }
+
+    @Override
+    public ActionBar createSupportActionBar() {
+        return new ActionBarImplJBMR2(mActivity, mActivity);
+    }
+}
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarImplBase.java b/v7/appcompat/src/android/support/v7/app/ActionBarImplBase.java
index 96761fe..ece56c5 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBarImplBase.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBarImplBase.java
@@ -333,6 +333,16 @@
     }
 
     @Override
+    public void setStackedBackgroundDrawable(Drawable d) {
+        mContainerView.setStackedBackground(d);
+    }
+
+    @Override
+    public void setSplitBackgroundDrawable(Drawable d) {
+        mContainerView.setSplitBackground(d);
+    }
+
+    @Override
     public View getCustomView() {
         return mActionView.getCustomNavigationView();
     }
@@ -515,6 +525,16 @@
     }
 
     @Override
+    public void setHomeAsUpIndicator(Drawable indicator) {
+        mActionView.setHomeAsUpIndicator(indicator);
+    }
+
+    @Override
+    public void setHomeAsUpIndicator(int resId) {
+        mActionView.setHomeAsUpIndicator(resId);
+    }
+
+    @Override
     public int getHeight() {
         return mContainerView.getHeight();
     }
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarImplICS.java b/v7/appcompat/src/android/support/v7/app/ActionBarImplICS.java
index 044aec6..9f47c21 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBarImplICS.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBarImplICS.java
@@ -18,9 +18,12 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.support.v4.app.FragmentTransaction;
 import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
 import android.widget.SpinnerAdapter;
 
 import java.lang.ref.WeakReference;
@@ -32,6 +35,8 @@
     final Callback mCallback;
     final android.app.ActionBar mActionBar;
 
+    private ImageView mHomeActionView;
+
     FragmentTransaction mActiveTransaction;
 
     private ArrayList<WeakReference<OnMenuVisibilityListenerWrapper>> mAddedMenuVisWrappers =
@@ -190,6 +195,16 @@
     }
 
     @Override
+    public void setStackedBackgroundDrawable(Drawable d) {
+        mActionBar.setStackedBackgroundDrawable(d);
+    }
+
+    @Override
+    public void setSplitBackgroundDrawable(Drawable d) {
+        mActionBar.setSplitBackgroundDrawable(d);
+    }
+
+    @Override
     public View getCustomView() {
         return mActionBar.getCustomView();
     }
@@ -288,6 +303,29 @@
     }
 
     @Override
+    public void setHomeAsUpIndicator(Drawable indicator) {
+        ImageView homeActionView = getHomeActionView();
+        if (homeActionView != null) {
+            if (indicator == null) {
+                indicator = getThemeDefaultUpIndicator();
+            }
+            homeActionView.setImageDrawable(indicator);
+        }
+    }
+
+    @Override
+    public void setHomeAsUpIndicator(int resId) {
+        ImageView homeActionView = getHomeActionView();
+        if (homeActionView != null) {
+            if (resId != 0) {
+                homeActionView.setImageResource(resId);
+            } else {
+                homeActionView.setImageDrawable(getThemeDefaultUpIndicator());
+            }
+        }
+    }
+
+    @Override
     public int getHeight() {
         return mActionBar.getHeight();
     }
@@ -342,6 +380,41 @@
         mActiveTransaction = null;
     }
 
+    ImageView getHomeActionView() {
+        if (mHomeActionView == null) {
+            final View home = mActivity.findViewById(android.R.id.home);
+            if (home == null) {
+                // Action bar doesn't have a known configuration, an OEM messed with things.
+                return null;
+            }
+
+            final ViewGroup parent = (ViewGroup) home.getParent();
+            final int childCount = parent.getChildCount();
+            if (childCount != 2) {
+                // No idea which one will be the right one, an OEM messed with things.
+                return null;
+            }
+
+            final View first = parent.getChildAt(0);
+            final View second = parent.getChildAt(1);
+            final View up = first.getId() == android.R.id.home ? second : first;
+
+            if (up instanceof ImageView) {
+                // Jackpot! (Probably...)
+                mHomeActionView = (ImageView) up;
+            }
+        }
+        return mHomeActionView;
+    }
+
+    Drawable getThemeDefaultUpIndicator() {
+        final TypedArray a = mActivity.obtainStyledAttributes(
+                new int[] { android.R.attr.homeAsUpIndicator });
+        final Drawable result = a.getDrawable(0);
+        a.recycle();
+        return result;
+    }
+
     static class OnNavigationListenerWrapper implements android.app.ActionBar.OnNavigationListener {
 
         private final OnNavigationListener mWrappedListener;
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarImplJBMR2.java b/v7/appcompat/src/android/support/v7/app/ActionBarImplJBMR2.java
new file mode 100644
index 0000000..474aca5
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/app/ActionBarImplJBMR2.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.v7.app;
+
+import android.app.Activity;
+import android.graphics.drawable.Drawable;
+
+public class ActionBarImplJBMR2 extends ActionBarImplJB {
+
+    public ActionBarImplJBMR2(Activity activity, Callback callback) {
+        super(activity, callback);
+    }
+
+    @Override
+    public void setHomeAsUpIndicator(Drawable indicator) {
+        mActionBar.setHomeAsUpIndicator(indicator);
+    }
+
+    @Override
+    public void setHomeAsUpIndicator(int resId) {
+        mActionBar.setHomeAsUpIndicator(resId);
+    }
+
+    @Override
+    public void setHomeActionContentDescription(CharSequence description) {
+        mActionBar.setHomeActionContentDescription(description);
+    }
+
+    @Override
+    public void setHomeActionContentDescription(int resId) {
+        mActionBar.setHomeActionContentDescription(resId);
+    }
+}
diff --git a/v7/appcompat/src/android/support/v7/internal/view/ActionModeWrapper.java b/v7/appcompat/src/android/support/v7/internal/view/ActionModeWrapper.java
index f124da3..2048d2b 100644
--- a/v7/appcompat/src/android/support/v7/internal/view/ActionModeWrapper.java
+++ b/v7/appcompat/src/android/support/v7/internal/view/ActionModeWrapper.java
@@ -47,21 +47,6 @@
     }
 
     @Override
-    public boolean getTitleOptionalHint() {
-        return mWrappedObject.getTitleOptionalHint();
-    }
-
-    @Override
-    public void setTitleOptionalHint(boolean titleOptional) {
-        mWrappedObject.setTitleOptionalHint(titleOptional);
-    }
-
-    @Override
-    public boolean isTitleOptional() {
-        return mWrappedObject.isTitleOptional();
-    }
-
-    @Override
     public void setTitle(CharSequence title) {
         mWrappedObject.setTitle(title);
     }
@@ -168,8 +153,13 @@
                 // If the given mode equals our wrapped mode, just return it
                 return mLastStartedActionMode;
             } else {
-                return new ActionModeWrapper(mContext, mode);
+                return createActionModeWrapper(mContext, mode);
             }
         }
+
+        protected ActionModeWrapper createActionModeWrapper(Context context,
+                android.view.ActionMode mode) {
+            return new ActionModeWrapper(context, mode);
+        }
     }
 }
diff --git a/v7/appcompat/src/android/support/v7/internal/view/ActionModeWrapperJB.java b/v7/appcompat/src/android/support/v7/internal/view/ActionModeWrapperJB.java
new file mode 100644
index 0000000..15ede6e
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/internal/view/ActionModeWrapperJB.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v7.internal.view;
+
+import android.content.Context;
+import android.view.ActionMode;
+
+/**
+ * @hide
+ */
+public class ActionModeWrapperJB extends ActionModeWrapper {
+
+    public ActionModeWrapperJB(Context context, android.view.ActionMode frameworkActionMode) {
+        super(context, frameworkActionMode);
+    }
+
+    @Override
+    public boolean getTitleOptionalHint() {
+        return mWrappedObject.getTitleOptionalHint();
+    }
+
+    @Override
+    public void setTitleOptionalHint(boolean titleOptional) {
+        mWrappedObject.setTitleOptionalHint(titleOptional);
+    }
+
+    @Override
+    public boolean isTitleOptional() {
+        return mWrappedObject.isTitleOptional();
+    }
+
+    /**
+     * @hide
+     */
+    public static class CallbackWrapper extends ActionModeWrapper.CallbackWrapper {
+
+        public CallbackWrapper(Context context, Callback supportCallback) {
+            super(context, supportCallback);
+        }
+
+        @Override
+        protected ActionModeWrapper createActionModeWrapper(Context context, ActionMode mode) {
+            return new ActionModeWrapperJB(context, mode);
+        }
+    }
+
+}
diff --git a/v7/appcompat/src/android/support/v7/internal/widget/ActionBarContainer.java b/v7/appcompat/src/android/support/v7/internal/widget/ActionBarContainer.java
index c08615d..230eae9 100644
--- a/v7/appcompat/src/android/support/v7/internal/widget/ActionBarContainer.java
+++ b/v7/appcompat/src/android/support/v7/internal/widget/ActionBarContainer.java
@@ -19,7 +19,10 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.support.v7.app.ActionBar;
 import android.support.v7.appcompat.R;
 import android.support.v7.view.ActionMode;
@@ -87,7 +90,12 @@
         mBackground = bg;
         if (bg != null) {
             bg.setCallback(this);
+            if (mActionBarView != null) {
+                mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(),
+                        mActionBarView.getRight(), mActionBarView.getBottom());
+            }
         }
+
         setWillNotDraw(mIsSplit ? mSplitBackground == null :
                 mBackground == null && mStackedBackground == null);
         invalidate();
@@ -101,6 +109,10 @@
         mStackedBackground = bg;
         if (bg != null) {
             bg.setCallback(this);
+            if ((mIsStacked && mStackedBackground != null)) {
+                mStackedBackground.setBounds(mTabContainer.getLeft(), mTabContainer.getTop(),
+                        mTabContainer.getRight(), mTabContainer.getBottom());
+            }
         }
         setWillNotDraw(mIsSplit ? mSplitBackground == null :
                 mBackground == null && mStackedBackground == null);
@@ -115,6 +127,9 @@
         mSplitBackground = bg;
         if (bg != null) {
             bg.setCallback(this);
+            if (mIsSplit && mSplitBackground != null) {
+                mSplitBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
+            }
         }
         setWillNotDraw(mIsSplit ? mSplitBackground == null :
                 mBackground == null && mStackedBackground == null);
@@ -210,14 +225,14 @@
 
         if (mIsSplit) {
             if (mSplitBackground != null) {
-                mSplitBackground.draw(canvas);
+                drawBackgroundDrawable(mSplitBackground, canvas);
             }
         } else {
             if (mBackground != null) {
-                mBackground.draw(canvas);
+                drawBackgroundDrawable(mBackground, canvas);
             }
             if (mStackedBackground != null && mIsStacked) {
-                mStackedBackground.draw(canvas);
+                drawBackgroundDrawable(mStackedBackground, canvas);
             }
         }
     }
@@ -304,4 +319,17 @@
             invalidate();
         }
     }
+
+    private void drawBackgroundDrawable(Drawable d, Canvas canvas) {
+        final Rect bounds = d.getBounds();
+        if (d instanceof ColorDrawable && !bounds.isEmpty() && Build.VERSION.SDK_INT < 11) {
+            // Pre-Honeycomb ColorDrawable does not respect it's bounds so we need to force it to
+            canvas.save();
+            canvas.clipRect(bounds);
+            d.draw(canvas);
+            canvas.restore();
+        } else {
+            d.draw(canvas);
+        }
+    }
 }
diff --git a/v7/appcompat/src/android/support/v7/internal/widget/ActionBarView.java b/v7/appcompat/src/android/support/v7/internal/widget/ActionBarView.java
index 4c0137c..111372a 100644
--- a/v7/appcompat/src/android/support/v7/internal/widget/ActionBarView.java
+++ b/v7/appcompat/src/android/support/v7/internal/widget/ActionBarView.java
@@ -1273,7 +1273,8 @@
 
         public void setUpIndicator(int resId) {
             mUpIndicatorRes = resId;
-            mUpView.setImageDrawable(resId != 0 ? getResources().getDrawable(resId) : null);
+            mUpView.setImageDrawable(resId != 0 ? getResources().getDrawable(resId)
+                    : mDefaultUpIndicator);
         }
 
         @Override