From 7f66873e0edfb9a4ad6b463c2839508f3453ad57 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Wed, 21 Feb 2018 16:14:37 -0500 Subject: [PATCH] Fixes for inflating AnimatedImageDrawable Bug: 73529437 Test: I7907f5dd7eb8d4ab72b8e9ddcbcbfc7aa8cb05ae Support AutoMirroring, from inflation and setting manually. Ensure that AnimatedImageDrawable always has a State object, even if it has no mNativePtr. If it has no mNativePtr, throw an Exception when trying to use it. Require that inflation have a valid src, unless it is waiting on a theme (like BitmapDrawable). Change-Id: I5b22cdbf4b57862d6ccc5750a677168287860f9f --- core/res/res/values/attrs.xml | 3 ++ .../drawable/AnimatedImageDrawable.java | 51 +++++++++++++++---- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index d26567e9a3f5f..14f72f6637ac8 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -5905,6 +5905,9 @@ + + diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java index 86e6fa8c2fc57..48a8ff90679d0 100644 --- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java @@ -72,11 +72,14 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { mAssetFd = afd; } - public final long mNativePtr; + final long mNativePtr; // These just keep references so the native code can continue using them. private final InputStream mInputStream; private final AssetFileDescriptor mAssetFd; + + int[] mThemeAttrs = null; + boolean mAutoMirrored = false; } private State mState; @@ -97,7 +100,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { *

By default, the loop count in the encoded data is respected.

*/ public void setLoopCount(int loopCount) { - if (mState == null) { + if (mState.mNativePtr == 0) { throw new IllegalStateException("called setLoopCount on empty AnimatedImageDrawable"); } nSetLoopCount(mState.mNativePtr, loopCount); @@ -107,7 +110,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { * Create an empty AnimatedImageDrawable. */ public AnimatedImageDrawable() { - mState = null; + mState = new State(0, null, null); } @Override @@ -121,6 +124,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { private void updateStateFromTypedArray(TypedArray a, int srcDensityOverride) throws XmlPullParserException { + State oldState = mState; final Resources r = a.getResources(); final int srcResId = a.getResourceId(R.styleable.AnimatedImageDrawable_src, 0); if (srcResId != 0) { @@ -170,6 +174,16 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { mIntrinsicWidth = other.mIntrinsicWidth; mIntrinsicHeight = other.mIntrinsicHeight; } + + mState.mThemeAttrs = a.extractThemeAttrs(); + if (mState.mNativePtr == 0 && (mState.mThemeAttrs == null + || mState.mThemeAttrs[R.styleable.AnimatedImageDrawable_src] == 0)) { + throw new XmlPullParserException(a.getPositionDescription() + + ": requires a valid 'src' attribute"); + } + + mState.mAutoMirrored = a.getBoolean( + R.styleable.AnimatedImageDrawable_autoMirrored, oldState.mAutoMirrored); } /** @@ -223,7 +237,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { @Override public void draw(@NonNull Canvas canvas) { - if (mState == null) { + if (mState.mNativePtr == 0) { throw new IllegalStateException("called draw on empty AnimatedImageDrawable"); } @@ -254,7 +268,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { + " 255! provided " + alpha); } - if (mState == null) { + if (mState.mNativePtr == 0) { throw new IllegalStateException("called setAlpha on empty AnimatedImageDrawable"); } @@ -264,7 +278,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { @Override public int getAlpha() { - if (mState == null) { + if (mState.mNativePtr == 0) { throw new IllegalStateException("called getAlpha on empty AnimatedImageDrawable"); } return nGetAlpha(mState.mNativePtr); @@ -272,7 +286,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { @Override public void setColorFilter(@Nullable ColorFilter colorFilter) { - if (mState == null) { + if (mState.mNativePtr == 0) { throw new IllegalStateException("called setColorFilter on empty AnimatedImageDrawable"); } @@ -286,12 +300,29 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { return PixelFormat.TRANSLUCENT; } + @Override + public void setAutoMirrored(boolean mirrored) { + if (mState.mAutoMirrored != mirrored) { + mState.mAutoMirrored = mirrored; + invalidateSelf(); + } + } + + @Override + public final boolean isAutoMirrored() { + return mState.mAutoMirrored; + } + @Override public boolean setVisible(boolean visible, boolean restart) { if (!super.setVisible(visible, restart)) { return false; } + if (mState.mNativePtr == 0) { + throw new IllegalStateException("called setVisible on empty AnimatedImageDrawable"); + } + if (!visible) { nMarkInvisible(mState.mNativePtr); } @@ -308,7 +339,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { */ @Override public boolean isRunning() { - if (mState == null) { + if (mState.mNativePtr == 0) { throw new IllegalStateException("called isRunning on empty AnimatedImageDrawable"); } return nIsRunning(mState.mNativePtr); @@ -325,7 +356,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { */ @Override public void start() { - if (mState == null) { + if (mState.mNativePtr == 0) { throw new IllegalStateException("called start on empty AnimatedImageDrawable"); } @@ -343,7 +374,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { */ @Override public void stop() { - if (mState == null) { + if (mState.mNativePtr == 0) { throw new IllegalStateException("called stop on empty AnimatedImageDrawable"); } if (nStop(mState.mNativePtr)) {