Ensure calling mutate() on DrawableContainer creates a new state

Previously, a new state would only be created on newDrawable(), which
caused the first drawable loaded for a resource to share constant state
with the cached version. Even if mutate() was called, the constant
state was still shared and any changes were applied to the cached copy.

BUG: 18504919
Change-Id: I1ce76fbbc144e9c0c93261e3a12cc613d0c74b83
This commit is contained in:
Alan Viverette
2014-11-24 11:11:05 -08:00
parent 29dc496a42
commit d7dab349c2
5 changed files with 75 additions and 35 deletions

View File

@@ -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,12 +567,23 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override
public Drawable mutate() {
if (!mMutated && super.mutate() == this) {
mDrawableContainerState = cloneConstantState();
mDrawableContainerState.mutate();
mMutated = true;
}
return this;
}
/**
* 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
*/
@@ -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;