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

Commit c4533b70 authored by Leon Scroggins's avatar Leon Scroggins Committed by Android (Google) Code Review
Browse files

Merge "Expose AnimatedImageDrawable"

parents 150cca87 127d31a6
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -13569,6 +13569,7 @@ package android.graphics {
  public static class ImageDecoder.ImageInfo {
    method public java.lang.String getMimeType();
    method public android.util.Size getSize();
    method public boolean isAnimated();
  }
  public static class ImageDecoder.IncompleteException extends java.io.IOException {
@@ -14439,6 +14440,22 @@ package android.graphics.drawable {
    method public void onAnimationStart(android.graphics.drawable.Drawable);
  }
  public class AnimatedImageDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable2 {
    ctor public AnimatedImageDrawable();
    method public void clearAnimationCallbacks();
    method public void draw(android.graphics.Canvas);
    method public int getOpacity();
    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 start();
    method public void stop();
    method public boolean unregisterAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
    field public static final int LOOP_INFINITE = -1; // 0xffffffff
  }
  public class AnimatedStateListDrawable extends android.graphics.drawable.StateListDrawable {
    ctor public AnimatedStateListDrawable();
    method public void addState(int[], android.graphics.drawable.Drawable, int);
+48 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "GraphicsJNI.h"
#include "ImageDecoder.h"
#include "core_jni_helpers.h"
#include "Utils.h"

#include <hwui/AnimatedImageDrawable.h>
#include <hwui/Canvas.h>
@@ -28,6 +29,7 @@

using namespace android;

static jmethodID gAnimatedImageDrawable_postOnAnimationEndMethodID;

// Note: jpostProcess holds a handle to the ImageDecoder.
static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
@@ -113,6 +115,9 @@ static jboolean AnimatedImageDrawable_nIsRunning(JNIEnv* env, jobject /*clazz*/,
    return drawable->isRunning();
}

// Java's NOT_RUNNING relies on this being -2.0.
static_assert(SkAnimatedImage::kNotRunning == -2.0);

static jboolean AnimatedImageDrawable_nStart(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
    auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
    return drawable->start();
@@ -123,6 +128,44 @@ static void AnimatedImageDrawable_nStop(JNIEnv* env, jobject /*clazz*/, jlong na
    drawable->stop();
}

// Java's LOOP_INFINITE relies on this being the same.
static_assert(SkCodec::kRepetitionCountInfinite == -1);

static void AnimatedImageDrawable_nSetLoopCount(JNIEnv* env, jobject /*clazz*/, jlong nativePtr,
                                                jint loopCount) {
    auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
    drawable->setRepetitionCount(loopCount);
}

class JniAnimationEndListener : public OnAnimationEndListener {
public:
    JniAnimationEndListener(JNIEnv* env, jobject javaObject) {
        LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&mJvm) != JNI_OK);
        mJavaObject = env->NewGlobalRef(javaObject);
    }

    ~JniAnimationEndListener() override {
        auto* env = get_env_or_die(mJvm);
        env->DeleteGlobalRef(mJavaObject);
    }

    void onAnimationEnd() override {
        auto* env = get_env_or_die(mJvm);
        env->CallVoidMethod(mJavaObject, gAnimatedImageDrawable_postOnAnimationEndMethodID);
    }

private:
    JavaVM* mJvm;
    jobject mJavaObject;
};

static void AnimatedImageDrawable_nSetOnAnimationEndListener(JNIEnv* env, jobject /*clazz*/,
                                                             jlong nativePtr, jobject jdrawable) {
    auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
    drawable->setOnAnimationEndListener(std::unique_ptr<OnAnimationEndListener>(
                new JniAnimationEndListener(env, jdrawable)));
}

static long AnimatedImageDrawable_nNativeByteSize(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
    auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
    // FIXME: Report the size of the internal SkBitmap etc.
@@ -139,10 +182,15 @@ static const JNINativeMethod gAnimatedImageDrawableMethods[] = {
    { "nIsRunning",          "(J)Z",                                                         (void*) AnimatedImageDrawable_nIsRunning },
    { "nStart",              "(J)Z",                                                         (void*) AnimatedImageDrawable_nStart },
    { "nStop",               "(J)V",                                                         (void*) AnimatedImageDrawable_nStop },
    { "nSetLoopCount",       "(JI)V",                                                        (void*) AnimatedImageDrawable_nSetLoopCount },
    { "nSetOnAnimationEndListener", "(JLandroid/graphics/drawable/AnimatedImageDrawable;)V", (void*) AnimatedImageDrawable_nSetOnAnimationEndListener },
    { "nNativeByteSize",     "(J)J",                                                         (void*) AnimatedImageDrawable_nNativeByteSize },
};

int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv* env) {
    jclass animatedImageDrawable_class = FindClassOrDie(env, "android/graphics/drawable/AnimatedImageDrawable");
    gAnimatedImageDrawable_postOnAnimationEndMethodID = GetMethodIDOrDie(env, animatedImageDrawable_class, "postOnAnimationEnd", "()V");

    return android::RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedImageDrawable",
            gAnimatedImageDrawableMethods, NELEM(gAnimatedImageDrawableMethods));
}
+1 −8
Original line number Diff line number Diff line
#include "ByteBufferStreamAdaptor.h"
#include "core_jni_helpers.h"
#include "Utils.h"

#include <SkStream.h>

@@ -8,14 +9,6 @@ using namespace android;
static jmethodID gByteBuffer_getMethodID;
static jmethodID gByteBuffer_setPositionMethodID;

static JNIEnv* get_env_or_die(JavaVM* jvm) {
    JNIEnv* env;
    if (jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
        LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", jvm);
    }
    return env;
}

class ByteBufferStream : public SkStreamAsset {
private:
    ByteBufferStream(JavaVM* jvm, jobject jbyteBuffer, size_t initialPosition, size_t length,
+2 −11
Original line number Diff line number Diff line
@@ -12,15 +12,6 @@
static jmethodID    gInputStream_readMethodID;
static jmethodID    gInputStream_skipMethodID;

// FIXME: Share with ByteBufferStreamAdaptor.cpp?
static JNIEnv* get_env_or_die(JavaVM* jvm) {
    JNIEnv* env;
    if (jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
        LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", jvm);
    }
    return env;
}

/**
 *  Wrapper for a Java InputStream.
 */
@@ -57,13 +48,13 @@ public:
    }

    ~JavaInputStreamAdaptor() override {
        auto* env = get_env_or_die(fJvm);
        auto* env = android::get_env_or_die(fJvm);
        env->DeleteGlobalRef(fJavaInputStream);
        env->DeleteGlobalRef(fJavaByteArray);
    }

    size_t read(void* buffer, size_t size) override {
        auto* env = get_env_or_die(fJvm);
        auto* env = android::get_env_or_die(fJvm);
        if (!fSwallowExceptions && checkException(env)) {
            // Just in case the caller did not clear from a previous exception.
            return 0;
+8 −0
Original line number Diff line number Diff line
@@ -117,3 +117,11 @@ jobject android::nullObjectReturn(const char msg[]) {
bool android::isSeekable(int descriptor) {
    return ::lseek64(descriptor, 0, SEEK_CUR) != -1;
}

JNIEnv* android::get_env_or_die(JavaVM* jvm) {
    JNIEnv* env;
    if (jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
        LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", jvm);
    }
    return env;
}
Loading