/*
**
** Copyright 2008, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

//#define LOG_NDEBUG 0
#define LOG_TAG "MediaMetadataRetrieverJNI"

#include <cmath>
#include <assert.h>
#include <utils/Log.h>
#include <utils/threads.h>
#include <android/graphics/bitmap.h>
#include <media/IMediaHTTPService.h>
#include <media/mediametadataretriever.h>
#include <media/mediascanner.h>
#include <nativehelper/ScopedLocalRef.h>
#include <private/media/VideoFrame.h>

#include "jni.h"
#include <nativehelper/JNIPlatformHelp.h>
#include "android_runtime/AndroidRuntime.h"
#include "android_media_MediaDataSource.h"
#include "android_media_Streams.h"
#include "android_util_Binder.h"

using namespace android;

struct fields_t {
    jfieldID context;
    jclass bitmapClazz;  // Must be a global ref
    jmethodID createBitmapMethod;
    jmethodID createScaledBitmapMethod;
    jclass bitmapParamsClazz; // Must be a global ref
    jfieldID inPreferredConfig;
    jfieldID outActualConfig;
    jclass arrayListClazz; // Must be a global ref
    jmethodID arrayListInit;
    jmethodID arrayListAdd;
};

static fields_t fields;
static Mutex sLock;
static const char* const kClassPathName = "android/media/MediaMetadataRetriever";

static void process_media_retriever_call(JNIEnv *env, status_t opStatus, const char* exception, const char *message)
{
    if (opStatus == (status_t) INVALID_OPERATION) {
        jniThrowException(env, "java/lang/IllegalStateException", NULL);
    } else if (opStatus != (status_t) OK) {
        if (strlen(message) > 230) {
            // If the message is too long, don't bother displaying the status code.
            jniThrowException( env, exception, message);
        } else {
            char msg[256];
            // Append the status code to the message.
            sprintf(msg, "%s: status = 0x%X", message, opStatus);
            jniThrowException( env, exception, msg);
        }
    }
}

static sp<MediaMetadataRetriever> getRetriever(JNIEnv* env, jobject thiz)
{
    // No lock is needed, since it is called internally by other methods that are protected
    MediaMetadataRetriever* retriever = (MediaMetadataRetriever*) env->GetLongField(thiz, fields.context);
    return retriever;
}

static void setRetriever(JNIEnv* env, jobject thiz, const sp<MediaMetadataRetriever> &retriever)
{
    // No lock is needed, since it is called internally by other methods that are protected

    if (retriever != NULL) {
        retriever->incStrong(thiz);
    }
    sp<MediaMetadataRetriever> old = getRetriever(env, thiz);
    if (old != NULL) {
        old->decStrong(thiz);
    }

    env->SetLongField(thiz, fields.context, (jlong) retriever.get());
}

static void
android_media_MediaMetadataRetriever_setDataSourceAndHeaders(
        JNIEnv *env, jobject thiz, jobject httpServiceBinderObj, jstring path,
        jobjectArray keys, jobjectArray values) {

    ALOGV("setDataSource");
    sp<MediaMetadataRetriever> retriever = getRetriever(env, thiz);
    if (retriever == 0) {
        jniThrowException(
                env,
                "java/lang/IllegalStateException", "No retriever available");

        return;
    }

    if (!path) {
        jniThrowException(
                env, "java/lang/IllegalArgumentException", "Null pointer");

        return;
    }

    const char *tmp = env->GetStringUTFChars(path, NULL);
    if (!tmp) {  // OutOfMemoryError exception already thrown
        return;
    }

    String8 pathStr(tmp);
    env->ReleaseStringUTFChars(path, tmp);
    tmp = NULL;

    // Don't let somebody trick us in to reading some random block of memory
    if (strncmp("mem://", pathStr.string(), 6) == 0) {
        jniThrowException(
                env, "java/lang/IllegalArgumentException", "Invalid pathname");
        return;
    }

    // We build a similar KeyedVector out of it.
    KeyedVector<String8, String8> headersVector;
    if (!ConvertKeyValueArraysToKeyedVector(
            env, keys, values, &headersVector)) {
        return;
    }

    sp<IMediaHTTPService> httpService;
    if (httpServiceBinderObj != NULL) {
        sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
        httpService = interface_cast<IMediaHTTPService>(binder);
    }

    process_media_retriever_call(
            env,
            retriever->setDataSource(
                httpService,
                pathStr.string(),
                headersVector.size() > 0 ? &headersVector : NULL),

            "java/lang/RuntimeException",
            "setDataSource failed");
}

static void android_media_MediaMetadataRetriever_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
{
    ALOGV("setDataSource");
    sp<MediaMetadataRetriever> retriever = getRetriever(env, thiz);
    if (retriever == 0) {
        jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
        return;
    }
    if (!fileDescriptor) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return;
    }
    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
    if (offset < 0 || length < 0 || fd < 0) {
        if (offset < 0) {
            ALOGE("negative offset (%lld)", (long long)offset);
        }
        if (length < 0) {
            ALOGE("negative length (%lld)", (long long)length);
        }
        if (fd < 0) {
            ALOGE("invalid file descriptor");
        }
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return;
    }
    process_media_retriever_call(env, retriever->setDataSource(fd, offset, length), "java/lang/RuntimeException", "setDataSource failed");
}

static void android_media_MediaMetadataRetriever_setDataSourceCallback(JNIEnv *env, jobject thiz, jobject dataSource)
{
    ALOGV("setDataSourceCallback");
    sp<MediaMetadataRetriever> retriever = getRetriever(env, thiz);
    if (retriever == 0) {
        jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
        return;
    }
    if (dataSource == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return;
    }

    sp<IDataSource> callbackDataSource = new JMediaDataSource(env, dataSource);
    process_media_retriever_call(env, retriever->setDataSource(callbackDataSource), "java/lang/RuntimeException", "setDataSourceCallback failed");
}

template<typename T>
static void rotate0(T* dst, const T* src, size_t width, size_t height)
{
    memcpy(dst, src, width * height * sizeof(T));
}

template<typename T>
static void rotate90(T* dst, const T* src, size_t width, size_t height)
{
    for (size_t i = 0; i < height; ++i) {
        for (size_t j = 0; j < width; ++j) {
            dst[j * height + height - 1 - i] = src[i * width + j];
        }
    }
}

template<typename T>
static void rotate180(T* dst, const T* src, size_t width, size_t height)
{
    for (size_t i = 0; i < height; ++i) {
        for (size_t j = 0; j < width; ++j) {
            dst[(height - 1 - i) * width + width - 1 - j] = src[i * width + j];
        }
    }
}

template<typename T>
static void rotate270(T* dst, const T* src, size_t width, size_t height)
{
    for (size_t i = 0; i < height; ++i) {
        for (size_t j = 0; j < width; ++j) {
            dst[(width - 1 - j) * height + i] = src[i * width + j];
        }
    }
}

template<typename T>
static void rotate(T *dst, const T *src, size_t width, size_t height, int angle)
{
    switch (angle) {
        case 0:
            rotate0(dst, src, width, height);
            break;
        case 90:
            rotate90(dst, src, width, height);
            break;
        case 180:
            rotate180(dst, src, width, height);
            break;
        case 270:
            rotate270(dst, src, width, height);
            break;
    }
}

static jobject getBitmapFromVideoFrame(
        JNIEnv *env, VideoFrame *videoFrame, jint dst_width, jint dst_height,
        AndroidBitmapFormat outColorType) {
    ALOGV("getBitmapFromVideoFrame: dimension = %dx%d, displaySize = %dx%d, bytes = %d",
            videoFrame->mWidth,
            videoFrame->mHeight,
            videoFrame->mDisplayWidth,
            videoFrame->mDisplayHeight,
            videoFrame->mSize);

    ScopedLocalRef<jobject> config(env, ABitmapConfig_getConfigFromFormat(env, outColorType));

    uint32_t width, height, displayWidth, displayHeight;
    bool swapWidthAndHeight = false;
    if (videoFrame->mRotationAngle == 90 || videoFrame->mRotationAngle == 270) {
        width = videoFrame->mHeight;
        height = videoFrame->mWidth;
        swapWidthAndHeight = true;
        displayWidth = videoFrame->mDisplayHeight;
        displayHeight = videoFrame->mDisplayWidth;
    } else {
        width = videoFrame->mWidth;
        height = videoFrame->mHeight;
        displayWidth = videoFrame->mDisplayWidth;
        displayHeight = videoFrame->mDisplayHeight;
    }

    jobject jBitmap = env->CallStaticObjectMethod(
                            fields.bitmapClazz,
                            fields.createBitmapMethod,
                            width,
                            height,
                            config.get());
    if (jBitmap == NULL) {
        if (env->ExceptionCheck()) {
            env->ExceptionClear();
        }
        ALOGE("getBitmapFromVideoFrame: create Bitmap failed!");
        return NULL;
    }

    graphics::Bitmap bitmap(env, jBitmap);

    if (outColorType == ANDROID_BITMAP_FORMAT_RGB_565) {
        rotate((uint16_t*)bitmap.getPixels(),
               (uint16_t*)((char*)videoFrame + sizeof(VideoFrame)),
               videoFrame->mWidth,
               videoFrame->mHeight,
               videoFrame->mRotationAngle);
    } else {
        rotate((uint32_t*)bitmap.getPixels(),
               (uint32_t*)((char*)videoFrame + sizeof(VideoFrame)),
               videoFrame->mWidth,
               videoFrame->mHeight,
               videoFrame->mRotationAngle);
    }

    if (dst_width <= 0 || dst_height <= 0) {
        dst_width = displayWidth;
        dst_height = displayHeight;
    } else {
        float factor = std::min((float)dst_width / (float)displayWidth,
                (float)dst_height / (float)displayHeight);
        dst_width = std::round(displayWidth * factor);
        dst_height = std::round(displayHeight * factor);
    }

    if ((uint32_t)dst_width != width || (uint32_t)dst_height != height) {
        ALOGV("Bitmap dimension is scaled from %dx%d to %dx%d",
                width, height, dst_width, dst_height);
        jobject scaledBitmap = env->CallStaticObjectMethod(fields.bitmapClazz,
                                fields.createScaledBitmapMethod,
                                jBitmap,
                                dst_width,
                                dst_height,
                                true);

        env->DeleteLocalRef(jBitmap);
        return scaledBitmap;
    }

    return jBitmap;
}

static AndroidBitmapFormat getColorFormat(JNIEnv *env, jobject options,
        AndroidBitmapFormat defaultPreferred = ANDROID_BITMAP_FORMAT_RGBA_8888) {
    if (options == NULL) {
        return defaultPreferred;
    }

    ScopedLocalRef<jobject> inConfig(env, env->GetObjectField(options, fields.inPreferredConfig));
    AndroidBitmapFormat format = ABitmapConfig_getFormatFromConfig(env, inConfig.get());

    if (format == ANDROID_BITMAP_FORMAT_RGB_565) {
        return ANDROID_BITMAP_FORMAT_RGB_565;
    }
    return ANDROID_BITMAP_FORMAT_RGBA_8888;
}

static void setOutConfig(JNIEnv *env, jobject options, AndroidBitmapFormat colorFormat) {
    if (options != NULL) {
        ScopedLocalRef<jobject> config(env, ABitmapConfig_getConfigFromFormat(env, colorFormat));
        env->SetObjectField(options, fields.outActualConfig, config.get());
    }
}

static jobject android_media_MediaMetadataRetriever_getFrameAtTime(
        JNIEnv *env, jobject thiz, jlong timeUs, jint option,
        jint dst_width, jint dst_height, jobject params)
{
    ALOGV("getFrameAtTime: %lld us option: %d dst width: %d heigh: %d",
            (long long)timeUs, option, dst_width, dst_height);
    sp<MediaMetadataRetriever> retriever = getRetriever(env, thiz);
    if (retriever == 0) {
        jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
        return NULL;
    }
    // For getFrameAtTime family of calls, default to ANDROID_BITMAP_FORMAT_RGB_565
    // to keep the behavior consistent with older releases
    AndroidBitmapFormat colorFormat = getColorFormat(env, params, ANDROID_BITMAP_FORMAT_RGB_565);

    // Call native method to retrieve a video frame
    VideoFrame *videoFrame = NULL;
    sp<IMemory> frameMemory = retriever->getFrameAtTime(timeUs, option, colorFormat);
    // TODO: Using unsecurePointer() has some associated security pitfalls
    //       (see declaration for details).
    //       Either document why it is safe in this case or address the
    //       issue (e.g. by copying).
    if (frameMemory != 0) {  // cast the shared structure to a VideoFrame object
        videoFrame = static_cast<VideoFrame *>(frameMemory->unsecurePointer());
    }
    if (videoFrame == NULL) {
        ALOGE("getFrameAtTime: videoFrame is a NULL pointer");
        return NULL;
    }

    setOutConfig(env, params, colorFormat);
    return getBitmapFromVideoFrame(env, videoFrame, dst_width, dst_height, colorFormat);
}

static jobject android_media_MediaMetadataRetriever_getImageAtIndex(
        JNIEnv *env, jobject thiz, jint index, jobject params)
{
    ALOGV("getImageAtIndex: index %d", index);
    sp<MediaMetadataRetriever> retriever = getRetriever(env, thiz);
    if (retriever == 0) {
        jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
        return NULL;
    }

    AndroidBitmapFormat colorFormat = getColorFormat(env, params);

    // Call native method to retrieve an image
    VideoFrame *videoFrame = NULL;
    sp<IMemory> frameMemory = retriever->getImageAtIndex(index, colorFormat);
    if (frameMemory != 0) {  // cast the shared structure to a VideoFrame object
        // TODO: Using unsecurePointer() has some associated security pitfalls
        //       (see declaration for details).
        //       Either document why it is safe in this case or address the
        //       issue (e.g. by copying).
        videoFrame = static_cast<VideoFrame *>(frameMemory->unsecurePointer());
    }
    if (videoFrame == NULL) {
        ALOGE("getImageAtIndex: videoFrame is a NULL pointer");
        return NULL;
    }

    setOutConfig(env, params, colorFormat);
    return getBitmapFromVideoFrame(env, videoFrame, -1, -1, colorFormat);
}

static jobject android_media_MediaMetadataRetriever_getThumbnailImageAtIndex(
        JNIEnv *env, jobject thiz, jint index, jobject params, jint targetSize, jint maxPixels)
{
    ALOGV("getThumbnailImageAtIndex: index %d", index);

    sp<MediaMetadataRetriever> retriever = getRetriever(env, thiz);
    if (retriever == 0) {
        jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
        return NULL;
    }

    AndroidBitmapFormat colorFormat = getColorFormat(env, params);
    jint dst_width = -1, dst_height = -1;

    // Call native method to retrieve an image
    VideoFrame *videoFrame = NULL;
    sp<IMemory> frameMemory = retriever->getImageAtIndex(
            index, colorFormat, true /*metaOnly*/, true /*thumbnail*/);
    if (frameMemory != 0) {
        // TODO: Using unsecurePointer() has some associated security pitfalls
        //       (see declaration for details).
        //       Either document why it is safe in this case or address the
        //       issue (e.g. by copying).
        videoFrame = static_cast<VideoFrame *>(frameMemory->unsecurePointer());
        int32_t thumbWidth = videoFrame->mWidth;
        int32_t thumbHeight = videoFrame->mHeight;
        videoFrame = NULL;
        int64_t thumbPixels = thumbWidth * thumbHeight;

        // Here we try to use the included thumbnail if it's not too shabby.
        // If this fails ThumbnailUtils would have to decode the full image and
        // downscale which could take long.
        if (thumbWidth >= targetSize || thumbHeight >= targetSize
                || thumbPixels * 6 >= maxPixels) {
            frameMemory = retriever->getImageAtIndex(
                    index, colorFormat, false /*metaOnly*/, true /*thumbnail*/);
            if (frameMemory != 0) {
                // TODO: Using unsecurePointer() has some associated security pitfalls
                //       (see declaration for details).
                //       Either document why it is safe in this case or address the
                //       issue (e.g. by copying).
                videoFrame = static_cast<VideoFrame *>(frameMemory->unsecurePointer());
            }

            if (thumbPixels > maxPixels) {
                int downscale = ceil(sqrt(thumbPixels / (float)maxPixels));
                dst_width = thumbWidth / downscale;
                dst_height = thumbHeight /downscale;
            }
        }
    }
    if (videoFrame == NULL) {
        ALOGV("getThumbnailImageAtIndex: no suitable thumbnails available");
        return NULL;
    }

    // Ignore rotation for thumbnail extraction to be consistent with
    // thumbnails extracted by BitmapFactory APIs.
    videoFrame->mRotationAngle = 0;

    setOutConfig(env, params, colorFormat);
    return getBitmapFromVideoFrame(env, videoFrame, dst_width, dst_height, colorFormat);
}

