Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f66873e authored by Leon Scroggins III's avatar Leon Scroggins III
Browse files

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
parent 04fe7e60
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -5905,6 +5905,9 @@
        <!-- Identifier of the image file. This attribute is mandatory.
             It must be an image file with multiple frames, e.g. gif or webp -->
        <attr name="src" />
        <!-- Indicates if the drawable needs to be mirrored when its layout direction is
             RTL (right-to-left). -->
        <attr name="autoMirrored" />
    </declare-styleable>

    <!-- Drawable used to draw bitmaps. -->
+41 −10
Original line number Diff line number Diff line
@@ -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 {
     *  <p>By default, the loop count in the encoded data is respected.</p>
     */
    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() +
                    ": <animated-image> 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)) {