summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Viverette <alanv@google.com>2014-11-25 23:42:17 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-11-25 23:42:19 +0000
commit10e2700d50f68a4943ee2d7fe0804db73dc76bff (patch)
tree79991beaefa7985448b60083ac876d5914ab79ce
parente511ddce43ce3586f9bced5f8505e540951ab524 (diff)
parent8dcd533786df8d824f1e040230ee9e7e5b083998 (diff)
downloadframeworks_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
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java29
-rw-r--r--graphics/java/android/graphics/drawable/AnimationDrawable.java11
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java15
-rw-r--r--graphics/java/android/graphics/drawable/LevelListDrawable.java14
-rw-r--r--graphics/java/android/graphics/drawable/StateListDrawable.java49
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);
}