static jobject android_media_MediaMetadataRetriever_getFrameAtIndex(
        JNIEnv *env, jobject thiz, jint frameIndex, jint numFrames, jobject params)
{
    ALOGV("getFrameAtIndex: frameIndex %d, numFrames %d", frameIndex, numFrames);
    sp<MediaMetadataRetriever> retriever = getRetriever(env, thiz);
    if (retriever == 0) {
        jniThrowException(env,
                "java/lang/IllegalStateException", "No retriever available");
        return NULL;
    }


    jobject arrayList = env->NewObject(fields.arrayListClazz, fields.arrayListInit);
    if (arrayList == NULL) {
        jniThrowException(env,
                "java/lang/IllegalStateException", "Can't create bitmap array");
        return NULL;
    }

    AndroidBitmapFormat colorFormat = getColorFormat(env, params);
    setOutConfig(env, params, colorFormat);
    size_t i = 0;
    for (; i < numFrames; i++) {
        sp<IMemory> frame = retriever->getFrameAtIndex(frameIndex + i, colorFormat);
        if (frame == NULL || frame->unsecurePointer() == NULL) {
            ALOGE("video frame at index %zu is a NULL pointer", frameIndex + i);
            break;
        }
        // TODO: Using unsecurePointer() has some associated security pitfalls
        //       (see declaration for details).
        //       Either document why it is safe in this case or address the
        //       issue (e.g. by copying).
        VideoFrame *videoFrame = static_cast<VideoFrame *>(frame->unsecurePointer());
        jobject bitmapObj = getBitmapFromVideoFrame(env, videoFrame, -1, -1, colorFormat);
        env->CallBooleanMethod(arrayList, fields.arrayListAdd, bitmapObj);
        env->DeleteLocalRef(bitmapObj);
    }

    if (i == 0) {
        env->DeleteLocalRef(arrayList);

        jniThrowException(env,
                "java/lang/IllegalStateException", "No frames from retriever");
        return NULL;
    }

    return arrayList;
}

