Merge "AID: Change loop to repeat and set from xml"
diff --git a/api/current.txt b/api/current.txt
index 12fb56c..7bdff3f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -14511,18 +14511,18 @@
ctor public AnimatedImageDrawable();
method public void clearAnimationCallbacks();
method public void draw(android.graphics.Canvas);
- method public int getLoopCount();
method public int getOpacity();
+ method public int getRepeatCount();
method public final boolean isAutoMirrored();
method public boolean isRunning();
method public void registerAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
method public void setAlpha(int);
method public void setColorFilter(android.graphics.ColorFilter);
- method public void setLoopCount(int);
+ method public void setRepeatCount(int);
method public void start();
method public void stop();
method public boolean unregisterAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
- field public static final int LOOP_INFINITE = -1; // 0xffffffff
+ field public static final int REPEAT_INFINITE = -1; // 0xffffffff
}
public class AnimatedStateListDrawable extends android.graphics.drawable.StateListDrawable {
diff --git a/api/removed.txt b/api/removed.txt
index 79c54fd..b8e2b98 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -173,6 +173,16 @@
}
+package android.graphics.drawable {
+
+ public class AnimatedImageDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable2 {
+ method public deprecated int getLoopCount(int);
+ method public deprecated void setLoopCount(int);
+ field public static final deprecated int LOOP_INFINITE = -1; // 0xffffffff
+ }
+
+}
+
package android.hardware {
public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
diff --git a/core/jni/android/graphics/AnimatedImageDrawable.cpp b/core/jni/android/graphics/AnimatedImageDrawable.cpp
index 6fd4abf..d5cad02 100644
--- a/core/jni/android/graphics/AnimatedImageDrawable.cpp
+++ b/core/jni/android/graphics/AnimatedImageDrawable.cpp
@@ -132,13 +132,13 @@
// Java's LOOP_INFINITE relies on this being the same.
static_assert(SkCodec::kRepetitionCountInfinite == -1);
-static jint AnimatedImageDrawable_nGetLoopCount(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
+static jint AnimatedImageDrawable_nGetRepeatCount(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
return drawable->getRepetitionCount();
}
-static void AnimatedImageDrawable_nSetLoopCount(JNIEnv* env, jobject /*clazz*/, jlong nativePtr,
- jint loopCount) {
+static void AnimatedImageDrawable_nSetRepeatCount(JNIEnv* env, jobject /*clazz*/, jlong nativePtr,
+ jint loopCount) {
auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
drawable->setRepetitionCount(loopCount);
}
@@ -223,8 +223,8 @@
{ "nIsRunning", "(J)Z", (void*) AnimatedImageDrawable_nIsRunning },
{ "nStart", "(J)Z", (void*) AnimatedImageDrawable_nStart },
{ "nStop", "(J)Z", (void*) AnimatedImageDrawable_nStop },
- { "nGetLoopCount", "(J)I", (void*) AnimatedImageDrawable_nGetLoopCount },
- { "nSetLoopCount", "(JI)V", (void*) AnimatedImageDrawable_nSetLoopCount },
+ { "nGetRepeatCount", "(J)I", (void*) AnimatedImageDrawable_nGetRepeatCount },
+ { "nSetRepeatCount", "(JI)V", (void*) AnimatedImageDrawable_nSetRepeatCount },
{ "nSetOnAnimationEndListener", "(JLandroid/graphics/drawable/AnimatedImageDrawable;)V", (void*) AnimatedImageDrawable_nSetOnAnimationEndListener },
{ "nNativeByteSize", "(J)J", (void*) AnimatedImageDrawable_nNativeByteSize },
{ "nMarkInvisible", "(J)V", (void*) AnimatedImageDrawable_nMarkInvisible },
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index ffabdab..796030e 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5954,6 +5954,11 @@
<!-- Indicates if the drawable needs to be mirrored when its layout direction is
RTL (right-to-left). -->
<attr name="autoMirrored" />
+ <!-- Replace the loop count in the encoded data. A repeat count of 0 means that
+ the animation will play once, regardless of the number of times specified
+ in the encoded data. Setting this to infinite (-1) will result in the
+ animation repeating as long as it is displayed (once start() is called). -->
+ <attr name="repeatCount"/>
</declare-styleable>
<!-- Drawable used to draw bitmaps. -->
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index f70d6e1..2ea745c 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -77,6 +77,7 @@
int[] mThemeAttrs = null;
boolean mAutoMirrored = false;
+ int mRepeatCount = REPEAT_UNDEFINED;
}
private State mState;
@@ -86,33 +87,87 @@
private ColorFilter mColorFilter;
/**
- * Pass this to {@link #setLoopCount} to loop infinitely.
+ * Pass this to {@link #setRepeatCount} to repeat infinitely.
*
* <p>{@link Animatable2.AnimationCallback#onAnimationEnd} will never be
* called unless there is an error.</p>
*/
- public static final int LOOP_INFINITE = -1;
+ public static final int REPEAT_INFINITE = -1;
+
+ /** @removed
+ * @deprecated Replaced with REPEAT_INFINITE to match other APIs.
+ */
+ @java.lang.Deprecated
+ public static final int LOOP_INFINITE = REPEAT_INFINITE;
+
+ private static final int REPEAT_UNDEFINED = -2;
/**
- * Specify the number of times to loop the animation.
+ * Specify the number of times to repeat the animation.
*
- * <p>By default, the loop count in the encoded data is respected.</p>
+ * <p>By default, the repeat count in the encoded data is respected. If set
+ * to {@link #REPEAT_INFINITE}, the animation will repeat as long as it is
+ * displayed. If the value is {@code 0}, the animation will play once.</p>
+ *
+ * <p>This call replaces the current repeat count. If the encoded data
+ * specified a repeat count of {@code 2} (meaning that
+ * {@link #getRepeatCount()} returns {@code 2}, the animation will play
+ * three times. Calling {@code setRepeatCount(1)} will result in playing only
+ * twice and {@link #getRepeatCount()} returning {@code 1}.</p>
+ *
+ * <p>If the animation is already playing, the iterations that have already
+ * occurred count towards the new count. If the animation has already
+ * repeated the appropriate number of times (or more), it will finish its
+ * current iteration and then stop.</p>
*/
- public void setLoopCount(int loopCount) {
- if (mState.mNativePtr == 0) {
- throw new IllegalStateException("called setLoopCount on empty AnimatedImageDrawable");
+ public void setRepeatCount(@IntRange(from = REPEAT_INFINITE) int repeatCount) {
+ if (repeatCount < REPEAT_INFINITE) {
+ throw new IllegalArgumentException("invalid value passed to setRepeatCount"
+ + repeatCount);
}
- nSetLoopCount(mState.mNativePtr, loopCount);
+ if (mState.mRepeatCount != repeatCount) {
+ mState.mRepeatCount = repeatCount;
+ if (mState.mNativePtr != 0) {
+ nSetRepeatCount(mState.mNativePtr, repeatCount);
+ }
+ }
+ }
+
+ /** @removed
+ * @deprecated Replaced with setRepeatCount to match other APIs.
+ */
+ @java.lang.Deprecated
+ public void setLoopCount(int loopCount) {
+ setRepeatCount(loopCount);
}
/**
- * Retrieve the number of times the animation will loop.
+ * Retrieve the number of times the animation will repeat.
+ *
+ * <p>By default, the repeat count in the encoded data is respected. If the
+ * value is {@link #REPEAT_INFINITE}, the animation will repeat as long as
+ * it is displayed. If the value is {@code 0}, it will play once.</p>
+ *
+ * <p>Calling {@link #setRepeatCount} will make future calls to this method
+ * return the value passed to {@link #setRepeatCount}.</p>
*/
- public int getLoopCount() {
+ public int getRepeatCount() {
if (mState.mNativePtr == 0) {
- throw new IllegalStateException("called getLoopCount on empty AnimatedImageDrawable");
+ throw new IllegalStateException("called getRepeatCount on empty AnimatedImageDrawable");
}
- return nGetLoopCount(mState.mNativePtr);
+ if (mState.mRepeatCount == REPEAT_UNDEFINED) {
+ mState.mRepeatCount = nGetRepeatCount(mState.mNativePtr);
+
+ }
+ return mState.mRepeatCount;
+ }
+
+ /** @removed
+ * @deprecated Replaced with getRepeatCount to match other APIs.
+ */
+ @java.lang.Deprecated
+ public int getLoopCount(int loopCount) {
+ return getRepeatCount();
}
/**
@@ -176,12 +231,18 @@
": <animated-image> did not decode animated");
}
+ // This may have previously been set without a src if we were waiting for a
+ // theme.
+ final int repeatCount = mState.mRepeatCount;
// Transfer the state of other to this one. other will be discarded.
AnimatedImageDrawable other = (AnimatedImageDrawable) drawable;
mState = other.mState;
other.mState = null;
mIntrinsicWidth = other.mIntrinsicWidth;
mIntrinsicHeight = other.mIntrinsicHeight;
+ if (repeatCount != REPEAT_UNDEFINED) {
+ this.setRepeatCount(repeatCount);
+ }
}
mState.mThemeAttrs = a.extractThemeAttrs();
@@ -193,6 +254,12 @@
mState.mAutoMirrored = a.getBoolean(
R.styleable.AnimatedImageDrawable_autoMirrored, oldState.mAutoMirrored);
+
+ int repeatCount = a.getInt(
+ R.styleable.AnimatedImageDrawable_repeatCount, REPEAT_UNDEFINED);
+ if (repeatCount != REPEAT_UNDEFINED) {
+ this.setRepeatCount(repeatCount);
+ }
}
/**
@@ -271,7 +338,7 @@
}
@Override
- public void setAlpha(@IntRange(from=0,to=255) int alpha) {
+ public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {
if (alpha < 0 || alpha > 255) {
throw new IllegalArgumentException("Alpha must be between 0 and"
+ " 255! provided " + alpha);
@@ -508,9 +575,9 @@
@FastNative
private static native boolean nStop(long nativePtr);
@FastNative
- private static native int nGetLoopCount(long nativePtr);
+ private static native int nGetRepeatCount(long nativePtr);
@FastNative
- private static native void nSetLoopCount(long nativePtr, int loopCount);
+ private static native void nSetRepeatCount(long nativePtr, int repeatCount);
// Pass the drawable down to native so it can call onAnimationEnd.
private static native void nSetOnAnimationEndListener(long nativePtr,
@Nullable AnimatedImageDrawable drawable);