blob: bf831728f791ed7269af2b5cc6723b8b9c5242e2 [file] [log] [blame]
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "MtpDatabaseJNI"
18#include "utils/Log.h"
19
20#include <stdio.h>
21#include <assert.h>
22#include <limits.h>
23#include <unistd.h>
24#include <fcntl.h>
25
26#include "jni.h"
27#include "JNIHelp.h"
28#include "android_runtime/AndroidRuntime.h"
29
30#include "MtpDatabase.h"
31#include "MtpDataPacket.h"
32#include "MtpUtils.h"
33#include "mtp.h"
34
35using namespace android;
36
37// ----------------------------------------------------------------------------
38
Mike Lockwoodd815f792010-07-12 08:49:01 -040039static jmethodID method_beginSendObject;
40static jmethodID method_endSendObject;
Mike Lockwoodd21eac92010-07-03 00:44:05 -040041static jmethodID method_getObjectList;
Mike Lockwood7a047c82010-08-02 10:52:20 -040042static jmethodID method_getNumObjects;
Mike Lockwood4b322ce2010-08-10 07:37:50 -040043static jmethodID method_getSupportedPlaybackFormats;
44static jmethodID method_getSupportedCaptureFormats;
45static jmethodID method_getSupportedObjectProperties;
46static jmethodID method_getSupportedDeviceProperties;
Mike Lockwoodd21eac92010-07-03 00:44:05 -040047static jmethodID method_getObjectProperty;
48static jmethodID method_getObjectInfo;
49static jmethodID method_getObjectFilePath;
50static jmethodID method_deleteFile;
Mike Lockwood9a2046f2010-08-03 15:30:09 -040051static jmethodID method_getObjectReferences;
52static jmethodID method_setObjectReferences;
Mike Lockwoodd21eac92010-07-03 00:44:05 -040053static jfieldID field_context;
54
55MtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) {
56 return (MtpDatabase *)env->GetIntField(database, field_context);
57}
58
Mike Lockwoodff164a72010-07-15 15:01:17 -040059#ifdef HAVE_ANDROID_OS
Mike Lockwoodd21eac92010-07-03 00:44:05 -040060// ----------------------------------------------------------------------------
61
62class MyMtpDatabase : public MtpDatabase {
63private:
64 jobject mDatabase;
65 jintArray mIntBuffer;
66 jlongArray mLongBuffer;
67 jcharArray mStringBuffer;
68
69public:
70 MyMtpDatabase(JNIEnv *env, jobject client);
71 virtual ~MyMtpDatabase();
72 void cleanup(JNIEnv *env);
73
Mike Lockwoodd815f792010-07-12 08:49:01 -040074 virtual MtpObjectHandle beginSendObject(const char* path,
Mike Lockwoodd21eac92010-07-03 00:44:05 -040075 MtpObjectFormat format,
76 MtpObjectHandle parent,
77 MtpStorageID storage,
78 uint64_t size,
79 time_t modified);
80
Mike Lockwoodd815f792010-07-12 08:49:01 -040081 virtual void endSendObject(const char* path,
82 MtpObjectHandle handle,
83 MtpObjectFormat format,
84 bool succeeded);
85
Mike Lockwoodd21eac92010-07-03 00:44:05 -040086 virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID,
87 MtpObjectFormat format,
88 MtpObjectHandle parent);
89
Mike Lockwood7a047c82010-08-02 10:52:20 -040090 virtual int getNumObjects(MtpStorageID storageID,
91 MtpObjectFormat format,
92 MtpObjectHandle parent);
93
Mike Lockwood4b322ce2010-08-10 07:37:50 -040094 // callee should delete[] the results from these
95 // results can be NULL
96 virtual MtpObjectFormatList* getSupportedPlaybackFormats();
97 virtual MtpObjectFormatList* getSupportedCaptureFormats();
98 virtual MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat format);
99 virtual MtpDevicePropertyList* getSupportedDeviceProperties();
100
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400101 virtual MtpResponseCode getObjectProperty(MtpObjectHandle handle,
102 MtpObjectProperty property,
103 MtpDataPacket& packet);
104
105 virtual MtpResponseCode getObjectInfo(MtpObjectHandle handle,
106 MtpDataPacket& packet);
107
Mike Lockwood59c777a2010-08-02 10:37:41 -0400108 virtual MtpResponseCode getObjectFilePath(MtpObjectHandle handle,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400109 MtpString& filePath,
110 int64_t& fileLength);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400111 virtual MtpResponseCode deleteFile(MtpObjectHandle handle);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400112
113 bool getPropertyInfo(MtpObjectProperty property, int& type);
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400114
115 virtual MtpObjectHandleList* getObjectReferences(MtpObjectHandle handle);
116
117 virtual MtpResponseCode setObjectReferences(MtpObjectHandle handle,
118 MtpObjectHandleList* references);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400119};
120
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400121// ----------------------------------------------------------------------------
122
123static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
124 if (env->ExceptionCheck()) {
125 LOGE("An exception was thrown by callback '%s'.", methodName);
126 LOGE_EX(env);
127 env->ExceptionClear();
128 }
129}
130
131// ----------------------------------------------------------------------------
132
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400133MyMtpDatabase::MyMtpDatabase(JNIEnv *env, jobject client)
134 : mDatabase(env->NewGlobalRef(client)),
135 mIntBuffer(NULL),
136 mLongBuffer(NULL),
137 mStringBuffer(NULL)
138{
139 jintArray intArray;
140 jlongArray longArray;
141 jcharArray charArray;
142
143 // create buffers for out arguments
144 // we don't need to be thread-safe so this is OK
145 intArray = env->NewIntArray(3);
146 if (!intArray)
147 goto out_of_memory;
148 mIntBuffer = (jintArray)env->NewGlobalRef(intArray);
149 longArray = env->NewLongArray(2);
150 if (!longArray)
151 goto out_of_memory;
152 mLongBuffer = (jlongArray)env->NewGlobalRef(longArray);
153 charArray = env->NewCharArray(256);
154 if (!charArray)
155 goto out_of_memory;
156 mStringBuffer = (jcharArray)env->NewGlobalRef(charArray);
157 return;
158
159out_of_memory:
160 env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), NULL);
161}
162
163void MyMtpDatabase::cleanup(JNIEnv *env) {
164 env->DeleteGlobalRef(mDatabase);
165 env->DeleteGlobalRef(mIntBuffer);
166 env->DeleteGlobalRef(mLongBuffer);
167 env->DeleteGlobalRef(mStringBuffer);
168}
169
170MyMtpDatabase::~MyMtpDatabase() {
171}
172
Mike Lockwoodd815f792010-07-12 08:49:01 -0400173MtpObjectHandle MyMtpDatabase::beginSendObject(const char* path,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400174 MtpObjectFormat format,
175 MtpObjectHandle parent,
176 MtpStorageID storage,
177 uint64_t size,
178 time_t modified) {
179 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400180 MtpObjectHandle result = env->CallIntMethod(mDatabase, method_beginSendObject,
181 env->NewStringUTF(path), (jint)format, (jint)parent, (jint)storage,
182 (jlong)size, (jlong)modified);
183
184 checkAndClearExceptionFromCallback(env, __FUNCTION__);
185 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400186}
187
Mike Lockwoodd815f792010-07-12 08:49:01 -0400188void MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
189 MtpObjectFormat format, bool succeeded) {
190 JNIEnv* env = AndroidRuntime::getJNIEnv();
191 env->CallVoidMethod(mDatabase, method_endSendObject, env->NewStringUTF(path),
192 (jint)handle, (jint)format, (jboolean)succeeded);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400193
194 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodd815f792010-07-12 08:49:01 -0400195}
196
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400197MtpObjectHandleList* MyMtpDatabase::getObjectList(MtpStorageID storageID,
198 MtpObjectFormat format,
199 MtpObjectHandle parent) {
200 JNIEnv* env = AndroidRuntime::getJNIEnv();
201 jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectList,
202 (jint)storageID, (jint)format, (jint)parent);
203 if (!array)
204 return NULL;
205 MtpObjectHandleList* list = new MtpObjectHandleList();
206 jint* handles = env->GetIntArrayElements(array, 0);
207 jsize length = env->GetArrayLength(array);
Mike Lockwood7a047c82010-08-02 10:52:20 -0400208 for (int i = 0; i < length; i++)
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400209 list->push(handles[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400210 env->ReleaseIntArrayElements(array, handles, 0);
211
212 checkAndClearExceptionFromCallback(env, __FUNCTION__);
213 return list;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400214}
215
Mike Lockwood7a047c82010-08-02 10:52:20 -0400216int MyMtpDatabase::getNumObjects(MtpStorageID storageID,
217 MtpObjectFormat format,
218 MtpObjectHandle parent) {
219 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400220 int result = env->CallIntMethod(mDatabase, method_getNumObjects,
Mike Lockwood7a047c82010-08-02 10:52:20 -0400221 (jint)storageID, (jint)format, (jint)parent);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400222
223 checkAndClearExceptionFromCallback(env, __FUNCTION__);
224 return result;
Mike Lockwood7a047c82010-08-02 10:52:20 -0400225}
226
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400227MtpObjectFormatList* MyMtpDatabase::getSupportedPlaybackFormats() {
228 JNIEnv* env = AndroidRuntime::getJNIEnv();
229 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
230 method_getSupportedPlaybackFormats);
231 if (!array)
232 return NULL;
233 MtpObjectFormatList* list = new MtpObjectFormatList();
234 jint* formats = env->GetIntArrayElements(array, 0);
235 jsize length = env->GetArrayLength(array);
236 for (int i = 0; i < length; i++)
237 list->push(formats[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400238 env->ReleaseIntArrayElements(array, formats, 0);
239
240 checkAndClearExceptionFromCallback(env, __FUNCTION__);
241 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400242}
243
244MtpObjectFormatList* MyMtpDatabase::getSupportedCaptureFormats() {
245 JNIEnv* env = AndroidRuntime::getJNIEnv();
246 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
247 method_getSupportedCaptureFormats);
248 if (!array)
249 return NULL;
250 MtpObjectFormatList* list = new MtpObjectFormatList();
251 jint* formats = env->GetIntArrayElements(array, 0);
252 jsize length = env->GetArrayLength(array);
253 for (int i = 0; i < length; i++)
254 list->push(formats[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400255 env->ReleaseIntArrayElements(array, formats, 0);
256
257 checkAndClearExceptionFromCallback(env, __FUNCTION__);
258 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400259}
260
261MtpObjectPropertyList* MyMtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) {
262 JNIEnv* env = AndroidRuntime::getJNIEnv();
263 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
264 method_getSupportedObjectProperties, (jint)format);
265 if (!array)
266 return NULL;
267 MtpObjectPropertyList* list = new MtpObjectPropertyList();
268 jint* properties = env->GetIntArrayElements(array, 0);
269 jsize length = env->GetArrayLength(array);
270 for (int i = 0; i < length; i++)
271 list->push(properties[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400272 env->ReleaseIntArrayElements(array, properties, 0);
273
274 checkAndClearExceptionFromCallback(env, __FUNCTION__);
275 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400276}
277
278MtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
279 JNIEnv* env = AndroidRuntime::getJNIEnv();
280 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
281 method_getSupportedDeviceProperties);
282 if (!array)
283 return NULL;
284 MtpDevicePropertyList* list = new MtpDevicePropertyList();
285 jint* properties = env->GetIntArrayElements(array, 0);
286 jsize length = env->GetArrayLength(array);
287 for (int i = 0; i < length; i++)
288 list->push(properties[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400289 env->ReleaseIntArrayElements(array, properties, 0);
290
291 checkAndClearExceptionFromCallback(env, __FUNCTION__);
292 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400293}
294
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400295MtpResponseCode MyMtpDatabase::getObjectProperty(MtpObjectHandle handle,
296 MtpObjectProperty property,
297 MtpDataPacket& packet) {
298 int type;
299
300 if (!getPropertyInfo(property, type))
301 return MTP_RESPONSE_INVALID_OBJECT_PROP_CODE;
302
303 JNIEnv* env = AndroidRuntime::getJNIEnv();
304 jint result = env->CallIntMethod(mDatabase, method_getObjectProperty,
305 (jint)handle, (jint)property, mLongBuffer, mStringBuffer);
306 if (result != MTP_RESPONSE_OK)
307 return result;
308
309 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
310 jlong longValue = longValues[0];
311 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
312
313 switch (type) {
314 case MTP_TYPE_INT8:
315 packet.putInt8(longValue);
316 break;
317 case MTP_TYPE_UINT8:
318 packet.putUInt8(longValue);
319 break;
320 case MTP_TYPE_INT16:
321 packet.putInt16(longValue);
322 break;
323 case MTP_TYPE_UINT16:
324 packet.putUInt16(longValue);
325 break;
326 case MTP_TYPE_INT32:
327 packet.putInt32(longValue);
328 break;
329 case MTP_TYPE_UINT32:
330 packet.putUInt32(longValue);
331 break;
332 case MTP_TYPE_INT64:
333 packet.putInt64(longValue);
334 break;
335 case MTP_TYPE_UINT64:
336 packet.putUInt64(longValue);
337 break;
338 case MTP_TYPE_STR:
339 {
340 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
341 packet.putString(str);
342 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
343 break;
344 }
345 default:
346 LOGE("unsupported object type\n");
347 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
348 }
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400349
350 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400351 return MTP_RESPONSE_OK;
352}
353
354MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
355 MtpDataPacket& packet) {
356 char date[20];
357
358 JNIEnv* env = AndroidRuntime::getJNIEnv();
359 jboolean result = env->CallBooleanMethod(mDatabase, method_getObjectInfo,
360 (jint)handle, mIntBuffer, mStringBuffer, mLongBuffer);
361 if (!result)
362 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
363
364 jint* intValues = env->GetIntArrayElements(mIntBuffer, 0);
365 MtpStorageID storageID = intValues[0];
366 MtpObjectFormat format = intValues[1];
367 MtpObjectHandle parent = intValues[2];
368 env->ReleaseIntArrayElements(mIntBuffer, intValues, 0);
369
370 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
371 uint64_t size = longValues[0];
372 uint64_t modified = longValues[1];
373 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
374
375 int associationType = (format == MTP_FORMAT_ASSOCIATION ?
376 MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
377 MTP_ASSOCIATION_TYPE_UNDEFINED);
378
379 packet.putUInt32(storageID);
380 packet.putUInt16(format);
381 packet.putUInt16(0); // protection status
382 packet.putUInt32((size > 0xFFFFFFFFLL ? 0xFFFFFFFF : size));
383 packet.putUInt16(0); // thumb format
384 packet.putUInt32(0); // thumb compressed size
385 packet.putUInt32(0); // thumb pix width
386 packet.putUInt32(0); // thumb pix height
387 packet.putUInt32(0); // image pix width
388 packet.putUInt32(0); // image pix height
389 packet.putUInt32(0); // image bit depth
390 packet.putUInt32(parent);
391 packet.putUInt16(associationType);
392 packet.putUInt32(0); // association desc
393 packet.putUInt32(0); // sequence number
394
395 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
396 packet.putString(str); // file name
397 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
398
399 packet.putEmptyString();
400 formatDateTime(modified, date, sizeof(date));
401 packet.putString(date); // date modified
402 packet.putEmptyString(); // keywords
403
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400404 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400405 return MTP_RESPONSE_OK;
406}
407
Mike Lockwood59c777a2010-08-02 10:37:41 -0400408MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400409 MtpString& filePath,
410 int64_t& fileLength) {
411 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood59c777a2010-08-02 10:37:41 -0400412 jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400413 (jint)handle, mStringBuffer, mLongBuffer);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400414 if (result != MTP_RESPONSE_OK)
415 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400416
417 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
418 filePath.setTo(str, strlen16(str));
419 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
420
421 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
422 fileLength = longValues[0];
423 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
424
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400425 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400426 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400427}
428
Mike Lockwood59c777a2010-08-02 10:37:41 -0400429MtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400430 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400431 MtpResponseCode result = env->CallIntMethod(mDatabase, method_deleteFile, (jint)handle);
432
433 checkAndClearExceptionFromCallback(env, __FUNCTION__);
434 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400435}
436
437struct PropertyTableEntry {
438 MtpObjectProperty property;
439 int type;
440};
441
442static const PropertyTableEntry kPropertyTable[] = {
443 { MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32 },
444 { MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32 },
Mike Lockwoodc642e8a2010-08-09 14:17:52 -0400445 { MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16 },
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400446 { MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR },
447 { MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64 },
448 { MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR },
449};
450
451bool MyMtpDatabase::getPropertyInfo(MtpObjectProperty property, int& type) {
452 int count = sizeof(kPropertyTable) / sizeof(kPropertyTable[0]);
453 const PropertyTableEntry* entry = kPropertyTable;
454 for (int i = 0; i < count; i++, entry++) {
455 if (entry->property == property) {
456 type = entry->type;
457 return true;
458 }
459 }
460 return false;
461}
462
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400463MtpObjectHandleList* MyMtpDatabase::getObjectReferences(MtpObjectHandle handle) {
464 JNIEnv* env = AndroidRuntime::getJNIEnv();
465 jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectReferences,
466 (jint)handle);
467 if (!array)
468 return NULL;
469 MtpObjectHandleList* list = new MtpObjectHandleList();
470 jint* handles = env->GetIntArrayElements(array, 0);
471 jsize length = env->GetArrayLength(array);
472 for (int i = 0; i < length; i++)
473 list->push(handles[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400474 env->ReleaseIntArrayElements(array, handles, 0);
475
476 checkAndClearExceptionFromCallback(env, __FUNCTION__);
477 return list;
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400478}
479
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400480MtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle,
481 MtpObjectHandleList* references) {
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400482 JNIEnv* env = AndroidRuntime::getJNIEnv();
483 int count = references->size();
484 jintArray array = env->NewIntArray(count);
485 if (!array) {
486 LOGE("out of memory in setObjectReferences");
487 return false;
488 }
489 jint* handles = env->GetIntArrayElements(array, 0);
490 for (int i = 0; i < count; i++)
491 handles[i] = (*references)[i];
492 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400493 MtpResponseCode result = env->CallIntMethod(mDatabase, method_setObjectReferences,
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400494 (jint)handle, array);
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400495
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400496 checkAndClearExceptionFromCallback(env, __FUNCTION__);
497 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400498}
499
Mike Lockwoodff164a72010-07-15 15:01:17 -0400500#endif // HAVE_ANDROID_OS
501
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400502// ----------------------------------------------------------------------------
503
504static void
505android_media_MtpDatabase_setup(JNIEnv *env, jobject thiz)
506{
Mike Lockwoodff164a72010-07-15 15:01:17 -0400507#ifdef HAVE_ANDROID_OS
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400508 LOGD("setup\n");
509 MyMtpDatabase* database = new MyMtpDatabase(env, thiz);
510 env->SetIntField(thiz, field_context, (int)database);
511 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodff164a72010-07-15 15:01:17 -0400512#endif
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400513}
514
515static void
516android_media_MtpDatabase_finalize(JNIEnv *env, jobject thiz)
517{
Mike Lockwoodff164a72010-07-15 15:01:17 -0400518#ifdef HAVE_ANDROID_OS
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400519 LOGD("finalize\n");
520 MyMtpDatabase* database = (MyMtpDatabase *)env->GetIntField(thiz, field_context);
521 database->cleanup(env);
522 delete database;
523 env->SetIntField(thiz, field_context, 0);
524 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodff164a72010-07-15 15:01:17 -0400525#endif
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400526}
527
528// ----------------------------------------------------------------------------
529
530static JNINativeMethod gMethods[] = {
531 {"native_setup", "()V", (void *)android_media_MtpDatabase_setup},
532 {"native_finalize", "()V", (void *)android_media_MtpDatabase_finalize},
533};
534
535static const char* const kClassPathName = "android/media/MtpDatabase";
536
537int register_android_media_MtpDatabase(JNIEnv *env)
538{
539 jclass clazz;
540
541 LOGD("register_android_media_MtpDatabase\n");
542
543 clazz = env->FindClass("android/media/MtpDatabase");
544 if (clazz == NULL) {
545 LOGE("Can't find android/media/MtpDatabase");
546 return -1;
547 }
Mike Lockwoodd815f792010-07-12 08:49:01 -0400548 method_beginSendObject = env->GetMethodID(clazz, "beginSendObject", "(Ljava/lang/String;IIIJJ)I");
549 if (method_beginSendObject == NULL) {
550 LOGE("Can't find beginSendObject");
551 return -1;
552 }
553 method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIZ)V");
554 if (method_endSendObject == NULL) {
555 LOGE("Can't find endSendObject");
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400556 return -1;
557 }
558 method_getObjectList = env->GetMethodID(clazz, "getObjectList", "(III)[I");
559 if (method_getObjectList == NULL) {
560 LOGE("Can't find getObjectList");
561 return -1;
562 }
Mike Lockwood7a047c82010-08-02 10:52:20 -0400563 method_getNumObjects = env->GetMethodID(clazz, "getNumObjects", "(III)I");
564 if (method_getNumObjects == NULL) {
565 LOGE("Can't find getNumObjects");
566 return -1;
567 }
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400568 method_getSupportedPlaybackFormats = env->GetMethodID(clazz, "getSupportedPlaybackFormats", "()[I");
569 if (method_getSupportedPlaybackFormats == NULL) {
570 LOGE("Can't find getSupportedPlaybackFormats");
571 return -1;
572 }
573 method_getSupportedCaptureFormats = env->GetMethodID(clazz, "getSupportedCaptureFormats", "()[I");
574 if (method_getSupportedCaptureFormats == NULL) {
575 LOGE("Can't find getSupportedCaptureFormats");
576 return -1;
577 }
578 method_getSupportedObjectProperties = env->GetMethodID(clazz, "getSupportedObjectProperties", "(I)[I");
579 if (method_getSupportedObjectProperties == NULL) {
580 LOGE("Can't find getSupportedObjectProperties");
581 return -1;
582 }
583 method_getSupportedDeviceProperties = env->GetMethodID(clazz, "getSupportedDeviceProperties", "()[I");
584 if (method_getSupportedDeviceProperties == NULL) {
585 LOGE("Can't find getSupportedDeviceProperties");
586 return -1;
587 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400588 method_getObjectProperty = env->GetMethodID(clazz, "getObjectProperty", "(II[J[C)I");
589 if (method_getObjectProperty == NULL) {
590 LOGE("Can't find getObjectProperty");
591 return -1;
592 }
593 method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z");
594 if (method_getObjectInfo == NULL) {
595 LOGE("Can't find getObjectInfo");
596 return -1;
597 }
Mike Lockwood59c777a2010-08-02 10:37:41 -0400598 method_getObjectFilePath = env->GetMethodID(clazz, "getObjectFilePath", "(I[C[J)I");
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400599 if (method_getObjectFilePath == NULL) {
600 LOGE("Can't find getObjectFilePath");
601 return -1;
602 }
Mike Lockwood59c777a2010-08-02 10:37:41 -0400603 method_deleteFile = env->GetMethodID(clazz, "deleteFile", "(I)I");
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400604 if (method_deleteFile == NULL) {
605 LOGE("Can't find deleteFile");
606 return -1;
607 }
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400608 method_getObjectReferences = env->GetMethodID(clazz, "getObjectReferences", "(I)[I");
609 if (method_getObjectReferences == NULL) {
610 LOGE("Can't find getObjectReferences");
611 return -1;
612 }
613 method_setObjectReferences = env->GetMethodID(clazz, "setObjectReferences", "(I[I)I");
614 if (method_setObjectReferences == NULL) {
615 LOGE("Can't find setObjectReferences");
616 return -1;
617 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400618 field_context = env->GetFieldID(clazz, "mNativeContext", "I");
619 if (field_context == NULL) {
620 LOGE("Can't find MtpDatabase.mNativeContext");
621 return -1;
622 }
623
624 return AndroidRuntime::registerNativeMethods(env,
625 "android/media/MtpDatabase", gMethods, NELEM(gMethods));
626}