static jbyteArray android_media_MediaMetadataRetriever_getEmbeddedPicture(
        JNIEnv *env, jobject thiz, jint pictureType)
{
    ALOGV("getEmbeddedPicture: %d", pictureType);
    sp<MediaMetadataRetriever> retriever = getRetriever(env, thiz);
    if (retriever == 0) {
        jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
        return NULL;
    }
    MediaAlbumArt* mediaAlbumArt = NULL;

    // FIXME:
    // Use pictureType to retrieve the intended embedded picture and also change
    // the method name to getEmbeddedPicture().
    sp<IMemory> albumArtMemory = retriever->extractAlbumArt();
    if (albumArtMemory != 0) {  // cast the shared structure to a MediaAlbumArt object
        // TODO: Using unsecurePointer() has some associated security pitfalls
        //       (see declaration for details).
        //       Either document why it is safe in this case or address the
        //       issue (e.g. by copying).
        mediaAlbumArt = static_cast<MediaAlbumArt *>(albumArtMemory->unsecurePointer());
    }
    if (mediaAlbumArt == NULL) {
        ALOGE("getEmbeddedPicture: Call to getEmbeddedPicture failed.");
        return NULL;
    }

    jbyteArray array = env->NewByteArray(mediaAlbumArt->size());
    if (!array) {  // OutOfMemoryError exception has already been thrown.
        ALOGE("getEmbeddedPicture: OutOfMemoryError is thrown.");
    } else {
        const jbyte* data =
                reinterpret_cast<const jbyte*>(mediaAlbumArt->data());
        env->SetByteArrayRegion(array, 0, mediaAlbumArt->size(), data);
    }

    // No need to delete mediaAlbumArt here
    return array;
}

