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: I40d257867eb0a092ce580b9c4338ddc7406a031d
This commit is contained in:
Alan Viverette
2014-11-25 10:40:24 -08:00
parent 59093d925d
commit 8dcd533786
5 changed files with 81 additions and 37 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;