Merge "A little cleanup in MediaScanner JNI code"
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user