static jobject android_media_MediaMetadataRetriever_extractMetadata(JNIEnv *env, jobject thiz, jint keyCode)
{
    ALOGV("extractMetadata");
    sp<MediaMetadataRetriever> retriever = getRetriever(env, thiz);
    if (retriever == 0) {
        jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
        return NULL;
    }
    const char* value = retriever->extractMetadata(keyCode);
    if (!value) {
        ALOGV("extractMetadata: Metadata is not found");
        return NULL;
    }
    ALOGV("extractMetadata: value (%s) for keyCode(%d)", value, keyCode);
    return env->NewStringUTF(value);
}

static void android_media_MediaMetadataRetriever_release(JNIEnv *env, jobject thiz)
{
    ALOGV("release");
    Mutex::Autolock lock(sLock);
    setRetriever(env, thiz, NULL);
}

static void android_media_MediaMetadataRetriever_native_finalize(JNIEnv *env, jobject thiz)
{
    ALOGV("native_finalize");
    // No lock is needed, since android_media_MediaMetadataRetriever_release() is protected
    android_media_MediaMetadataRetriever_release(env, thiz);
}

// This function gets a field ID, which in turn causes class initialization.
// It is called from a static block in MediaMetadataRetriever, which won't run until the
// first time an instance of this class is used.
static void android_media_MediaMetadataRetriever_native_init(JNIEnv *env)
{
    ScopedLocalRef<jclass> clazz(env, env->FindClass(kClassPathName));
    if (clazz.get() == NULL) {
        return;
    }

    fields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J");
    if (fields.context == NULL) {
        return;
    }

    clazz.reset(env->FindClass("android/graphics/Bitmap"));
    if (clazz.get() == NULL) {
        return;
    }
    fields.bitmapClazz = (jclass) env->NewGlobalRef(clazz.get());
    if (fields.bitmapClazz == NULL) {
        return;
    }
    fields.createBitmapMethod =
            env->GetStaticMethodID(fields.bitmapClazz, "createBitmap",
                    "(IILandroid/graphics/Bitmap$Config;)"
                    "Landroid/graphics/Bitmap;");
    if (fields.createBitmapMethod == NULL) {
        return;
    }
    fields.createScaledBitmapMethod =
            env->GetStaticMethodID(fields.bitmapClazz, "createScaledBitmap",
                    "(Landroid/graphics/Bitmap;IIZ)"
                    "Landroid/graphics/Bitmap;");
    if (fields.createScaledBitmapMethod == NULL) {
        return;
    }

    clazz.reset(env->FindClass("android/media/MediaMetadataRetriever$BitmapParams"));
    if (clazz.get() == NULL) {
        return;
    }
    fields.bitmapParamsClazz = (jclass) env->NewGlobalRef(clazz.get());
    if (fields.bitmapParamsClazz == NULL) {
        return;
    }
    fields.inPreferredConfig = env->GetFieldID(fields.bitmapParamsClazz,
            "inPreferredConfig", "Landroid/graphics/Bitmap$Config;");
    if (fields.inPreferredConfig == NULL) {
        return;
    }
    fields.outActualConfig = env->GetFieldID(fields.bitmapParamsClazz,
            "outActualConfig", "Landroid/graphics/Bitmap$Config;");
    if (fields.outActualConfig == NULL) {
        return;
    }

    clazz.reset(env->FindClass("java/util/ArrayList"));
    if (clazz.get() == NULL) {
        return;
    }
    fields.arrayListClazz = (jclass) env->NewGlobalRef(clazz.get());
    if (fields.arrayListClazz == NULL) {
        return;
    }
    fields.arrayListInit = env->GetMethodID(clazz.get(), "<init>", "()V");
    if (fields.arrayListInit == NULL) {
        return;
    }
    fields.arrayListAdd = env->GetMethodID(clazz.get(), "add", "(Ljava/lang/Object;)Z");
    if (fields.arrayListAdd == NULL) {
        return;
    }
}

