Propagate DrawableContainer state on mutate, fix ColorDrawable theming

BUG: 18542282
BUG: 18467568
Change-Id: Id1d75cfe47fde3206ab40e5360289e0cb2504402
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 0f0c844..e3b50ea 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -252,6 +252,11 @@
     }
 
     @Override
+    public boolean canApplyTheme() {
+        return mColorState.canApplyTheme() || super.canApplyTheme();
+    }
+
+    @Override
     public void applyTheme(Theme t) {
         super.applyTheme(t);
 
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 3fe408a..39ef10c 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -447,36 +447,10 @@
             mCurrDrawable = d;
             mCurIndex = idx;
             if (d != null) {
-                d.mutate();
                 if (mDrawableContainerState.mEnterFadeDuration > 0) {
                     mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration;
-                } else if (mHasAlpha) {
-                    d.setAlpha(mAlpha);
                 }
-                if (mDrawableContainerState.mHasColorFilter) {
-                    // Color filter always overrides tint.
-                    d.setColorFilter(mDrawableContainerState.mColorFilter);
-                } else {
-                    if (mDrawableContainerState.mHasTintList) {
-                        d.setTintList(mDrawableContainerState.mTintList);
-                    }
-                    if (mDrawableContainerState.mHasTintMode) {
-                        d.setTintMode(mDrawableContainerState.mTintMode);
-                    }
-                }
-                d.setVisible(isVisible(), true);
-                d.setDither(mDrawableContainerState.mDither);
-                d.setState(getState());
-                d.setLevel(getLevel());
-                d.setBounds(getBounds());
-                d.setLayoutDirection(getLayoutDirection());
-                d.setAutoMirrored(mDrawableContainerState.mAutoMirrored);
-
-                final Rect hotspotBounds = mHotspotBounds;
-                if (hotspotBounds != null) {
-                    d.setHotspotBounds(hotspotBounds.left, hotspotBounds.top,
-                            hotspotBounds.right, hotspotBounds.bottom);
-                }
+                initializeDrawableForDisplay(d);
             }
         } else {
             mCurrDrawable = null;
@@ -503,6 +477,45 @@
         return true;
     }
 
+    /**
+     * Initializes a drawable for display in this container.
+     *
+     * @param d The drawable to initialize.
+     */
+    private void initializeDrawableForDisplay(Drawable d) {
+        d.mutate();
+
+        if (mDrawableContainerState.mEnterFadeDuration <= 0 && mHasAlpha) {
+            d.setAlpha(mAlpha);
+        }
+
+        if (mDrawableContainerState.mHasColorFilter) {
+            // Color filter always overrides tint.
+            d.setColorFilter(mDrawableContainerState.mColorFilter);
+        } else {
+            if (mDrawableContainerState.mHasTintList) {
+                d.setTintList(mDrawableContainerState.mTintList);
+            }
+            if (mDrawableContainerState.mHasTintMode) {
+                d.setTintMode(mDrawableContainerState.mTintMode);
+            }
+        }
+
+        d.setVisible(isVisible(), true);
+        d.setDither(mDrawableContainerState.mDither);
+        d.setState(getState());
+        d.setLevel(getLevel());
+        d.setBounds(getBounds());
+        d.setLayoutDirection(getLayoutDirection());
+        d.setAutoMirrored(mDrawableContainerState.mAutoMirrored);
+
+        final Rect hotspotBounds = mHotspotBounds;
+        if (hotspotBounds != null) {
+            d.setHotspotBounds(hotspotBounds.left, hotspotBounds.top,
+                    hotspotBounds.right, hotspotBounds.bottom);
+        }
+    }
+
     void animate(boolean schedule) {
         mHasAlpha = true;
 
@@ -1136,9 +1149,14 @@
         // The locally cached drawables may have changed.
         if (mCurIndex >= 0) {
             mCurrDrawable = state.getChild(mCurIndex);
+            if (mCurrDrawable != null) {
+                initializeDrawableForDisplay(mCurrDrawable);
+            }
         }
-        if (mLastIndex >= 0) {
-            mLastDrawable = state.getChild(mLastIndex);
-        }
+
+        // Clear out the last drawable. We don't have enough information to
+        // propagate local state from the past.
+        mLastIndex = -1;
+        mLastDrawable = null;
     }
 }