Merge "Revert "Ensure calling mutate() on DrawableContainer creates a new state"" into lmp-mr1-dev
diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
index c58563f..f58a765 100644
--- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
@@ -527,18 +527,14 @@
     @Override
     public Drawable mutate() {
         if (!mMutated && super.mutate() == this) {
-            mState.mutate();
+            final AnimatedStateListState newState = new AnimatedStateListState(mState, this, null);
+            setConstantState(newState);
             mMutated = true;
         }
 
         return this;
     }
 
-    @Override
-    AnimatedStateListState cloneConstantState() {
-        return new AnimatedStateListState(mState, this, null);
-    }
-
     /**
      * @hide
      */
@@ -557,29 +553,23 @@
 
         int[] mAnimThemeAttrs;
 
-        LongSparseLongArray mTransitions;
-        SparseIntArray mStateIds;
+        final LongSparseLongArray mTransitions;
+        final SparseIntArray mStateIds;
 
         AnimatedStateListState(@Nullable AnimatedStateListState orig,
                 @NonNull AnimatedStateListDrawable owner, @Nullable Resources res) {
             super(orig, owner, res);
 
             if (orig != null) {
-                // Perform a shallow copy and rely on mutate() to deep-copy.
                 mAnimThemeAttrs = orig.mAnimThemeAttrs;
-                mTransitions = orig.mTransitions;
-                mStateIds = orig.mStateIds;
+                mTransitions = orig.mTransitions.clone();
+                mStateIds = orig.mStateIds.clone();
             } else {
                 mTransitions = new LongSparseLongArray();
                 mStateIds = new SparseIntArray();
             }
         }
 
-        private void mutate() {
-            mTransitions = mTransitions.clone();
-            mStateIds = mStateIds.clone();
-        }
-
         int addTransition(int fromId, int toId, @NonNull Drawable anim, boolean reversible) {
             final int pos = super.addChild(anim);
             final long keyFromTo = generateTransitionKey(fromId, toId);
@@ -651,7 +641,7 @@
         }
     }
 
-    protected void setConstantState(@NonNull AnimatedStateListState state) {
+    void setConstantState(@NonNull AnimatedStateListState state) {
         super.setConstantState(state);
 
         mState = state;
@@ -660,7 +650,6 @@
     private AnimatedStateListDrawable(@Nullable AnimatedStateListState state, @Nullable Resources res) {
         super(null);
 
-        // Every animated state list drawable has its own constant state.
         final AnimatedStateListState newState = new AnimatedStateListState(state, this, res);
         setConstantState(newState);
         onStateChange(getState());
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 28ada82..2ddf9df 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -342,17 +342,12 @@
     @Override
     public Drawable mutate() {
         if (!mMutated && super.mutate() == this) {
-            mAnimationState.mutate();
+            mAnimationState.mDurations = mAnimationState.mDurations.clone();
             mMutated = true;
         }
         return this;
     }
 
-    @Override
-    AnimationState cloneConstantState() {
-        return new AnimationState(mAnimationState, this, null);
-    }
-
     /**
      * @hide
      */
@@ -378,10 +373,6 @@
             }
         }
 
-        private void mutate() {
-            mDurations = mDurations.clone();
-        }
-
         @Override
         public Drawable newDrawable() {
             return new AnimationDrawable(this, null);
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 6d43a0c..326490f 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -536,7 +536,7 @@
         }
 
         if (schedule && animating) {
-            scheduleSelf(mAnimationRunnable, now + 1000 / 60);
+            scheduleSelf(mAnimationRunnable, now + 1000/60);
         }
     }
 
@@ -567,7 +567,6 @@
     @Override
     public Drawable mutate() {
         if (!mMutated && super.mutate() == this) {
-            mDrawableContainerState = cloneConstantState();
             mDrawableContainerState.mutate();
             mMutated = true;
         }
@@ -575,16 +574,6 @@
     }
 
     /**
-     * Returns a shallow copy of the container's constant state to be used as
-     * the base state for {@link #mutate()}.
-     *
-     * @return a shallow copy of the constant state
-     */
-    DrawableContainerState cloneConstantState() {
-        return mDrawableContainerState;
-    }
-
-    /**
      * @hide
      */
     public void clearMutated() {
@@ -844,7 +833,7 @@
             return false;
         }
 
