diff options
author | Alan Viverette <alanv@google.com> | 2014-11-25 23:42:17 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-11-25 23:42:19 +0000 |
commit | 10e2700d50f68a4943ee2d7fe0804db73dc76bff (patch) | |
tree | 79991beaefa7985448b60083ac876d5914ab79ce | |
parent | e511ddce43ce3586f9bced5f8505e540951ab524 (diff) | |
parent | 8dcd533786df8d824f1e040230ee9e7e5b083998 (diff) | |
download | frameworks_base-10e2700d50f68a4943ee2d7fe0804db73dc76bff.zip frameworks_base-10e2700d50f68a4943ee2d7fe0804db73dc76bff.tar.gz frameworks_base-10e2700d50f68a4943ee2d7fe0804db73dc76bff.tar.bz2 |
Merge "Ensure calling mutate() on DrawableContainer creates a new state" into lmp-mr1-dev
5 files changed, 81 insertions, 37 deletions
diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java index f58a765..5fc40f2 100644 --- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java @@ -527,14 +527,18 @@ public class AnimatedStateListDrawable extends StateListDrawable { @Override public Drawable mutate() { if (!mMutated && super.mutate() == this) { - final AnimatedStateListState newState = new AnimatedStateListState(mState, this, null); - setConstantState(newState); + mState.mutate(); mMutated = true; } return this; } + @Override + AnimatedStateListState cloneConstantState() { + return new AnimatedStateListState(mState, this, null); + } + /** * @hide */ @@ -553,23 +557,29 @@ public class AnimatedStateListDrawable extends StateListDrawable { int[] mAnimThemeAttrs; - final LongSparseLongArray mTransitions; - final SparseIntArray mStateIds; + LongSparseLongArray mTransitions; + 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.clone(); - mStateIds = orig.mStateIds.clone(); + mTransitions = orig.mTransitions; + mStateIds = orig.mStateIds; } 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); @@ -641,15 +651,18 @@ public class AnimatedStateListDrawable extends StateListDrawable { } } - void setConstantState(@NonNull AnimatedStateListState state) { + protected void setConstantState(@NonNull DrawableContainerState state) { super.setConstantState(state); - mState = state; + if (state instanceof AnimatedStateListState) { + mState = (AnimatedStateListState) state; + } } 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 2ddf9df..28ada82 100644 --- a/graphics/java/android/graphics/drawable/AnimationDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java @@ -342,12 +342,17 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An @Override public Drawable mutate() { if (!mMutated && super.mutate() == this) { - mAnimationState.mDurations = mAnimationState.mDurations.clone(); + mAnimationState.mutate(); mMutated = true; } return this; } + @Override + AnimationState cloneConstantState() { + return new AnimationState(mAnimationState, this, null); + } + /** * @hide */ @@ -373,6 +378,10 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An } } + 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 326490f..6d43a0c 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -536,7 +536,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } if (schedule && animating) { - scheduleSelf(mAnimationRunnable, now + 1000/60); + scheduleSelf(mAnimationRunnable, now + 1000 / 60); } } @@ -567,6 +567,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { @Override public Drawable mutate() { if (!mMutated && super.mutate() == this) { + mDrawableContainerState = cloneConstantState(); mDrawableContainerState.mutate(); mMutated = true; } @@ -574,6 +575,16 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } /** + * 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() { @@ -833,7 +844,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { return false; } - final void mutate() { + private 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 9e918f6..dc41216 100644 --- a/graphics/java/android/graphics/drawable/LevelListDrawable.java +++ b/graphics/java/android/graphics/drawable/LevelListDrawable.java @@ -146,13 +146,17 @@ public class LevelListDrawable extends DrawableContainer { @Override public Drawable mutate() { if (!mMutated && super.mutate() == this) { - mLevelListState.mLows = mLevelListState.mLows.clone(); - mLevelListState.mHighs = mLevelListState.mHighs.clone(); + mLevelListState.mutate(); mMutated = true; } return this; } + @Override + LevelListState cloneConstantState() { + return new LevelListState(mLevelListState, this, null); + } + /** * @hide */ @@ -169,6 +173,7 @@ public class LevelListDrawable extends DrawableContainer { 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 { @@ -177,6 +182,11 @@ public class LevelListDrawable extends DrawableContainer { } } + 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 e7a8233..59d0ba6 100644 --- a/graphics/java/android/graphics/drawable/StateListDrawable.java +++ b/graphics/java/android/graphics/drawable/StateListDrawable.java @@ -24,6 +24,8 @@ import org.xmlpull.v1.XmlPullParserException; 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; @@ -288,20 +290,17 @@ public class StateListDrawable extends DrawableContainer { @Override public Drawable mutate() { if (!mMutated && super.mutate() == this) { - 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(); - } - } + mStateListState.mutate(); mMutated = true; } return this; } + @Override + StateListState cloneConstantState() { + return new StateListState(mStateListState, this, null); + } + /** * @hide */ @@ -328,25 +327,24 @@ public class StateListDrawable extends DrawableContainer { super(orig, owner, res); if (orig != null) { - // 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(); - } - } - + // Perform a shallow copy and rely on mutate() to deep-copy. mThemeAttrs = orig.mThemeAttrs; - mStateSets = Arrays.copyOf(orig.mStateSets, orig.mStateSets.length); + mStateSets = orig.mStateSets; } 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; @@ -395,13 +393,16 @@ public class StateListDrawable extends DrawableContainer { onStateChange(getState()); } - void setConstantState(StateListState state) { + protected void setConstantState(@NonNull DrawableContainerState state) { super.setConstantState(state); - mStateListState = state; + if (state instanceof StateListState) { + mStateListState = (StateListState) 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()); @@ -411,7 +412,7 @@ public class StateListDrawable extends DrawableContainer { * This constructor exists so subclasses can avoid calling the default * constructor and setting up a StateListDrawable-specific constant state. */ - StateListDrawable(StateListState state) { + StateListDrawable(@Nullable StateListState state) { if (state != null) { setConstantState(state); } |