blob: 4e3d14e338109d227431463f2d8bc811d3850633 [file] [log] [blame]
James Dongf3997522011-03-11 12:02:12 -08001/*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002**
3** Copyright 2007, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
James Dongf3997522011-03-11 12:02:12 -080018//#define LOG_NDEBUG 0
19#define LOG_TAG "MediaScannerJNI"
20#include <utils/Log.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021#include <utils/threads.h>
James Dongf3997522011-03-11 12:02:12 -080022#include <media/mediascanner.h>
23#include <media/stagefright/StagefrightMediaScanner.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
25#include "jni.h"
26#include "JNIHelp.h"
27#include "android_runtime/AndroidRuntime.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070028#include "android_runtime/Log.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030using namespace android;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032
James Dongf3997522011-03-11 12:02:12 -080033static const char* const kClassMediaScannerClient =
34 "android/media/MediaScannerClient";
35
36static const char* const kClassMediaScanner =
37 "android/media/MediaScanner";
38
39static const char* const kRunTimeException =
40 "java/lang/RuntimeException";
41
42static const char* const kIllegalArgumentException =
43 "java/lang/IllegalArgumentException";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044
James Dong133cf8b2011-03-11 15:18:40 -080045struct fields_t {
46 jfieldID context;
47};
48static fields_t fields;
James Dong133cf8b2011-03-11 15:18:40 -080049
Jeff Brown2c70d4a2011-07-20 16:38:43 -070050static status_t checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
51 if (env->ExceptionCheck()) {
Steve Blockc6aacce2012-01-06 19:20:56 +000052 ALOGE("An exception was thrown by callback '%s'.", methodName);
Jeff Brown2c70d4a2011-07-20 16:38:43 -070053 LOGE_EX(env);
54 env->ExceptionClear();
55 return UNKNOWN_ERROR;
56 }
57 return OK;
58}
59
Marco Nelissena0a73ed2013-02-12 18:33:41 +000060// stolen from dalvik/vm/checkJni.cpp
61static bool isValidUtf8(const char* bytes) {
62 while (*bytes != '\0') {
63 unsigned char utf8 = *(bytes++);
64 // Switch on the high four bits.
65 switch (utf8 >> 4) {
66 case 0x00:
67 case 0x01:
68 case 0x02:
69 case 0x03:
70 case 0x04:
71 case 0x05:
72 case 0x06:
73 case 0x07:
74 // Bit pattern 0xxx. No need for any extra bytes.
75 break;
76 case 0x08:
77 case 0x09:
78 case 0x0a:
79 case 0x0b:
80 case 0x0f:
81 /*
82 * Bit pattern 10xx or 1111, which are illegal start bytes.
83 * Note: 1111 is valid for normal UTF-8, but not the
84 * modified UTF-8 used here.
85 */
86 return false;
87 case 0x0e:
88 // Bit pattern 1110, so there are two additional bytes.
89 utf8 = *(bytes++);
90 if ((utf8 & 0xc0) != 0x80) {
91 return false;
92 }
93 // Fall through to take care of the final byte.
94 case 0x0c:
95 case 0x0d:
96 // Bit pattern 110x, so there is one additional byte.
97 utf8 = *(bytes++);
98 if ((utf8 & 0xc0) != 0x80) {
99 return false;
100 }
101 break;
102 }
103 }
104 return true;
105}
106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107class MyMediaScannerClient : public MediaScannerClient
108{
109public:
110 MyMediaScannerClient(JNIEnv *env, jobject client)
111 : mEnv(env),
112 mClient(env->NewGlobalRef(client)),
113 mScanFileMethodID(0),
114 mHandleStringTagMethodID(0),
115 mSetMimeTypeMethodID(0)
116 {
Steve Block06ade6a2011-10-20 11:56:00 +0100117 ALOGV("MyMediaScannerClient constructor");
James Dongf3997522011-03-11 12:02:12 -0800118 jclass mediaScannerClientInterface =
119 env->FindClass(kClassMediaScannerClient);
120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 if (mediaScannerClientInterface == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000122 ALOGE("Class %s not found", kClassMediaScannerClient);
James Dongf3997522011-03-11 12:02:12 -0800123 } else {
124 mScanFileMethodID = env->GetMethodID(
125 mediaScannerClientInterface,
126 "scanFile",
Mike Lockwood997354e2011-04-24 11:15:09 -0700127 "(Ljava/lang/String;JJZZ)V");
James Dongf3997522011-03-11 12:02:12 -0800128
129 mHandleStringTagMethodID = env->GetMethodID(
130 mediaScannerClientInterface,
131 "handleStringTag",
132 "(Ljava/lang/String;Ljava/lang/String;)V");
133
134 mSetMimeTypeMethodID = env->GetMethodID(
135 mediaScannerClientInterface,
136 "setMimeType",
137 "(Ljava/lang/String;)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 }
139 }
James Dongf3997522011-03-11 12:02:12 -0800140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 virtual ~MyMediaScannerClient()
142 {
Steve Block06ade6a2011-10-20 11:56:00 +0100143 ALOGV("MyMediaScannerClient destructor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 mEnv->DeleteGlobalRef(mClient);
145 }
James Dongf3997522011-03-11 12:02:12 -0800146
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700147 virtual status_t scanFile(const char* path, long long lastModified,
Mike Lockwood997354e2011-04-24 11:15:09 -0700148 long long fileSize, bool isDirectory, bool noMedia)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 {
Steve Block06ade6a2011-10-20 11:56:00 +0100150 ALOGV("scanFile: path(%s), time(%lld), size(%lld) and isDir(%d)",
James Dongf3997522011-03-11 12:02:12 -0800151 path, lastModified, fileSize, isDirectory);
152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 jstring pathStr;
James Dongf3997522011-03-11 12:02:12 -0800154 if ((pathStr = mEnv->NewStringUTF(path)) == NULL) {
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700155 mEnv->ExceptionClear();
156 return NO_MEMORY;
James Dongf3997522011-03-11 12:02:12 -0800157 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158
Mike Lockwood076e05b2010-12-16 12:54:24 -0800159 mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified,
Mike Lockwood997354e2011-04-24 11:15:09 -0700160 fileSize, isDirectory, noMedia);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161
162 mEnv->DeleteLocalRef(pathStr);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700163 return checkAndClearExceptionFromCallback(mEnv, "scanFile");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 }
165
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700166 virtual status_t handleStringTag(const char* name, const char* value)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 {
Steve Block06ade6a2011-10-20 11:56:00 +0100168 ALOGV("handleStringTag: name(%s) and value(%s)", name, value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 jstring nameStr, valueStr;
James Dongf3997522011-03-11 12:02:12 -0800170 if ((nameStr = mEnv->NewStringUTF(name)) == NULL) {
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700171 mEnv->ExceptionClear();
172 return NO_MEMORY;
James Dongf3997522011-03-11 12:02:12 -0800173 }
Marco Nelissenf51f1bd2011-11-02 10:49:50 -0700174 char *cleaned = NULL;
Marco Nelissena0a73ed2013-02-12 18:33:41 +0000175 if (!isValidUtf8(value)) {
Marco Nelissenf51f1bd2011-11-02 10:49:50 -0700176 cleaned = strdup(value);
177 char *chp = cleaned;
178 char ch;
179 while ((ch = *chp)) {
180 if (ch & 0x80) {
181 *chp = '?';
182 }
183 chp++;
184 }
185 value = cleaned;
186 }
187 valueStr = mEnv->NewStringUTF(value);
188 free(cleaned);
189 if (valueStr == NULL) {
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700190 mEnv->DeleteLocalRef(nameStr);
191 mEnv->ExceptionClear();
192 return NO_MEMORY;
James Dongf3997522011-03-11 12:02:12 -0800193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194
James Dongf3997522011-03-11 12:02:12 -0800195 mEnv->CallVoidMethod(
196 mClient, mHandleStringTagMethodID, nameStr, valueStr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197
198 mEnv->DeleteLocalRef(nameStr);
199 mEnv->DeleteLocalRef(valueStr);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700200 return checkAndClearExceptionFromCallback(mEnv, "handleStringTag");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 }
202
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700203 virtual status_t setMimeType(const char* mimeType)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 {
Steve Block06ade6a2011-10-20 11:56:00 +0100205 ALOGV("setMimeType: %s", mimeType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 jstring mimeTypeStr;
James Dongf3997522011-03-11 12:02:12 -0800207 if ((mimeTypeStr = mEnv->NewStringUTF(mimeType)) == NULL) {
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700208 mEnv->ExceptionClear();
209 return NO_MEMORY;
James Dongf3997522011-03-11 12:02:12 -0800210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211
212 mEnv->CallVoidMethod(mClient, mSetMimeTypeMethodID, mimeTypeStr);
213
214 mEnv->DeleteLocalRef(mimeTypeStr);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700215 return checkAndClearExceptionFromCallback(mEnv, "setMimeType");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 }
217
218private:
219 JNIEnv *mEnv;
220 jobject mClient;
James Dongf3997522011-03-11 12:02:12 -0800221 jmethodID mScanFileMethodID;
222 jmethodID mHandleStringTagMethodID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 jmethodID mSetMimeTypeMethodID;
224};
225
226
James Dong133cf8b2011-03-11 15:18:40 -0800227static MediaScanner *getNativeScanner_l(JNIEnv* env, jobject thiz)
228{
229 return (MediaScanner *) env->GetIntField(thiz, fields.context);
230}
231
James Dong133cf8b2011-03-11 15:18:40 -0800232static void setNativeScanner_l(JNIEnv* env, jobject thiz, MediaScanner *s)
233{
234 env->SetIntField(thiz, fields.context, (int)s);
235}
236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237static void
James Dongf3997522011-03-11 12:02:12 -0800238android_media_MediaScanner_processDirectory(
239 JNIEnv *env, jobject thiz, jstring path, jobject client)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240{
Steve Block06ade6a2011-10-20 11:56:00 +0100241 ALOGV("processDirectory");
James Dong133cf8b2011-03-11 15:18:40 -0800242 MediaScanner *mp = getNativeScanner_l(env, thiz);
243 if (mp == NULL) {
244 jniThrowException(env, kRunTimeException, "No scanner available");
245 return;
246 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247
248 if (path == NULL) {
James Dongf3997522011-03-11 12:02:12 -0800249 jniThrowException(env, kIllegalArgumentException, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 return;
251 }
Mike Lockwoodc37255d2010-09-10 14:47:36 -0400252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 const char *pathStr = env->GetStringUTFChars(path, NULL);
254 if (pathStr == NULL) { // Out of memory
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 return;
256 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257
258 MyMediaScannerClient myClient(env, client);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700259 MediaScanResult result = mp->processDirectory(pathStr, myClient);
260 if (result == MEDIA_SCAN_RESULT_ERROR) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000261 ALOGE("An error occurred while scanning directory '%s'.", pathStr);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700262 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 env->ReleaseStringUTFChars(path, pathStr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264}
265
266static void
James Dongf3997522011-03-11 12:02:12 -0800267android_media_MediaScanner_processFile(
268 JNIEnv *env, jobject thiz, jstring path,
269 jstring mimeType, jobject client)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270{
Steve Block06ade6a2011-10-20 11:56:00 +0100271 ALOGV("processFile");
James Dong133cf8b2011-03-11 15:18:40 -0800272
273 // Lock already hold by processDirectory
274 MediaScanner *mp = getNativeScanner_l(env, thiz);
275 if (mp == NULL) {
276 jniThrowException(env, kRunTimeException, "No scanner available");
277 return;
278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279
280 if (path == NULL) {
James Dongf3997522011-03-11 12:02:12 -0800281 jniThrowException(env, kIllegalArgumentException, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 return;
283 }
James Dongf3997522011-03-11 12:02:12 -0800284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 const char *pathStr = env->GetStringUTFChars(path, NULL);
286 if (pathStr == NULL) { // Out of memory
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287 return;
288 }
James Dongf3997522011-03-11 12:02:12 -0800289
290 const char *mimeTypeStr =
291 (mimeType ? env->GetStringUTFChars(mimeType, NULL) : NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 if (mimeType && mimeTypeStr == NULL) { // Out of memory
James Dongc371a022011-04-06 12:16:07 -0700293 // ReleaseStringUTFChars can be called with an exception pending.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 env->ReleaseStringUTFChars(path, pathStr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 return;
296 }
297
298 MyMediaScannerClient myClient(env, client);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700299 MediaScanResult result = mp->processFile(pathStr, mimeTypeStr, myClient);
300 if (result == MEDIA_SCAN_RESULT_ERROR) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000301 ALOGE("An error occurred while scanning file '%s'.", pathStr);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 env->ReleaseStringUTFChars(path, pathStr);
304 if (mimeType) {
305 env->ReleaseStringUTFChars(mimeType, mimeTypeStr);
306 }
307}
308
309static void
James Dongf3997522011-03-11 12:02:12 -0800310android_media_MediaScanner_setLocale(
311 JNIEnv *env, jobject thiz, jstring locale)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312{
Steve Block06ade6a2011-10-20 11:56:00 +0100313 ALOGV("setLocale");
James Dong133cf8b2011-03-11 15:18:40 -0800314 MediaScanner *mp = getNativeScanner_l(env, thiz);
315 if (mp == NULL) {
316 jniThrowException(env, kRunTimeException, "No scanner available");
317 return;
318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319
320 if (locale == NULL) {
James Dongf3997522011-03-11 12:02:12 -0800321 jniThrowException(env, kIllegalArgumentException, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 return;
323 }
324 const char *localeStr = env->GetStringUTFChars(locale, NULL);
325 if (localeStr == NULL) { // Out of memory
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 return;
327 }
328 mp->setLocale(localeStr);
329
330 env->ReleaseStringUTFChars(locale, localeStr);
331}
332
333static jbyteArray
James Dongf3997522011-03-11 12:02:12 -0800334android_media_MediaScanner_extractAlbumArt(
335 JNIEnv *env, jobject thiz, jobject fileDescriptor)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336{
Steve Block06ade6a2011-10-20 11:56:00 +0100337 ALOGV("extractAlbumArt");
James Dong133cf8b2011-03-11 15:18:40 -0800338 MediaScanner *mp = getNativeScanner_l(env, thiz);
339 if (mp == NULL) {
340 jniThrowException(env, kRunTimeException, "No scanner available");
341 return NULL;
342 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343
344 if (fileDescriptor == NULL) {
James Dongf3997522011-03-11 12:02:12 -0800345 jniThrowException(env, kIllegalArgumentException, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 return NULL;
347 }
348
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700349 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 char* data = mp->extractAlbumArt(fd);
351 if (!data) {
352 return NULL;
353 }
354 long len = *((long*)data);
James Dongf3997522011-03-11 12:02:12 -0800355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 jbyteArray array = env->NewByteArray(len);
357 if (array != NULL) {
358 jbyte* bytes = env->GetByteArrayElements(array, NULL);
359 memcpy(bytes, data + 4, len);
360 env->ReleaseByteArrayElements(array, bytes, 0);
361 }
James Dongf3997522011-03-11 12:02:12 -0800362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363done:
364 free(data);
365 // if NewByteArray() returned NULL, an out-of-memory
366 // exception will have been raised. I just want to
367 // return null in that case.
368 env->ExceptionClear();
369 return array;
370}
371
Marco Nelissen4935d052009-08-03 11:12:58 -0700372// This function gets a field ID, which in turn causes class initialization.
373// It is called from a static block in MediaScanner, which won't run until the
374// first time an instance of this class is used.
375static void
376android_media_MediaScanner_native_init(JNIEnv *env)
377{
Steve Block06ade6a2011-10-20 11:56:00 +0100378 ALOGV("native_init");
James Dongf3997522011-03-11 12:02:12 -0800379 jclass clazz = env->FindClass(kClassMediaScanner);
Marco Nelissen4935d052009-08-03 11:12:58 -0700380 if (clazz == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700381 return;
382 }
383
384 fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
385 if (fields.context == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700386 return;
387 }
388}
389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390static void
391android_media_MediaScanner_native_setup(JNIEnv *env, jobject thiz)
392{
Steve Block06ade6a2011-10-20 11:56:00 +0100393 ALOGV("native_setup");
Andreas Huber8d65dd22010-06-23 16:40:57 -0700394 MediaScanner *mp = new StagefrightMediaScanner;
Andreas Huberbfb9fb12009-12-03 11:31:19 -0800395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 if (mp == NULL) {
James Dongf3997522011-03-11 12:02:12 -0800397 jniThrowException(env, kRunTimeException, "Out of memory");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 return;
399 }
400
401 env->SetIntField(thiz, fields.context, (int)mp);
402}
403
404static void
405android_media_MediaScanner_native_finalize(JNIEnv *env, jobject thiz)
406{
Steve Block06ade6a2011-10-20 11:56:00 +0100407 ALOGV("native_finalize");
James Dong133cf8b2011-03-11 15:18:40 -0800408 MediaScanner *mp = getNativeScanner_l(env, thiz);
James Dongf3997522011-03-11 12:02:12 -0800409 if (mp == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 return;
James Dongf3997522011-03-11 12:02:12 -0800411 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 delete mp;
James Dong133cf8b2011-03-11 15:18:40 -0800413 setNativeScanner_l(env, thiz, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414}
415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416static JNINativeMethod gMethods[] = {
James Dongf3997522011-03-11 12:02:12 -0800417 {
418 "processDirectory",
419 "(Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
420 (void *)android_media_MediaScanner_processDirectory
421 },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422
James Dongf3997522011-03-11 12:02:12 -0800423 {
424 "processFile",
425 "(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
426 (void *)android_media_MediaScanner_processFile
427 },
428
429 {
430 "setLocale",
431 "(Ljava/lang/String;)V",
432 (void *)android_media_MediaScanner_setLocale
433 },
434
435 {
436 "extractAlbumArt",
437 "(Ljava/io/FileDescriptor;)[B",
438 (void *)android_media_MediaScanner_extractAlbumArt
439 },
440
441 {
442 "native_init",
443 "()V",
444 (void *)android_media_MediaScanner_native_init
445 },
446
447 {
448 "native_setup",
449 "()V",
450 (void *)android_media_MediaScanner_native_setup
451 },
452
453 {
454 "native_finalize",
455 "()V",
456 (void *)android_media_MediaScanner_native_finalize
457 },
458};
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459
Marco Nelissen4935d052009-08-03 11:12:58 -0700460// This function only registers the native methods, and is called from
461// JNI_OnLoad in android_media_MediaPlayer.cpp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462int register_android_media_MediaScanner(JNIEnv *env)
463{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 return AndroidRuntime::registerNativeMethods(env,
James Dongf3997522011-03-11 12:02:12 -0800465 kClassMediaScanner, gMethods, NELEM(gMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466}