Merge "A little cleanup in MediaScanner JNI code"

This commit is contained in:
James Dong
2011-03-11 15:15:40 -08:00
committed by Android (Google) Code Review

View File

@@ -1,4 +1,4 @@
/* //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",
"(Ljava/lang/String;JJZ)V");
mHandleStringTagMethodID = env->GetMethodID(mediaScannerClientInterface, "handleStringTag",
"(Ljava/lang/String;Ljava/lang/String;)V");
mSetMimeTypeMethodID = env->GetMethodID(mediaScannerClientInterface, "setMimeType",
"(Ljava/lang/String;)V");
mAddNoMediaFolderMethodID = env->GetMethodID(mediaScannerClientInterface, "addNoMediaFolder",
"(Ljava/lang/String;)V");
LOGE("Class %s not found", kClassMediaScannerClient);
} else {
mScanFileMethodID = env->GetMethodID(
mediaScannerClientInterface,
"scanFile",
"(Ljava/lang/String;JJZ)V");
mHandleStringTagMethodID = env->GetMethodID(
mediaScannerClientInterface,
"handleStringTag",
"(Ljava/lang/String;Ljava/lang/String;)V");
mSetMimeTypeMethodID = env->GetMethodID(
mediaScannerClientInterface,
"setMimeType",
"(Ljava/lang/String;)V");
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);
@@ -133,33 +168,35 @@ public:
private:
JNIEnv *mEnv;
jobject mClient;
jmethodID mScanFileMethodID;
jmethodID mHandleStringTagMethodID;
jmethodID mScanFileMethodID;
jmethodID mHandleStringTagMethodID;
jmethodID mSetMimeTypeMethodID;
jmethodID mAddNoMediaFolderMethodID;
};
// ----------------------------------------------------------------------------
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;
}
@@ -233,14 +282,14 @@ android_media_MediaScanner_extractAlbumArt(JNIEnv *env, jobject thiz, jobject fi
return NULL;
}
long len = *((long*)data);
jbyteArray array = env->NewByteArray(len);
if (array != NULL) {
jbyte* bytes = env->GetByteArrayElements(array, NULL);
memcpy(bytes, data + 4, len);
env->ReleaseByteArrayElements(array, bytes, 0);
}
done:
free(data);
// if NewByteArray() returned NULL, an out-of-memory
@@ -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
},
static const char* const kClassPathName = "android/media/MediaScanner";
{
"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
},
};
// 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));
}