-        private void mutate() {
+        final void mutate() {
             // No need to call createAllFutures, since future drawables will
             // mutate when they are prepared.
             final int N = mNumChildren;
diff --git a/graphics/java/android/graphics/drawable/LevelListDrawable.java b/graphics/java/android/graphics/drawable/LevelListDrawable.java
index dc41216..9e918f6 100644
--- a/graphics/java/android/graphics/drawable/LevelListDrawable.java
+++ b/graphics/java/android/graphics/drawable/LevelListDrawable.java
@@ -146,17 +146,13 @@
     @Override
     public Drawable mutate() {
         if (!mMutated && super.mutate() == this) {
-            mLevelListState.mutate();
+            mLevelListState.mLows = mLevelListState.mLows.clone();
+            mLevelListState.mHighs = mLevelListState.mHighs.clone();
             mMutated = true;
         }
         return this;
     }
 
-    @Override
-    LevelListState cloneConstantState() {
-        return new LevelListState(mLevelListState, this, null);
-    }
-
     /**
      * @hide
      */
@@ -173,7 +169,6 @@
             super(orig, owner, res);
 
             if (orig != null) {
-                // Perform a shallow copy and rely on mutate() to deep-copy.
                 mLows = orig.mLows;
                 mHighs = orig.mHighs;
             } else {
@@ -182,11 +177,6 @@
             }
         }
 
-        private void mutate() {
-            mLows = mLows.clone();
-            mHighs = mHighs.clone();
-        }
-
         public void addLevel(int low, int high, Drawable drawable) {
             int pos = addChild(drawable);
             mLows[pos] = low;
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index eb6f94f..e7a8233 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -24,8 +24,6 @@
 import java.io.IOException;
 import java.util.Arrays;
 
-import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.Resources.Theme;
@@ -290,17 +288,20 @@
     @Override
     public Drawable mutate() {
         if (!mMutated && super.mutate() == this) {
-            mStateListState.mutate();
+            final int[][] sets = mStateListState.mStateSets;
+            final int count = sets.length;
+            mStateListState.mStateSets = new int[count][];
+            for (int i = 0; i < count; i++) {
+                final int[] set = sets[i];
+                if (set != null) {
+                    mStateListState.mStateSets[i] = set.clone();
+                }
+            }
             mMutated = true;
         }
         return this;
     }
 
-    @Override
-    StateListState cloneConstantState() {
-        return new StateListState(mStateListState, this, null);
-    }
-
     /**
      * @hide
      */
@@ -327,24 +328,25 @@
             super(orig, owner, res);
 
             if (orig != null) {
-                // Perform a shallow copy and rely on mutate() to deep-copy.
+                // Perform a deep copy.
+                final int[][] sets = orig.mStateSets;
+                final int count = sets.length;
+                mStateSets = new int[count][];
+                for (int i = 0; i < count; i++) {
+                    final int[] set = sets[i];
+                    if (set != null) {
+                        mStateSets[i] = set.clone();
+                    }
+                }
+
                 mThemeAttrs = orig.mThemeAttrs;
-                mStateSets = orig.mStateSets;
+                mStateSets = Arrays.copyOf(orig.mStateSets, orig.mStateSets.length);
             } else {
                 mThemeAttrs = null;
                 mStateSets = new int[getCapacity()][];
             }
         }
 
-        private void mutate() {
-            mThemeAttrs = mThemeAttrs != null ? mThemeAttrs.clone() : null;
-
-            final int[][] stateSets = new int[mStateSets.length][];
-            for (int i = mStateSets.length - 1; i >= 0; i--) {
-                stateSets[i] = mStateSets[i] != null ? mStateSets[i].clone() : null;
-            }
-        }
-
         int addStateSet(int[] stateSet, Drawable drawable) {
             final int pos = addChild(drawable);
             mStateSets[pos] = stateSet;
@@ -393,14 +395,13 @@
         onStateChange(getState());
     }
 
-    protected void setConstantState(@NonNull StateListState state) {
+    void setConstantState(StateListState state) {
         super.setConstantState(state);
 
         mStateListState = state;
     }
 
     private StateListDrawable(StateListState state, Resources res) {
-        // Every state list drawable has its own constant state.
         final StateListState newState = new StateListState(state, this, res);
         setConstantState(newState);
         onStateChange(getState());
@@ -410,7 +411,7 @@
      * This constructor exists so subclasses can avoid calling the default
      * constructor and setting up a StateListDrawable-specific constant state.
      */
-    StateListDrawable(@Nullable StateListState state) {
+    StateListDrawable(StateListState state) {
         if (state != null) {
             setConstantState(state);
         }