static void android_media_MediaMetadataRetriever_native_setup(JNIEnv *env, jobject thiz)
{
    ALOGV("native_setup");
    sp<MediaMetadataRetriever> retriever = new MediaMetadataRetriever();
    if (retriever == 0) {
        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
        return;
    }
    setRetriever(env, thiz, retriever);
}

// JNI mapping between Java methods and native methods
static const JNINativeMethod nativeMethods[] = {
        {
            "_setDataSource",
            "(Landroid/os/IBinder;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
            (void *)android_media_MediaMetadataRetriever_setDataSourceAndHeaders
        },

        {"_setDataSource",   "(Ljava/io/FileDescriptor;JJ)V",
                (void *)android_media_MediaMetadataRetriever_setDataSourceFD},
        {"_setDataSource",   "(Landroid/media/MediaDataSource;)V",
                (void *)android_media_MediaMetadataRetriever_setDataSourceCallback},
        {"_getFrameAtTime", "(JIIILandroid/media/MediaMetadataRetriever$BitmapParams;)Landroid/graphics/Bitmap;",
                (void *)android_media_MediaMetadataRetriever_getFrameAtTime},
        {
            "_getImageAtIndex",
            "(ILandroid/media/MediaMetadataRetriever$BitmapParams;)Landroid/graphics/Bitmap;",
            (void *)android_media_MediaMetadataRetriever_getImageAtIndex
        },

        {
            "getThumbnailImageAtIndex",
            "(ILandroid/media/MediaMetadataRetriever$BitmapParams;II)Landroid/graphics/Bitmap;",
            (void *)android_media_MediaMetadataRetriever_getThumbnailImageAtIndex
        },

        {
            "_getFrameAtIndex",
            "(IILandroid/media/MediaMetadataRetriever$BitmapParams;)Ljava/util/List;",
            (void *)android_media_MediaMetadataRetriever_getFrameAtIndex
        },

        {"nativeExtractMetadata", "(I)Ljava/lang/String;",
                (void *)android_media_MediaMetadataRetriever_extractMetadata},
        {"getEmbeddedPicture", "(I)[B",
                (void *)android_media_MediaMetadataRetriever_getEmbeddedPicture},
        {"release",         "()V",
                (void *)android_media_MediaMetadataRetriever_release},
        {"native_finalize", "()V",
                (void *)android_media_MediaMetadataRetriever_native_finalize},
        {"native_setup",    "()V",
                (void *)android_media_MediaMetadataRetriever_native_setup},
        {"native_init",     "()V",
                (void *)android_media_MediaMetadataRetriever_native_init},
};

// This function only registers the native methods, and is called from
// JNI_OnLoad in android_media_MediaPlayer.cpp
int register_android_media_MediaMetadataRetriever(JNIEnv *env)
{
    return AndroidRuntime::registerNativeMethods
        (env, kClassPathName, nativeMethods, NELEM(nativeMethods));
}
