diff options
Diffstat (limited to 'graphics/java')
5 files changed, 263 insertions, 74 deletions
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java index e7cfcfdf7760..c69eb32148c0 100644 --- a/graphics/java/android/graphics/FontFamily.java +++ b/graphics/java/android/graphics/FontFamily.java @@ -24,6 +24,8 @@ import android.util.Log; import dalvik.annotation.optimization.CriticalNative; +import libcore.util.NativeAllocationRegistry; + import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; @@ -38,6 +40,14 @@ public class FontFamily { private static String TAG = "FontFamily"; + private static final NativeAllocationRegistry sBuilderRegistry = new NativeAllocationRegistry( + FontFamily.class.getClassLoader(), nGetBuilderReleaseFunc(), 64); + + private @Nullable Runnable mNativeBuilderCleaner; + + private static final NativeAllocationRegistry sFamilyRegistry = new NativeAllocationRegistry( + FontFamily.class.getClassLoader(), nGetFamilyReleaseFunc(), 64); + /** * @hide */ @@ -48,6 +58,7 @@ public class FontFamily { public FontFamily() { mBuilderPtr = nInitBuilder(null, 0); + mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr); } public FontFamily(@Nullable String[] langs, int variant) { @@ -60,6 +71,7 @@ public class FontFamily { langsString = TextUtils.join(",", langs); } mBuilderPtr = nInitBuilder(langsString, variant); + mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr); } /** @@ -73,7 +85,11 @@ public class FontFamily { throw new IllegalStateException("This FontFamily is already frozen"); } mNativePtr = nCreateFamily(mBuilderPtr); + mNativeBuilderCleaner.run(); mBuilderPtr = 0; + if (mNativePtr != 0) { + sFamilyRegistry.registerNativeAllocation(this, mNativePtr); + } return mNativePtr != 0; } @@ -81,24 +97,10 @@ public class FontFamily { if (mBuilderPtr == 0) { throw new IllegalStateException("This FontFamily is already frozen or abandoned"); } - nAbort(mBuilderPtr); + mNativeBuilderCleaner.run(); mBuilderPtr = 0; } - @Override - protected void finalize() throws Throwable { - try { - if (mNativePtr != 0) { - nUnrefFamily(mNativePtr); - } - if (mBuilderPtr != 0) { - nAbort(mBuilderPtr); - } - } finally { - super.finalize(); - } - } - public boolean addFont(String path, int ttcIndex, FontVariationAxis[] axes, int weight, int italic) { if (mBuilderPtr == 0) { @@ -171,10 +173,10 @@ public class FontFamily { private static native long nCreateFamily(long mBuilderPtr); @CriticalNative - private static native void nAbort(long mBuilderPtr); + private static native long nGetBuilderReleaseFunc(); @CriticalNative - private static native void nUnrefFamily(long nativePtr); + private static native long nGetFamilyReleaseFunc(); // By passing -1 to weigth argument, the weight value is resolved by OS/2 table in the font. // By passing -1 to italic argument, the italic value is resolved by OS/2 table in the font. private static native boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex, diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index 5abd31a0998a..88701fac66c7 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -493,7 +493,7 @@ public final class ImageDecoder implements AutoCloseable { private boolean mRequireUnpremultiplied = false; private boolean mMutable = false; private boolean mConserveMemory = false; - private boolean mAsAlphaMask = false; + private boolean mDecodeAsAlphaMask = false; private Rect mCropRect; private Rect mOutPaddingRect; private Source mSource; @@ -730,7 +730,7 @@ public final class ImageDecoder implements AutoCloseable { * Will typically result in a {@link Bitmap.Config#HARDWARE} * allocation, but may be software for small images. In addition, this will * switch to software when HARDWARE is incompatible, e.g. - * {@link #setMutable}, {@link #setAsAlphaMask}. + * {@link #setMutable}, {@link #setDecodeAsAlphaMask}. */ public static final int ALLOCATOR_DEFAULT = 0; @@ -753,7 +753,7 @@ public final class ImageDecoder implements AutoCloseable { * Require a {@link Bitmap.Config#HARDWARE} {@link Bitmap}. * * When this is combined with incompatible options, like - * {@link #setMutable} or {@link #setAsAlphaMask}, {@link #decodeDrawable} + * {@link #setMutable} or {@link #setDecodeAsAlphaMask}, {@link #decodeDrawable} * / {@link #decodeBitmap} will throw an * {@link java.lang.IllegalStateException}. */ @@ -783,6 +783,14 @@ public final class ImageDecoder implements AutoCloseable { } /** + * Return the allocator for the pixel memory. + */ + @Allocator + public int getAllocator() { + return mAllocator; + } + + /** * Specify whether the {@link Bitmap} should have unpremultiplied pixels. * * <p>By default, ImageDecoder will create a {@link Bitmap} with @@ -803,6 +811,13 @@ public final class ImageDecoder implements AutoCloseable { } /** + * Return whether the {@link Bitmap} will have unpremultiplied pixels. + */ + public boolean getRequireUnpremultiplied() { + return mRequireUnpremultiplied; + } + + /** * Modify the image after decoding and scaling. * * <p>This allows adding effects prior to returning a {@link Drawable} or @@ -823,6 +838,14 @@ public final class ImageDecoder implements AutoCloseable { } /** + * Return the {@link PostProcessor} currently set. + */ + @Nullable + public PostProcessor getPostProcessor() { + return mPostProcessor; + } + + /** * Set (replace) the {@link OnPartialImageListener} on this object. * * <p>Will be called if there is an error in the input. Without one, an @@ -836,6 +859,14 @@ public final class ImageDecoder implements AutoCloseable { } /** + * Return the {@link OnPartialImageListener} currently set. + */ + @Nullable + public OnPartialImageListener getOnPartialImageListener() { + return mOnPartialImageListener; + } + + /** * Crop the output to {@code subset} of the (possibly) scaled image. * * <p>{@code subset} must be contained within the size set by @@ -855,6 +886,14 @@ public final class ImageDecoder implements AutoCloseable { } /** + * Return the cropping rectangle, if set. + */ + @Nullable + public Rect getCrop() { + return mCropRect; + } + + /** * Set a Rect for retrieving nine patch padding. * * If the image is a nine patch, this Rect will be set to the padding @@ -893,6 +932,13 @@ public final class ImageDecoder implements AutoCloseable { } /** + * Return whether the {@link Bitmap} will be mutable. + */ + public boolean getMutable() { + return mMutable; + } + + /** * Specify whether to potentially save RAM at the expense of quality. * * <p>Setting this to {@code true} may result in a {@link Bitmap} with a @@ -912,24 +958,62 @@ public final class ImageDecoder implements AutoCloseable { } /** + * Return whether this object will try to save RAM at the expense of quality. + * + * <p>This returns whether {@link #setConserveMemory} was set to {@code true}. + * It may still return {@code true} even if the {@code ImageDecoder} does not + * have a way to save RAM at the expense of quality for this image.</p> + */ + public boolean getConserveMemory() { + return mConserveMemory; + } + + /** * Specify whether to potentially treat the output as an alpha mask. * * <p>If this is set to {@code true} and the image is encoded in a format * with only one channel, treat that channel as alpha. Otherwise this call has * no effect.</p> * - * <p>setAsAlphaMask is incompatible with {@link #ALLOCATOR_HARDWARE}. Trying to + * <p>setDecodeAsAlphaMask is incompatible with {@link #ALLOCATOR_HARDWARE}. Trying to * combine them will result in {@link #decodeDrawable}/ * {@link #decodeBitmap} throwing an * {@link java.lang.IllegalStateException}.</p> * * @return this object for chaining. */ - public ImageDecoder setAsAlphaMask(boolean asAlphaMask) { - mAsAlphaMask = asAlphaMask; + public ImageDecoder setDecodeAsAlphaMask(boolean decodeAsAlphaMask) { + mDecodeAsAlphaMask = decodeAsAlphaMask; return this; } + /** @removed + * @deprecated Call {@link #setDecodeAsAlphaMask} instead. + */ + @java.lang.Deprecated + public ImageDecoder setAsAlphaMask(boolean asAlphaMask) { + return this.setDecodeAsAlphaMask(asAlphaMask); + } + + /** + * Return whether to treat single channel input as alpha. + * + * <p>This returns whether {@link #setDecodeAsAlphaMask} was set to {@code true}. + * It may still return {@code true} even if the image has more than one + * channel and therefore will not be treated as an alpha mask.</p> + */ + public boolean getDecodeAsAlphaMask() { + return mDecodeAsAlphaMask; + } + + /** @removed + * @deprecated Call {@link #getDecodeAsAlphaMask} instead. + */ + @java.lang.Deprecated + public boolean getAsAlphaMask() { + return this.getDecodeAsAlphaMask(); + } + @Override public void close() { mCloseGuard.close(); @@ -960,7 +1044,7 @@ public final class ImageDecoder implements AutoCloseable { if (mMutable) { throw new IllegalStateException("Cannot make mutable HARDWARE Bitmap!"); } - if (mAsAlphaMask) { + if (mDecodeAsAlphaMask) { throw new IllegalStateException("Cannot make HARDWARE Alpha mask Bitmap!"); } } @@ -981,7 +1065,7 @@ public final class ImageDecoder implements AutoCloseable { } @NonNull - private Bitmap decodeBitmap() throws IOException { + private Bitmap decodeBitmapInternal() throws IOException { checkState(); // nDecodeBitmap calls onPartialImage only if mOnPartialImageListener // exists @@ -992,7 +1076,7 @@ public final class ImageDecoder implements AutoCloseable { return nDecodeBitmap(mNativePtr, partialImagePtr, postProcessPtr, mDesiredWidth, mDesiredHeight, mCropRect, mMutable, mAllocator, mRequireUnpremultiplied, - mConserveMemory, mAsAlphaMask); + mConserveMemory, mDecodeAsAlphaMask); } private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener, @@ -1012,15 +1096,24 @@ public final class ImageDecoder implements AutoCloseable { * * @param src representing the encoded image. * @param listener for learning the {@link ImageInfo} and changing any - * default settings on the {@code ImageDecoder}. If not {@code null}, - * this will be called on the same thread as {@code decodeDrawable} - * before that method returns. + * default settings on the {@code ImageDecoder}. This will be called on + * the same thread as {@code decodeDrawable} before that method returns. * @return Drawable for displaying the image. * @throws IOException if {@code src} is not found, is an unsupported * format, or cannot be decoded for any reason. */ @NonNull public static Drawable decodeDrawable(@NonNull Source src, + @NonNull OnHeaderDecodedListener listener) throws IOException { + if (listener == null) { + throw new IllegalArgumentException("listener cannot be null! " + + "Use decodeDrawable(Source) to not have a listener"); + } + return decodeDrawableImpl(src, listener); + } + + @NonNull + private static Drawable decodeDrawableImpl(@NonNull Source src, @Nullable OnHeaderDecodedListener listener) throws IOException { try (ImageDecoder decoder = src.createImageDecoder()) { decoder.mSource = src; @@ -1057,7 +1150,7 @@ public final class ImageDecoder implements AutoCloseable { return d; } - Bitmap bm = decoder.decodeBitmap(); + Bitmap bm = decoder.decodeBitmapInternal(); bm.setDensity(srcDensity); Resources res = src.getResources(); @@ -1084,7 +1177,7 @@ public final class ImageDecoder implements AutoCloseable { @NonNull public static Drawable decodeDrawable(@NonNull Source src) throws IOException { - return decodeDrawable(src, null); + return decodeDrawableImpl(src, null); } /** @@ -1092,15 +1185,24 @@ public final class ImageDecoder implements AutoCloseable { * * @param src representing the encoded image. * @param listener for learning the {@link ImageInfo} and changing any - * default settings on the {@code ImageDecoder}. If not {@code null}, - * this will be called on the same thread as {@code decodeBitmap} - * before that method returns. + * default settings on the {@code ImageDecoder}. This will be called on + * the same thread as {@code decodeBitmap} before that method returns. * @return Bitmap containing the image. * @throws IOException if {@code src} is not found, is an unsupported * format, or cannot be decoded for any reason. */ @NonNull public static Bitmap decodeBitmap(@NonNull Source src, + @NonNull OnHeaderDecodedListener listener) throws IOException { + if (listener == null) { + throw new IllegalArgumentException("listener cannot be null! " + + "Use decodeBitmap(Source) to not have a listener"); + } + return decodeBitmapImpl(src, listener); + } + + @NonNull + private static Bitmap decodeBitmapImpl(@NonNull Source src, @Nullable OnHeaderDecodedListener listener) throws IOException { try (ImageDecoder decoder = src.createImageDecoder()) { decoder.mSource = src; @@ -1109,7 +1211,7 @@ public final class ImageDecoder implements AutoCloseable { // this call potentially manipulates the decoder so it must be performed prior to // decoding the bitmap final int srcDensity = computeDensity(src, decoder); - Bitmap bm = decoder.decodeBitmap(); + Bitmap bm = decoder.decodeBitmapInternal(); bm.setDensity(srcDensity); Rect padding = decoder.mOutPaddingRect; @@ -1167,7 +1269,7 @@ public final class ImageDecoder implements AutoCloseable { */ @NonNull public static Bitmap decodeBitmap(@NonNull Source src) throws IOException { - return decodeBitmap(src, null); + return decodeBitmapImpl(src, null); } /** @@ -1206,7 +1308,7 @@ public final class ImageDecoder implements AutoCloseable { int width, int height, @Nullable Rect cropRect, boolean mutable, int allocator, boolean requireUnpremul, - boolean conserveMemory, boolean asAlphaMask) + boolean conserveMemory, boolean decodeAsAlphaMask) throws IOException; private static native Size nGetSampledSize(long nativePtr, int sampleSize); diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 38beebde4b14..f27c11dbf735 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -42,6 +42,10 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; +import dalvik.annotation.optimization.CriticalNative; + +import libcore.util.NativeAllocationRegistry; + import org.xmlpull.v1.XmlPullParserException; import java.io.File; @@ -71,6 +75,9 @@ public class Typeface { private static String TAG = "Typeface"; + private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( + Typeface.class.getClassLoader(), nativeGetReleaseFunc(), 64); + /** The default NORMAL typeface object */ public static final Typeface DEFAULT; /** @@ -911,6 +918,7 @@ public class Typeface { } native_instance = ni; + sRegistry.registerNativeAllocation(this, native_instance); mStyle = nativeGetStyle(ni); mWeight = nativeGetWeight(ni); } @@ -1120,16 +1128,6 @@ public class Typeface { } @Override - protected void finalize() throws Throwable { - try { - nativeUnref(native_instance); - native_instance = 0; // Other finalizers can still call us. - } finally { - super.finalize(); - } - } - - @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; @@ -1173,10 +1171,18 @@ public class Typeface { private static native long nativeCreateFromTypefaceWithVariation( long native_instance, List<FontVariationAxis> axes); private static native long nativeCreateWeightAlias(long native_instance, int weight); - private static native void nativeUnref(long native_instance); - private static native int nativeGetStyle(long native_instance); - private static native int nativeGetWeight(long native_instance); private static native long nativeCreateFromArray(long[] familyArray, int weight, int italic); - private static native void nativeSetDefault(long native_instance); private static native int[] nativeGetSupportedAxes(long native_instance); + + @CriticalNative + private static native void nativeSetDefault(long nativePtr); + + @CriticalNative + private static native int nativeGetStyle(long nativePtr); + + @CriticalNative + private static native int nativeGetWeight(long nativePtr); + + @CriticalNative + private static native long nativeGetReleaseFunc(); } diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java index 1d0cfa5ff082..fdd638adba81 100644 --- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java +++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java @@ -44,6 +44,7 @@ import android.util.DisplayMetrics; import android.util.PathParser; import com.android.internal.R; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -668,13 +669,7 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback @Override public void setAlpha(int alpha) { - final ChildDrawable[] array = mLayerState.mChildren; - for (int i = 0; i < mLayerState.N_CHILDREN; i++) { - final Drawable dr = array[i].mDrawable; - if (dr != null) { - dr.setAlpha(alpha); - } - } + mPaint.setAlpha(alpha); } @Override diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java index f70d6e1223df..c0f49208e27e 100644 --- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java @@ -34,6 +34,7 @@ import android.os.Looper; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.TypedValue; +import android.view.View; import com.android.internal.R; @@ -77,6 +78,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { int[] mThemeAttrs = null; boolean mAutoMirrored = false; + int mRepeatCount = REPEAT_UNDEFINED; } private State mState; @@ -86,33 +88,87 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { 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 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>By default, the loop count in the encoded data is respected.</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); + } + if (mState.mRepeatCount != repeatCount) { + mState.mRepeatCount = repeatCount; + if (mState.mNativePtr != 0) { + nSetRepeatCount(mState.mNativePtr, repeatCount); + } } - nSetLoopCount(mState.mNativePtr, loopCount); + } + + /** @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"); + } + if (mState.mRepeatCount == REPEAT_UNDEFINED) { + mState.mRepeatCount = nGetRepeatCount(mState.mNativePtr); + } - return nGetLoopCount(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 +232,18 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { ": <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 +255,12 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { 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 +339,7 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { } @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); @@ -322,11 +390,25 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { public void setAutoMirrored(boolean mirrored) { if (mState.mAutoMirrored != mirrored) { mState.mAutoMirrored = mirrored; - invalidateSelf(); + if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL && mState.mNativePtr != 0) { + nSetMirrored(mState.mNativePtr, mirrored); + invalidateSelf(); + } } } @Override + public boolean onLayoutDirectionChanged(int layoutDirection) { + if (!mState.mAutoMirrored || mState.mNativePtr == 0) { + return false; + } + + final boolean mirror = layoutDirection == View.LAYOUT_DIRECTION_RTL; + nSetMirrored(mState.mNativePtr, mirror); + return true; + } + + @Override public final boolean isAutoMirrored() { return mState.mAutoMirrored; } @@ -508,9 +590,9 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { @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); @@ -518,4 +600,6 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { private static native long nNativeByteSize(long nativePtr); @FastNative private static native void nMarkInvisible(long nativePtr); + @FastNative + private static native void nSetMirrored(long nativePtr, boolean mirror); } |