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

Commit d96d1be7 authored by James Dong's avatar James Dong Committed by Android (Google) Code Review
Browse files

Merge "A little cleanup in MediaScanner JNI code"

parents f667740d f3997528
Loading
Loading
Loading
Loading
+169 −89
Original line number Diff line number Diff line
/* //device/libs/media_jni/MediaScanner.cpp
/*
**
** Copyright 2007, The Android Open Source Project
**
@@ -15,36 +15,36 @@
** limitations under the License.
*/

#define LOG_TAG "MediaScanner"
#include "utils/Log.h"

#include <media/mediascanner.h>
#include <stdio.h>
#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <cutils/properties.h>
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaScannerJNI"
#include <utils/Log.h>
#include <utils/threads.h>
#include <media/mediascanner.h>
#include <media/stagefright/StagefrightMediaScanner.h>

#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"

#include <media/stagefright/StagefrightMediaScanner.h>

// ----------------------------------------------------------------------------

using namespace android;

// ----------------------------------------------------------------------------

struct fields_t {
    jfieldID    context;
};
static fields_t fields;

// ----------------------------------------------------------------------------
static const char* const kClassMediaScannerClient =
        "android/media/MediaScannerClient";

static const char* const kClassMediaScanner =
        "android/media/MediaScanner";

static const char* const kRunTimeException =
        "java/lang/RuntimeException";

static const char* const kIllegalArgumentException =
        "java/lang/IllegalArgumentException";

