blob: 58044c0307eb85cea271f789d94687d392f289ee [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>
Elliott Hughes9fa803b2014-06-05 10:38:30 -070024#include <private/media/VideoFrame.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025
26#include "jni.h"
Steven Moreland2279b252017-07-19 09:50:45 -070027#include <nativehelper/JNIHelp.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028#include "android_runtime/AndroidRuntime.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070029#include "android_runtime/Log.h"
Ray Essick67004bc2018-11-01 13:57:11 -070030#include <android-base/macros.h> // for FALLTHROUGH_INTENDED
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032using namespace android;
33
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034
James Dongf3997522011-03-11 12:02:12 -080035static const char* const kClassMediaScannerClient =
36 "android/media/MediaScannerClient";
37
38static const char* const kClassMediaScanner =
39 "android/media/MediaScanner";
40
41static const char* const kRunTimeException =
42 "java/lang/RuntimeException";
43
44static const char* const kIllegalArgumentException =
45 "java/lang/IllegalArgumentException";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046
James Dong133cf8b2011-03-11 15:18:40 -080047struct fields_t {
48 jfieldID context;
49};
50static fields_t fields;
James Dong133cf8b2011-03-11 15:18:40 -080051
Jeff Brown2c70d4a2011-07-20 16:38:43 -070052static status_t checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
53 if (env->ExceptionCheck()) {
Steve Blockc6aacce2012-01-06 19:20:56 +000054 ALOGE("An exception was thrown by callback '%s'.", methodName);
Jeff Brown2c70d4a2011-07-20 16:38:43 -070055 LOGE_EX(env);
56 env->ExceptionClear();
57 return UNKNOWN_ERROR;
58 }
59 return OK;
60}
61
Marco Nelissena0a73ed2013-02-12 18:33:41 +000062// stolen from dalvik/vm/checkJni.cpp
63static bool isValidUtf8(const char* bytes) {
64 while (*bytes != '\0') {
65 unsigned char utf8 = *(bytes++);
66 // Switch on the high four bits.
67 switch (utf8 >> 4) {
68 case 0x00:
69 case 0x01:
70 case 0x02:
71 case 0x03:
72 case 0x04:
73 case 0x05:
74 case 0x06:
75 case 0x07:
76 // Bit pattern 0xxx. No need for any extra bytes.
77 break;
78 case 0x08:
79 case 0x09:
80 case 0x0a:
81 case 0x0b:
82 case 0x0f:
83 /*
84 * Bit pattern 10xx or 1111, which are illegal start bytes.
85 * Note: 1111 is valid for normal UTF-8, but not the
86 * modified UTF-8 used here.
87 */
88 return false;
89 case 0x0e:
90 // Bit pattern 1110, so there are two additional bytes.
91 utf8 = *(bytes++);
92 if ((utf8 & 0xc0) != 0x80) {
93 return false;
94 }
95 // Fall through to take care of the final byte.
Ray Essick67004bc2018-11-01 13:57:11 -070096 FALLTHROUGH_INTENDED;
Marco Nelissena0a73ed2013-02-12 18:33:41 +000097 case 0x0c:
98 case 0x0d:
99 // Bit pattern 110x, so there is one additional byte.
100 utf8 = *(bytes++);
101 if ((utf8 & 0xc0) != 0x80) {
102 return false;
103 }
104 break;
105 }
106 }
107 return true;
108}
109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110class MyMediaScannerClient : public MediaScannerClient
111{
112public:
113 MyMediaScannerClient(JNIEnv *env, jobject client)
114 : mEnv(env),
115 mClient(env->NewGlobalRef(client)),
116 mScanFileMethodID(0),
117 mHandleStringTagMethodID(0),
118 mSetMimeTypeMethodID(0)
119 {
Steve Block06ade6a2011-10-20 11:56:00 +0100120 ALOGV("MyMediaScannerClient constructor");
James Dongf3997522011-03-11 12:02:12 -0800121 jclass mediaScannerClientInterface =
122 env->FindClass(kClassMediaScannerClient);
123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 if (mediaScannerClientInterface == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000125 ALOGE("Class %s not found", kClassMediaScannerClient);
James Dongf3997522011-03-11 12:02:12 -0800126 } else {
127 mScanFileMethodID = env->GetMethodID(
128 mediaScannerClientInterface,
129 "scanFile",
Mike Lockwood997354e2011-04-24 11:15:09 -0700130 "(Ljava/lang/String;JJZZ)V");
James Dongf3997522011-03-11 12:02:12 -0800131
132 mHandleStringTagMethodID = env->GetMethodID(
133 mediaScannerClientInterface,
134 "handleStringTag",
135 "(Ljava/lang/String;Ljava/lang/String;)V");
136
137 mSetMimeTypeMethodID = env->GetMethodID(
138 mediaScannerClientInterface,
139 "setMimeType",
140 "(Ljava/lang/String;)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 }
142 }
James Dongf3997522011-03-11 12:02:12 -0800143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 virtual ~MyMediaScannerClient()
145 {
Steve Block06ade6a2011-10-20 11:56:00 +0100146 ALOGV("MyMediaScannerClient destructor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 mEnv->DeleteGlobalRef(mClient);
148 }
James Dongf3997522011-03-11 12:02:12 -0800149
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700150 virtual status_t scanFile(const char* path, long long lastModified,
Mike Lockwood997354e2011-04-24 11:15:09 -0700151 long long fileSize, bool isDirectory, bool noMedia)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 {
Steve Block06ade6a2011-10-20 11:56:00 +0100153 ALOGV("scanFile: path(%s), time(%lld), size(%lld) and isDir(%d)",
James Dongf3997522011-03-11 12:02:12 -0800154 path, lastModified, fileSize, isDirectory);
155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 jstring pathStr;
James Dongf3997522011-03-11 12:02:12 -0800157 if ((pathStr = mEnv->NewStringUTF(path)) == NULL) {
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700158 mEnv->ExceptionClear();
159 return NO_MEMORY;
James Dongf3997522011-03-11 12:02:12 -0800160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161
Mike Lockwood076e05b2010-12-16 12:54:24 -0800162 mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified,
Mike Lockwood997354e2011-04-24 11:15:09 -0700163 fileSize, isDirectory, noMedia);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164
165 mEnv->DeleteLocalRef(pathStr);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700166 return checkAndClearExceptionFromCallback(mEnv, "scanFile");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 }
168
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700169 virtual status_t handleStringTag(const char* name, const char* value)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 {
Steve Block06ade6a2011-10-20 11:56:00 +0100171 ALOGV("handleStringTag: name(%s) and value(%s)", name, value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 jstring nameStr, valueStr;
James Dongf3997522011-03-11 12:02:12 -0800173 if ((nameStr = mEnv->NewStringUTF(name)) == NULL) {
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700174 mEnv->ExceptionClear();
175 return NO_MEMORY;
James Dongf3997522011-03-11 12:02:12 -0800176 }
Marco Nelissenf51f1bd2011-11-02 10:49:50 -0700177 char *cleaned = NULL;
Marco Nelissena0a73ed2013-02-12 18:33:41 +0000178 if (!isValidUtf8(value)) {
Marco Nelissenf51f1bd2011-11-02 10:49:50 -0700179 cleaned = strdup(value);
180 char *chp = cleaned;
181 char ch;
182 while ((ch = *chp)) {
183 if (ch & 0x80) {
184 *chp = '?';
185 }
186 chp++;
187 }
188 value = cleaned;
189 }
190 valueStr = mEnv->NewStringUTF(value);
191 free(cleaned);
192 if (valueStr == NULL) {
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700193 mEnv->DeleteLocalRef(nameStr);
194 mEnv->ExceptionClear();
195 return NO_MEMORY;
James Dongf3997522011-03-11 12:02:12 -0800196 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197
James Dongf3997522011-03-11 12:02:12 -0800198 mEnv->CallVoidMethod(
199 mClient, mHandleStringTagMethodID, nameStr, valueStr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200
201 mEnv->DeleteLocalRef(nameStr);
202 mEnv->DeleteLocalRef(valueStr);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700203 return checkAndClearExceptionFromCallback(mEnv, "handleStringTag");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 }
205
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700206 virtual status_t setMimeType(const char* mimeType)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 {
Steve Block06ade6a2011-10-20 11:56:00 +0100208 ALOGV("setMimeType: %s", mimeType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 jstring mimeTypeStr;
James Dongf3997522011-03-11 12:02:12 -0800210 if ((mimeTypeStr = mEnv->NewStringUTF(mimeType)) == NULL) {
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700211 mEnv->ExceptionClear();
212 return NO_MEMORY;
James Dongf3997522011-03-11 12:02:12 -0800213 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214
215 mEnv->CallVoidMethod(mClient, mSetMimeTypeMethodID, mimeTypeStr);
216
217 mEnv->DeleteLocalRef(mimeTypeStr);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700218 return checkAndClearExceptionFromCallback(mEnv, "setMimeType");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 }
220
221private:
222 JNIEnv *mEnv;
223 jobject mClient;
James Dongf3997522011-03-11 12:02:12 -0800224 jmethodID mScanFileMethodID;
225 jmethodID mHandleStringTagMethodID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 jmethodID mSetMimeTypeMethodID;
227};
228
229
James Dong133cf8b2011-03-11 15:18:40 -0800230static MediaScanner *getNativeScanner_l(JNIEnv* env, jobject thiz)
231{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000232 return (MediaScanner *) env->GetLongField(thiz, fields.context);
James Dong133cf8b2011-03-11 15:18:40 -0800233}
234
James Dong133cf8b2011-03-11 15:18:40 -0800235static void setNativeScanner_l(JNIEnv* env, jobject thiz, MediaScanner *s)
236{
Ashok Bhat075e9a12014-01-06 13:45:09 +0000237 env->SetLongField(thiz, fields.context, (jlong)s);
James Dong133cf8b2011-03-11 15:18:40 -0800238}
239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240static void
James Dongf3997522011-03-11 12:02:12 -0800241android_media_MediaScanner_processDirectory(
242 JNIEnv *env, jobject thiz, jstring path, jobject client)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243{
Steve Block06ade6a2011-10-20 11:56:00 +0100244 ALOGV("processDirectory");
James Dong133cf8b2011-03-11 15:18:40 -0800245 MediaScanner *mp = getNativeScanner_l(env, thiz);
246 if (mp == NULL) {
247 jniThrowException(env, kRunTimeException, "No scanner available");
248 return;
249 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250
251 if (path == NULL) {
James Dongf3997522011-03-11 12:02:12 -0800252 jniThrowException(env, kIllegalArgumentException, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 return;
254 }
Mike Lockwoodc37255d2010-09-10 14:47:36 -0400255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 const char *pathStr = env->GetStringUTFChars(path, NULL);
257 if (pathStr == NULL) { // Out of memory
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 return;
259 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260
261 MyMediaScannerClient myClient(env, client);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700262 MediaScanResult result = mp->processDirectory(pathStr, myClient);
263 if (result == MEDIA_SCAN_RESULT_ERROR) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000264 ALOGE("An error occurred while scanning directory '%s'.", pathStr);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700265 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 env->ReleaseStringUTFChars(path, pathStr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267}
268
Marco Nelissenbab75902018-04-25 12:24:11 -0700269static jboolean
James Dongf3997522011-03-11 12:02:12 -0800270android_media_MediaScanner_processFile(
271 JNIEnv *env, jobject thiz, jstring path,
272 jstring mimeType, jobject client)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273{
Steve Block06ade6a2011-10-20 11:56:00 +0100274 ALOGV("processFile");
James Dong133cf8b2011-03-11 15:18:40 -0800275
276 // Lock already hold by processDirectory
277 MediaScanner *mp = getNativeScanner_l(env, thiz);
278 if (mp == NULL) {
279 jniThrowException(env, kRunTimeException, "No scanner available");
Marco Nelissenbab75902018-04-25 12:24:11 -0700280 return false;
James Dong133cf8b2011-03-11 15:18:40 -0800281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282
283 if (path == NULL) {
James Dongf3997522011-03-11 12:02:12 -0800284 jniThrowException(env, kIllegalArgumentException, NULL);
Marco Nelissenbab75902018-04-25 12:24:11 -0700285 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 }
James Dongf3997522011-03-11 12:02:12 -0800287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 const char *pathStr = env->GetStringUTFChars(path, NULL);
289 if (pathStr == NULL) { // Out of memory
Marco Nelissenbab75902018-04-25 12:24:11 -0700290 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 }
James Dongf3997522011-03-11 12:02:12 -0800292
293 const char *mimeTypeStr =
294 (mimeType ? env->GetStringUTFChars(mimeType, NULL) : NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 if (mimeType && mimeTypeStr == NULL) { // Out of memory
James Dongc371a022011-04-06 12:16:07 -0700296 // ReleaseStringUTFChars can be called with an exception pending.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 env->ReleaseStringUTFChars(path, pathStr);
Marco Nelissenbab75902018-04-25 12:24:11 -0700298 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 }
300
301 MyMediaScannerClient myClient(env, client);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700302 MediaScanResult result = mp->processFile(pathStr, mimeTypeStr, myClient);
303 if (result == MEDIA_SCAN_RESULT_ERROR) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000304 ALOGE("An error occurred while scanning file '%s'.", pathStr);
Jeff Brown2c70d4a2011-07-20 16:38:43 -0700305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 env->ReleaseStringUTFChars(path, pathStr);
307 if (mimeType) {
308 env->ReleaseStringUTFChars(mimeType, mimeTypeStr);
309 }
Marco Nelissenbab75902018-04-25 12:24:11 -0700310 return result != MEDIA_SCAN_RESULT_ERROR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311}
312
313static void
James Dongf3997522011-03-11 12:02:12 -0800314android_media_MediaScanner_setLocale(
315 JNIEnv *env, jobject thiz, jstring locale)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316{
Steve Block06ade6a2011-10-20 11:56:00 +0100317 ALOGV("setLocale");
James Dong133cf8b2011-03-11 15:18:40 -0800318 MediaScanner *mp = getNativeScanner_l(env, thiz);
319 if (mp == NULL) {
320 jniThrowException(env, kRunTimeException, "No scanner available");
321 return;
322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323
324 if (locale == NULL) {
James Dongf3997522011-03-11 12:02:12 -0800325 jniThrowException(env, kIllegalArgumentException, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 return;
327 }
328 const char *localeStr = env->GetStringUTFChars(locale, NULL);
329 if (localeStr == NULL) { // Out of memory
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 return;
331 }
332 mp->setLocale(localeStr);
333
334 env->ReleaseStringUTFChars(locale, localeStr);
335}
336
337static jbyteArray
James Dongf3997522011-03-11 12:02:12 -0800338android_media_MediaScanner_extractAlbumArt(
339 JNIEnv *env, jobject thiz, jobject fileDescriptor)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340{
Steve Block06ade6a2011-10-20 11:56:00 +0100341 ALOGV("extractAlbumArt");
James Dong133cf8b2011-03-11 15:18:40 -0800342 MediaScanner *mp = getNativeScanner_l(env, thiz);
343 if (mp == NULL) {
344 jniThrowException(env, kRunTimeException, "No scanner available");
345 return NULL;
346 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347
348 if (fileDescriptor == NULL) {
James Dongf3997522011-03-11 12:02:12 -0800349 jniThrowException(env, kIllegalArgumentException, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 return NULL;
351 }
352
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700353 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
Elliott Hughes95d3f862014-06-10 16:53:31 -0700354 MediaAlbumArt* mediaAlbumArt = mp->extractAlbumArt(fd);
Elliott Hughese0f2fa32014-06-09 09:22:58 -0700355 if (mediaAlbumArt == NULL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 return NULL;
357 }
James Dongf3997522011-03-11 12:02:12 -0800358
Elliott Hughes95d3f862014-06-10 16:53:31 -0700359 jbyteArray array = env->NewByteArray(mediaAlbumArt->size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 if (array != NULL) {
Elliott Hughes95d3f862014-06-10 16:53:31 -0700361 const jbyte* data =
362 reinterpret_cast<const jbyte*>(mediaAlbumArt->data());
363 env->SetByteArrayRegion(array, 0, mediaAlbumArt->size(), data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 }
James Dongf3997522011-03-11 12:02:12 -0800365
Elliott Hughes9fa803b2014-06-05 10:38:30 -0700366 free(mediaAlbumArt);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 // if NewByteArray() returned NULL, an out-of-memory
368 // exception will have been raised. I just want to
369 // return null in that case.
370 env->ExceptionClear();
371 return array;
372}
373
Marco Nelissen4935d052009-08-03 11:12:58 -0700374// This function gets a field ID, which in turn causes class initialization.
375// It is called from a static block in MediaScanner, which won't run until the
376// first time an instance of this class is used.
377static void
378android_media_MediaScanner_native_init(JNIEnv *env)
379{
Steve Block06ade6a2011-10-20 11:56:00 +0100380 ALOGV("native_init");
James Dongf3997522011-03-11 12:02:12 -0800381 jclass clazz = env->FindClass(kClassMediaScanner);
Marco Nelissen4935d052009-08-03 11:12:58 -0700382 if (clazz == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700383 return;
384 }
385
Ashok Bhat075e9a12014-01-06 13:45:09 +0000386 fields.context = env->GetFieldID(clazz, "mNativeContext", "J");
Marco Nelissen4935d052009-08-03 11:12:58 -0700387 if (fields.context == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700388 return;
389 }
390}
391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392static void
393android_media_MediaScanner_native_setup(JNIEnv *env, jobject thiz)
394{
Steve Block06ade6a2011-10-20 11:56:00 +0100395 ALOGV("native_setup");
Andreas Huber8d65dd22010-06-23 16:40:57 -0700396 MediaScanner *mp = new StagefrightMediaScanner;
Andreas Huberbfb9fb12009-12-03 11:31:19 -0800397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 if (mp == NULL) {
James Dongf3997522011-03-11 12:02:12 -0800399 jniThrowException(env, kRunTimeException, "Out of memory");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 return;
401 }
402
Ashok Bhat075e9a12014-01-06 13:45:09 +0000403 env->SetLongField(thiz, fields.context, (jlong)mp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404}
405
406static void
407android_media_MediaScanner_native_finalize(JNIEnv *env, jobject thiz)
408{
Steve Block06ade6a2011-10-20 11:56:00 +0100409 ALOGV("native_finalize");
James Dong133cf8b2011-03-11 15:18:40 -0800410 MediaScanner *mp = getNativeScanner_l(env, thiz);
James Dongf3997522011-03-11 12:02:12 -0800411 if (mp == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 return;
James Dongf3997522011-03-11 12:02:12 -0800413 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 delete mp;
James Dong133cf8b2011-03-11 15:18:40 -0800415 setNativeScanner_l(env, thiz, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416}
417
Daniel Micay76f6a862015-09-19 17:31:01 -0400418static const JNINativeMethod gMethods[] = {
James Dongf3997522011-03-11 12:02:12 -0800419 {
420 "processDirectory",
421 "(Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
422 (void *)android_media_MediaScanner_processDirectory
423 },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424
James Dongf3997522011-03-11 12:02:12 -0800425 {
426 "processFile",
Marco Nelissenbab75902018-04-25 12:24:11 -0700427 "(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)Z",
James Dongf3997522011-03-11 12:02:12 -0800428 (void *)android_media_MediaScanner_processFile
429 },
430
431 {
432 "setLocale",
433 "(Ljava/lang/String;)V",
434 (void *)android_media_MediaScanner_setLocale
435 },
436
437 {
438 "extractAlbumArt",
439 "(Ljava/io/FileDescriptor;)[B",
440 (void *)android_media_MediaScanner_extractAlbumArt
441 },
442
443 {
444 "native_init",
445 "()V",
446 (void *)android_media_MediaScanner_native_init
447 },
448
449 {
450 "native_setup",
451 "()V",
452 (void *)android_media_MediaScanner_native_setup
453 },
454
455 {
456 "native_finalize",
457 "()V",
458 (void *)android_media_MediaScanner_native_finalize
459 },
460};
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461
Marco Nelissen4935d052009-08-03 11:12:58 -0700462// This function only registers the native methods, and is called from
463// JNI_OnLoad in android_media_MediaPlayer.cpp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464int register_android_media_MediaScanner(JNIEnv *env)
465{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 return AndroidRuntime::registerNativeMethods(env,
James Dongf3997522011-03-11 12:02:12 -0800467 kClassMediaScanner, gMethods, NELEM(gMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468}