class MyMediaScannerClient : public MediaScannerClient
{
@@ -56,33 +56,53 @@ public:
            mHandleStringTagMethodID(0),
            mSetMimeTypeMethodID(0)
    {
        jclass mediaScannerClientInterface = env->FindClass("android/media/MediaScannerClient");
        LOGV("MyMediaScannerClient constructor");
        jclass mediaScannerClientInterface =
                env->FindClass(kClassMediaScannerClient);

        if (mediaScannerClientInterface == NULL) {
            fprintf(stderr, "android/media/MediaScannerClient not found\n");
        }
        else {
            mScanFileMethodID = env->GetMethodID(mediaScannerClientInterface, "scanFile",
            LOGE("Class %s not found", kClassMediaScannerClient);
        } else {
            mScanFileMethodID = env->GetMethodID(
                                    mediaScannerClientInterface,
                                    "scanFile",
                                    "(Ljava/lang/String;JJZ)V");
            mHandleStringTagMethodID = env->GetMethodID(mediaScannerClientInterface, "handleStringTag",

            mHandleStringTagMethodID = env->GetMethodID(
                                    mediaScannerClientInterface,
                                    "handleStringTag",
                                    "(Ljava/lang/String;Ljava/lang/String;)V");
            mSetMimeTypeMethodID = env->GetMethodID(mediaScannerClientInterface, "setMimeType",

            mSetMimeTypeMethodID = env->GetMethodID(
                                    mediaScannerClientInterface,
                                    "setMimeType",
                                    "(Ljava/lang/String;)V");
            mAddNoMediaFolderMethodID = env->GetMethodID(mediaScannerClientInterface, "addNoMediaFolder",

            mAddNoMediaFolderMethodID = env->GetMethodID(
                                    mediaScannerClientInterface,
                                    "addNoMediaFolder",
                                    "(Ljava/lang/String;)V");
        }
    }

    virtual ~MyMediaScannerClient()
    {
        LOGV("MyMediaScannerClient destructor");
        mEnv->DeleteGlobalRef(mClient);
    }

    // returns true if it succeeded, false if an exception occured in the Java code
    // Returns true if it succeeded, false if an exception occured
    // in the Java code
    virtual bool scanFile(const char* path, long long lastModified,
            long long fileSize, bool isDirectory)
    {
        LOGV("scanFile: path(%s), time(%lld), size(%lld) and isDir(%d)",
            path, lastModified, fileSize, isDirectory);

        jstring pathStr;
        if ((pathStr = mEnv->NewStringUTF(path)) == NULL) return false;
        if ((pathStr = mEnv->NewStringUTF(path)) == NULL) {
            return false;
        }

        mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified,
                fileSize, isDirectory);
@@ -91,25 +111,36 @@ public:
        return (!mEnv->ExceptionCheck());
    }

    // returns true if it succeeded, false if an exception occured in the Java code
    // Returns true if it succeeded, false if an exception occured
    // in the Java code
    virtual bool handleStringTag(const char* name, const char* value)
    {
        LOGV("handleStringTag: name(%s) and value(%s)", name, value);
        jstring nameStr, valueStr;
        if ((nameStr = mEnv->NewStringUTF(name)) == NULL) return false;
        if ((valueStr = mEnv->NewStringUTF(value)) == NULL) return false;
        if ((nameStr = mEnv->NewStringUTF(name)) == NULL) {
            return false;
        }
        if ((valueStr = mEnv->NewStringUTF(value)) == NULL) {
            return false;
        }

        mEnv->CallVoidMethod(mClient, mHandleStringTagMethodID, nameStr, valueStr);
        mEnv->CallVoidMethod(
            mClient, mHandleStringTagMethodID, nameStr, valueStr);

        mEnv->DeleteLocalRef(nameStr);
        mEnv->DeleteLocalRef(valueStr);
        return (!mEnv->ExceptionCheck());
    }

    // returns true if it succeeded, false if an exception occured in the Java code
    // Returns true if it succeeded, false if an exception occured
    // in the Java code
    virtual bool setMimeType(const char* mimeType)
    {
        LOGV("setMimeType: %s", mimeType);
        jstring mimeTypeStr;
        if ((mimeTypeStr = mEnv->NewStringUTF(mimeType)) == NULL) return false;
        if ((mimeTypeStr = mEnv->NewStringUTF(mimeType)) == NULL) {
            return false;
        }

        mEnv->CallVoidMethod(mClient, mSetMimeTypeMethodID, mimeTypeStr);

@@ -117,11 +148,15 @@ public:
        return (!mEnv->ExceptionCheck());
    }

    // returns true if it succeeded, false if an exception occured in the Java code
    // Returns true if it succeeded, false if an exception occured
    // in the Java code
    virtual bool addNoMediaFolder(const char* path)
    {
        LOGV("addNoMediaFolder: path(%s)", path);
        jstring pathStr;
        if ((pathStr = mEnv->NewStringUTF(path)) == NULL) return false;
        if ((pathStr = mEnv->NewStringUTF(path)) == NULL) {
            return false;
        }

        mEnv->CallVoidMethod(mClient, mAddNoMediaFolderMethodID, pathStr);

@@ -140,26 +175,28 @@ private:
};


// ----------------------------------------------------------------------------

static bool ExceptionCheck(void* env)
{
    LOGV("ExceptionCheck");
    return ((JNIEnv *)env)->ExceptionCheck();
}

static void
android_media_MediaScanner_processDirectory(JNIEnv *env, jobject thiz, jstring path, jobject client)
android_media_MediaScanner_processDirectory(
        JNIEnv *env, jobject thiz, jstring path, jobject client)
{
    MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz, fields.context);
    LOGV("processDirectory");
    MediaScanner *mp =
        (MediaScanner *)env->GetIntField(thiz, fields.context);

    if (path == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        jniThrowException(env, kIllegalArgumentException, NULL);
        return;
    }

    const char *pathStr = env->GetStringUTFChars(path, NULL);
    if (pathStr == NULL) {  // Out of memory
        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
        jniThrowException(env, kRunTimeException, "Out of memory");
        return;
    }

@@ -169,24 +206,30 @@ android_media_MediaScanner_processDirectory(JNIEnv *env, jobject thiz, jstring p
}

static void
android_media_MediaScanner_processFile(JNIEnv *env, jobject thiz, jstring path, jstring mimeType, jobject client)
android_media_MediaScanner_processFile(
        JNIEnv *env, jobject thiz, jstring path,
        jstring mimeType, jobject client)
{
    MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz, fields.context);
    LOGV("processFile");
    MediaScanner *mp =
        (MediaScanner *)env->GetIntField(thiz, fields.context);

    if (path == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        jniThrowException(env, kIllegalArgumentException, NULL);
        return;
    }

    const char *pathStr = env->GetStringUTFChars(path, NULL);
    if (pathStr == NULL) {  // Out of memory
        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
        jniThrowException(env, kRunTimeException, "Out of memory");
        return;
    }
    const char *mimeTypeStr = (mimeType ? env->GetStringUTFChars(mimeType, NULL) : NULL);

    const char *mimeTypeStr =
        (mimeType ? env->GetStringUTFChars(mimeType, NULL) : NULL);
    if (mimeType && mimeTypeStr == NULL) {  // Out of memory
        env->ReleaseStringUTFChars(path, pathStr);
        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
        jniThrowException(env, kRunTimeException, "Out of memory");
        return;
    }

@@ -199,17 +242,20 @@ android_media_MediaScanner_processFile(JNIEnv *env, jobject thiz, jstring path,
}

static void
android_media_MediaScanner_setLocale(JNIEnv *env, jobject thiz, jstring locale)
android_media_MediaScanner_setLocale(
        JNIEnv *env, jobject thiz, jstring locale)
{
    MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz, fields.context);
    LOGV("setLocale");
    MediaScanner *mp =
        (MediaScanner *)env->GetIntField(thiz, fields.context);

    if (locale == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        jniThrowException(env, kIllegalArgumentException, NULL);
        return;
    }
    const char *localeStr = env->GetStringUTFChars(locale, NULL);
    if (localeStr == NULL) {  // Out of memory
        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
        jniThrowException(env, kRunTimeException, "Out of memory");
        return;
    }
    mp->setLocale(localeStr);
@@ -218,12 +264,15 @@ android_media_MediaScanner_setLocale(JNIEnv *env, jobject thiz, jstring locale)
}

static jbyteArray
android_media_MediaScanner_extractAlbumArt(JNIEnv *env, jobject thiz, jobject fileDescriptor)
android_media_MediaScanner_extractAlbumArt(
        JNIEnv *env, jobject thiz, jobject fileDescriptor)
{
    MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz, fields.context);
    LOGV("extractAlbumArt");
    MediaScanner *mp =
        (MediaScanner *)env->GetIntField(thiz, fields.context);

    if (fileDescriptor == NULL) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        jniThrowException(env, kIllegalArgumentException, NULL);
        return NULL;
    }

@@ -256,17 +305,18 @@ done:
static void
android_media_MediaScanner_native_init(JNIEnv *env)
{
     jclass clazz;

    clazz = env->FindClass("android/media/MediaScanner");
    LOGV("native_init");
    jclass clazz = env->FindClass(kClassMediaScanner);
    if (clazz == NULL) {
        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaScanner");
        const char* err = "Can't find android/media/MediaScanner";
        jniThrowException(env, kRunTimeException, err);
        return;
    }

    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
    if (fields.context == NULL) {
        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaScanner.mNativeContext");
        const char* err = "Can't find MediaScanner.mNativeContext";
        jniThrowException(env, kRunTimeException, err);
        return;
    }
}
@@ -274,10 +324,11 @@ android_media_MediaScanner_native_init(JNIEnv *env)
static void
android_media_MediaScanner_native_setup(JNIEnv *env, jobject thiz)
{
    LOGV("native_setup");
    MediaScanner *mp = new StagefrightMediaScanner;

    if (mp == NULL) {
        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
        jniThrowException(env, kRunTimeException, "Out of memory");
        return;
    }

@@ -287,38 +338,67 @@ android_media_MediaScanner_native_setup(JNIEnv *env, jobject thiz)
static void
android_media_MediaScanner_native_finalize(JNIEnv *env, jobject thiz)
{
    MediaScanner *mp = (MediaScanner *)env->GetIntField(thiz, fields.context);
    LOGV("native_finalize");
    MediaScanner *mp =
        (MediaScanner *)env->GetIntField(thiz, fields.context);

    //printf("##### android_media_MediaScanner_native_finalize: ctx=0x%p\n", ctx);

    if (mp == 0)
    if (mp == 0) {
        return;
    }

    delete mp;
}

// ----------------------------------------------------------------------------

static JNINativeMethod gMethods[] = {
    {"processDirectory",  "(Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
                                                        (void *)android_media_MediaScanner_processDirectory},
    {"processFile",       "(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
                                                        (void *)android_media_MediaScanner_processFile},
    {"setLocale",         "(Ljava/lang/String;)V",      (void *)android_media_MediaScanner_setLocale},
    {"extractAlbumArt",   "(Ljava/io/FileDescriptor;)[B",     (void *)android_media_MediaScanner_extractAlbumArt},
    {"native_init",        "()V",                      (void *)android_media_MediaScanner_native_init},
    {"native_setup",        "()V",                      (void *)android_media_MediaScanner_native_setup},
    {"native_finalize",     "()V",                      (void *)android_media_MediaScanner_native_finalize},
};
    {
        "processDirectory",
        "(Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
        (void *)android_media_MediaScanner_processDirectory
    },

    {
        "processFile",
        "(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
        (void *)android_media_MediaScanner_processFile
    },

static const char* const kClassPathName = "android/media/MediaScanner";
    {
        "setLocale",
        "(Ljava/lang/String;)V",
        (void *)android_media_MediaScanner_setLocale
    },

    {
        "extractAlbumArt",
        "(Ljava/io/FileDescriptor;)[B",
        (void *)android_media_MediaScanner_extractAlbumArt
    },

    {
        "native_init",
        "()V",
        (void *)android_media_MediaScanner_native_init
    },

    {
        "native_setup",
        "()V",
        (void *)android_media_MediaScanner_native_setup
    },

    {
        "native_finalize",
        "()V",
        (void *)android_media_MediaScanner_native_finalize
    },
};

// This function only registers the native methods, and is called from
// JNI_OnLoad in android_media_MediaPlayer.cpp
int register_android_media_MediaScanner(JNIEnv *env)
{
    return AndroidRuntime::registerNativeMethods(env,
                "android/media/MediaScanner", gMethods, NELEM(gMethods));
                kClassMediaScanner, gMethods, NELEM(gMethods));
}