blob: bc65de5bd55944e5f82470b45171bad1db1f1b91 [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"
Mike Lockwood9df53fae2011-04-21 17:05:55 -070032#include "MtpObjectInfo.h"
Mike Lockwood828d19d2010-08-10 15:20:35 -040033#include "MtpProperty.h"
Mike Lockwood59e3f0d2010-09-02 14:57:30 -040034#include "MtpStringBuffer.h"
Mike Lockwoodd21eac92010-07-03 00:44:05 -040035#include "MtpUtils.h"
36#include "mtp.h"
37
Mike Lockwoodc89f2222011-04-24 18:40:17 -070038extern "C" {
39#include "jhead.h"
40}
41
Mike Lockwoodd21eac92010-07-03 00:44:05 -040042using namespace android;
43
44// ----------------------------------------------------------------------------
45
Mike Lockwoodd815f792010-07-12 08:49:01 -040046static jmethodID method_beginSendObject;
47static jmethodID method_endSendObject;
Mike Lockwoodd21eac92010-07-03 00:44:05 -040048static jmethodID method_getObjectList;
Mike Lockwood7a047c82010-08-02 10:52:20 -040049static jmethodID method_getNumObjects;
Mike Lockwood4b322ce2010-08-10 07:37:50 -040050static jmethodID method_getSupportedPlaybackFormats;
51static jmethodID method_getSupportedCaptureFormats;
52static jmethodID method_getSupportedObjectProperties;
53static jmethodID method_getSupportedDeviceProperties;
Mike Lockwood828d19d2010-08-10 15:20:35 -040054static jmethodID method_setObjectProperty;
Mike Lockwood59e3f0d2010-09-02 14:57:30 -040055static jmethodID method_getDeviceProperty;
56static jmethodID method_setDeviceProperty;
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -040057static jmethodID method_getObjectPropertyList;
Mike Lockwoodd21eac92010-07-03 00:44:05 -040058static jmethodID method_getObjectInfo;
59static jmethodID method_getObjectFilePath;
60static jmethodID method_deleteFile;
Mike Lockwood9a2046f2010-08-03 15:30:09 -040061static jmethodID method_getObjectReferences;
62static jmethodID method_setObjectReferences;
Mike Lockwood2837eef2010-08-31 16:25:12 -040063static jmethodID method_sessionStarted;
64static jmethodID method_sessionEnded;
65
Mike Lockwoodd21eac92010-07-03 00:44:05 -040066static jfieldID field_context;
67
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -040068// MtpPropertyList fields
69static jfieldID field_mCount;
70static jfieldID field_mResult;
71static jfieldID field_mObjectHandles;
72static jfieldID field_mPropertyCodes;
73static jfieldID field_mDataTypes;
74static jfieldID field_mLongValues;
75static jfieldID field_mStringValues;
76
77
Mike Lockwoodd21eac92010-07-03 00:44:05 -040078MtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) {
79 return (MtpDatabase *)env->GetIntField(database, field_context);
80}
81
82// ----------------------------------------------------------------------------
83
84class MyMtpDatabase : public MtpDatabase {
85private:
86 jobject mDatabase;
87 jintArray mIntBuffer;
88 jlongArray mLongBuffer;
89 jcharArray mStringBuffer;
90
91public:
92 MyMtpDatabase(JNIEnv *env, jobject client);
93 virtual ~MyMtpDatabase();
94 void cleanup(JNIEnv *env);
95
Mike Lockwoodd815f792010-07-12 08:49:01 -040096 virtual MtpObjectHandle beginSendObject(const char* path,
Mike Lockwoodd21eac92010-07-03 00:44:05 -040097 MtpObjectFormat format,
98 MtpObjectHandle parent,
99 MtpStorageID storage,
100 uint64_t size,
101 time_t modified);
102
Mike Lockwoodd815f792010-07-12 08:49:01 -0400103 virtual void endSendObject(const char* path,
104 MtpObjectHandle handle,
105 MtpObjectFormat format,
106 bool succeeded);
107
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400108 virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID,
109 MtpObjectFormat format,
110 MtpObjectHandle parent);
111
Mike Lockwood7a047c82010-08-02 10:52:20 -0400112 virtual int getNumObjects(MtpStorageID storageID,
113 MtpObjectFormat format,
114 MtpObjectHandle parent);
115
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400116 // callee should delete[] the results from these
117 // results can be NULL
118 virtual MtpObjectFormatList* getSupportedPlaybackFormats();
119 virtual MtpObjectFormatList* getSupportedCaptureFormats();
120 virtual MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat format);
121 virtual MtpDevicePropertyList* getSupportedDeviceProperties();
122
Mike Lockwood828d19d2010-08-10 15:20:35 -0400123 virtual MtpResponseCode getObjectPropertyValue(MtpObjectHandle handle,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400124 MtpObjectProperty property,
125 MtpDataPacket& packet);
126
Mike Lockwood828d19d2010-08-10 15:20:35 -0400127 virtual MtpResponseCode setObjectPropertyValue(MtpObjectHandle handle,
128 MtpObjectProperty property,
129 MtpDataPacket& packet);
130
131 virtual MtpResponseCode getDevicePropertyValue(MtpDeviceProperty property,
132 MtpDataPacket& packet);
133
134 virtual MtpResponseCode setDevicePropertyValue(MtpDeviceProperty property,
135 MtpDataPacket& packet);
136
137 virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty property);
138
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400139 virtual MtpResponseCode getObjectPropertyList(MtpObjectHandle handle,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500140 uint32_t format, uint32_t property,
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400141 int groupCode, int depth,
142 MtpDataPacket& packet);
143
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400144 virtual MtpResponseCode getObjectInfo(MtpObjectHandle handle,
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700145 MtpObjectInfo& info);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400146
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700147 virtual void* getThumbnail(MtpObjectHandle handle, size_t& outThumbSize);
148
Mike Lockwood59c777a2010-08-02 10:37:41 -0400149 virtual MtpResponseCode getObjectFilePath(MtpObjectHandle handle,
Mike Lockwood365e03e2010-12-08 16:08:01 -0800150 MtpString& outFilePath,
151 int64_t& outFileLength,
152 MtpObjectFormat& outFormat);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400153 virtual MtpResponseCode deleteFile(MtpObjectHandle handle);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400154
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400155 bool getObjectPropertyInfo(MtpObjectProperty property, int& type);
156 bool getDevicePropertyInfo(MtpDeviceProperty property, int& type);
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400157
158 virtual MtpObjectHandleList* getObjectReferences(MtpObjectHandle handle);
159
160 virtual MtpResponseCode setObjectReferences(MtpObjectHandle handle,
161 MtpObjectHandleList* references);
Mike Lockwood828d19d2010-08-10 15:20:35 -0400162
163 virtual MtpProperty* getObjectPropertyDesc(MtpObjectProperty property,
164 MtpObjectFormat format);
165
166 virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property);
Mike Lockwood2837eef2010-08-31 16:25:12 -0400167
168 virtual void sessionStarted();
169
170 virtual void sessionEnded();
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400171};
172
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400173// ----------------------------------------------------------------------------
174
175static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
176 if (env->ExceptionCheck()) {
Steve Block3762c312012-01-06 19:20:56 +0000177 ALOGE("An exception was thrown by callback '%s'.", methodName);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400178 LOGE_EX(env);
179 env->ExceptionClear();
180 }
181}
182
183// ----------------------------------------------------------------------------
184
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400185MyMtpDatabase::MyMtpDatabase(JNIEnv *env, jobject client)
186 : mDatabase(env->NewGlobalRef(client)),
187 mIntBuffer(NULL),
188 mLongBuffer(NULL),
189 mStringBuffer(NULL)
190{
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400191 // create buffers for out arguments
192 // we don't need to be thread-safe so this is OK
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700193 jintArray intArray = env->NewIntArray(3);
194 if (!intArray) {
195 return; // Already threw.
196 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400197 mIntBuffer = (jintArray)env->NewGlobalRef(intArray);
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700198 jlongArray longArray = env->NewLongArray(2);
199 if (!longArray) {
200 return; // Already threw.
201 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400202 mLongBuffer = (jlongArray)env->NewGlobalRef(longArray);
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700203 jcharArray charArray = env->NewCharArray(256);
204 if (!charArray) {
205 return; // Already threw.
206 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400207 mStringBuffer = (jcharArray)env->NewGlobalRef(charArray);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400208}
209
210void MyMtpDatabase::cleanup(JNIEnv *env) {
211 env->DeleteGlobalRef(mDatabase);
212 env->DeleteGlobalRef(mIntBuffer);
213 env->DeleteGlobalRef(mLongBuffer);
214 env->DeleteGlobalRef(mStringBuffer);
215}
216
217MyMtpDatabase::~MyMtpDatabase() {
218}
219
Mike Lockwoodd815f792010-07-12 08:49:01 -0400220MtpObjectHandle MyMtpDatabase::beginSendObject(const char* path,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400221 MtpObjectFormat format,
222 MtpObjectHandle parent,
223 MtpStorageID storage,
224 uint64_t size,
225 time_t modified) {
226 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood88394712010-09-27 10:01:00 -0400227 jstring pathStr = env->NewStringUTF(path);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400228 MtpObjectHandle result = env->CallIntMethod(mDatabase, method_beginSendObject,
Mike Lockwood88394712010-09-27 10:01:00 -0400229 pathStr, (jint)format, (jint)parent, (jint)storage,
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400230 (jlong)size, (jlong)modified);
231
Mike Lockwood88394712010-09-27 10:01:00 -0400232 if (pathStr)
233 env->DeleteLocalRef(pathStr);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400234 checkAndClearExceptionFromCallback(env, __FUNCTION__);
235 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400236}
237
Mike Lockwoodd815f792010-07-12 08:49:01 -0400238void MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
Mike Lockwood7a0bd172011-01-18 11:06:19 -0800239 MtpObjectFormat format, bool succeeded) {
Mike Lockwoodd815f792010-07-12 08:49:01 -0400240 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood88394712010-09-27 10:01:00 -0400241 jstring pathStr = env->NewStringUTF(path);
242 env->CallVoidMethod(mDatabase, method_endSendObject, pathStr,
Mike Lockwood7a0bd172011-01-18 11:06:19 -0800243 (jint)handle, (jint)format, (jboolean)succeeded);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400244
Mike Lockwood88394712010-09-27 10:01:00 -0400245 if (pathStr)
246 env->DeleteLocalRef(pathStr);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400247 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodd815f792010-07-12 08:49:01 -0400248}
249
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400250MtpObjectHandleList* MyMtpDatabase::getObjectList(MtpStorageID storageID,
251 MtpObjectFormat format,
252 MtpObjectHandle parent) {
253 JNIEnv* env = AndroidRuntime::getJNIEnv();
254 jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectList,
255 (jint)storageID, (jint)format, (jint)parent);
256 if (!array)
257 return NULL;
258 MtpObjectHandleList* list = new MtpObjectHandleList();
259 jint* handles = env->GetIntArrayElements(array, 0);
260 jsize length = env->GetArrayLength(array);
Mike Lockwood7a047c82010-08-02 10:52:20 -0400261 for (int i = 0; i < length; i++)
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400262 list->push(handles[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400263 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400264 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400265
266 checkAndClearExceptionFromCallback(env, __FUNCTION__);
267 return list;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400268}
269
Mike Lockwood7a047c82010-08-02 10:52:20 -0400270int MyMtpDatabase::getNumObjects(MtpStorageID storageID,
271 MtpObjectFormat format,
272 MtpObjectHandle parent) {
273 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400274 int result = env->CallIntMethod(mDatabase, method_getNumObjects,
Mike Lockwood7a047c82010-08-02 10:52:20 -0400275 (jint)storageID, (jint)format, (jint)parent);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400276
277 checkAndClearExceptionFromCallback(env, __FUNCTION__);
278 return result;
Mike Lockwood7a047c82010-08-02 10:52:20 -0400279}
280
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400281MtpObjectFormatList* MyMtpDatabase::getSupportedPlaybackFormats() {
282 JNIEnv* env = AndroidRuntime::getJNIEnv();
283 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
284 method_getSupportedPlaybackFormats);
285 if (!array)
286 return NULL;
287 MtpObjectFormatList* list = new MtpObjectFormatList();
288 jint* formats = env->GetIntArrayElements(array, 0);
289 jsize length = env->GetArrayLength(array);
290 for (int i = 0; i < length; i++)
291 list->push(formats[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400292 env->ReleaseIntArrayElements(array, formats, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400293 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400294
295 checkAndClearExceptionFromCallback(env, __FUNCTION__);
296 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400297}
298
299MtpObjectFormatList* MyMtpDatabase::getSupportedCaptureFormats() {
300 JNIEnv* env = AndroidRuntime::getJNIEnv();
301 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
302 method_getSupportedCaptureFormats);
303 if (!array)
304 return NULL;
305 MtpObjectFormatList* list = new MtpObjectFormatList();
306 jint* formats = env->GetIntArrayElements(array, 0);
307 jsize length = env->GetArrayLength(array);
308 for (int i = 0; i < length; i++)
309 list->push(formats[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400310 env->ReleaseIntArrayElements(array, formats, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400311 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400312
313 checkAndClearExceptionFromCallback(env, __FUNCTION__);
314 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400315}
316
317MtpObjectPropertyList* MyMtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) {
318 JNIEnv* env = AndroidRuntime::getJNIEnv();
319 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
320 method_getSupportedObjectProperties, (jint)format);
321 if (!array)
322 return NULL;
323 MtpObjectPropertyList* list = new MtpObjectPropertyList();
324 jint* properties = env->GetIntArrayElements(array, 0);
325 jsize length = env->GetArrayLength(array);
326 for (int i = 0; i < length; i++)
327 list->push(properties[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400328 env->ReleaseIntArrayElements(array, properties, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400329 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400330
331 checkAndClearExceptionFromCallback(env, __FUNCTION__);
332 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400333}
334
335MtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
336 JNIEnv* env = AndroidRuntime::getJNIEnv();
337 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
338 method_getSupportedDeviceProperties);
339 if (!array)
340 return NULL;
341 MtpDevicePropertyList* list = new MtpDevicePropertyList();
342 jint* properties = env->GetIntArrayElements(array, 0);
343 jsize length = env->GetArrayLength(array);
344 for (int i = 0; i < length; i++)
345 list->push(properties[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400346 env->ReleaseIntArrayElements(array, properties, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400347 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400348
349 checkAndClearExceptionFromCallback(env, __FUNCTION__);
350 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400351}
352
Mike Lockwood828d19d2010-08-10 15:20:35 -0400353MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400354 MtpObjectProperty property,
355 MtpDataPacket& packet) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400356 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400357 jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500358 (jlong)handle, 0, (jlong)property, 0, 0);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400359 MtpResponseCode result = env->GetIntField(list, field_mResult);
360 int count = env->GetIntField(list, field_mCount);
361 if (result == MTP_RESPONSE_OK && count != 1)
362 result = MTP_RESPONSE_GENERAL_ERROR;
363
364 if (result == MTP_RESPONSE_OK) {
365 jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
366 jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
367 jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
368 jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
369 jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
370
371 jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
372 jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
373 jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
374 jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
375
376 int type = dataTypes[0];
377 jlong longValue = (longValues ? longValues[0] : 0);
378
379 // special case date properties, which are strings to MTP
380 // but stored internally as a uint64
381 if (property == MTP_PROPERTY_DATE_MODIFIED || property == MTP_PROPERTY_DATE_ADDED) {
382 char date[20];
383 formatDateTime(longValue, date, sizeof(date));
384 packet.putString(date);
385 goto out;
386 }
387 // release date is stored internally as just the year
388 if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) {
389 char date[20];
390 snprintf(date, sizeof(date), "%04lld0101T000000", longValue);
391 packet.putString(date);
392 goto out;
393 }
394
395 switch (type) {
396 case MTP_TYPE_INT8:
397 packet.putInt8(longValue);
398 break;
399 case MTP_TYPE_UINT8:
400 packet.putUInt8(longValue);
401 break;
402 case MTP_TYPE_INT16:
403 packet.putInt16(longValue);
404 break;
405 case MTP_TYPE_UINT16:
406 packet.putUInt16(longValue);
407 break;
408 case MTP_TYPE_INT32:
409 packet.putInt32(longValue);
410 break;
411 case MTP_TYPE_UINT32:
412 packet.putUInt32(longValue);
413 break;
414 case MTP_TYPE_INT64:
415 packet.putInt64(longValue);
416 break;
417 case MTP_TYPE_UINT64:
418 packet.putUInt64(longValue);
419 break;
420 case MTP_TYPE_INT128:
421 packet.putInt128(longValue);
422 break;
423 case MTP_TYPE_UINT128:
424 packet.putInt128(longValue);
425 break;
426 case MTP_TYPE_STR:
427 {
428 jstring stringValue = (jstring)env->GetObjectArrayElement(stringValuesArray, 0);
429 if (stringValue) {
430 const char* str = env->GetStringUTFChars(stringValue, NULL);
James Dong39774722011-04-06 11:57:48 -0700431 if (str == NULL) {
432 return MTP_RESPONSE_GENERAL_ERROR;
433 }
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400434 packet.putString(str);
435 env->ReleaseStringUTFChars(stringValue, str);
436 } else {
437 packet.putEmptyString();
438 }
439 break;
440 }
441 default:
Steve Block3762c312012-01-06 19:20:56 +0000442 ALOGE("unsupported type in getObjectPropertyValue\n");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400443 result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
444 }
445out:
446 env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
447 env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
448 env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
449 if (longValues)
450 env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
451
452 env->DeleteLocalRef(objectHandlesArray);
453 env->DeleteLocalRef(propertyCodesArray);
454 env->DeleteLocalRef(dataTypesArray);
455 if (longValuesArray)
456 env->DeleteLocalRef(longValuesArray);
457 if (stringValuesArray)
458 env->DeleteLocalRef(stringValuesArray);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400459 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400460
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400461 env->DeleteLocalRef(list);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400462 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400463 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400464}
465
Mike Lockwood828d19d2010-08-10 15:20:35 -0400466MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
467 MtpObjectProperty property,
468 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400469 int type;
470
471 if (!getObjectPropertyInfo(property, type))
472 return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
473
474 JNIEnv* env = AndroidRuntime::getJNIEnv();
475 jlong longValue = 0;
476 jstring stringValue = NULL;
477
478 switch (type) {
479 case MTP_TYPE_INT8:
480 longValue = packet.getInt8();
481 break;
482 case MTP_TYPE_UINT8:
483 longValue = packet.getUInt8();
484 break;
485 case MTP_TYPE_INT16:
486 longValue = packet.getInt16();
487 break;
488 case MTP_TYPE_UINT16:
489 longValue = packet.getUInt16();
490 break;
491 case MTP_TYPE_INT32:
492 longValue = packet.getInt32();
493 break;
494 case MTP_TYPE_UINT32:
495 longValue = packet.getUInt32();
496 break;
497 case MTP_TYPE_INT64:
498 longValue = packet.getInt64();
499 break;
500 case MTP_TYPE_UINT64:
501 longValue = packet.getUInt64();
502 break;
503 case MTP_TYPE_STR:
504 {
505 MtpStringBuffer buffer;
506 packet.getString(buffer);
507 stringValue = env->NewStringUTF((const char *)buffer);
508 break;
509 }
510 default:
Steve Block3762c312012-01-06 19:20:56 +0000511 ALOGE("unsupported type in getObjectPropertyValue\n");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400512 return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
513 }
514
515 jint result = env->CallIntMethod(mDatabase, method_setObjectProperty,
516 (jint)handle, (jint)property, longValue, stringValue);
Mike Lockwood88394712010-09-27 10:01:00 -0400517 if (stringValue)
518 env->DeleteLocalRef(stringValue);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400519
520 checkAndClearExceptionFromCallback(env, __FUNCTION__);
521 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400522}
523
524MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
525 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400526 int type;
527
528 if (!getDevicePropertyInfo(property, type))
529 return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
530
531 JNIEnv* env = AndroidRuntime::getJNIEnv();
532 jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
533 (jint)property, mLongBuffer, mStringBuffer);
534 if (result != MTP_RESPONSE_OK) {
535 checkAndClearExceptionFromCallback(env, __FUNCTION__);
536 return result;
537 }
538
539 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
540 jlong longValue = longValues[0];
541 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
542
543 switch (type) {
544 case MTP_TYPE_INT8:
545 packet.putInt8(longValue);
546 break;
547 case MTP_TYPE_UINT8:
548 packet.putUInt8(longValue);
549 break;
550 case MTP_TYPE_INT16:
551 packet.putInt16(longValue);
552 break;
553 case MTP_TYPE_UINT16:
554 packet.putUInt16(longValue);
555 break;
556 case MTP_TYPE_INT32:
557 packet.putInt32(longValue);
558 break;
559 case MTP_TYPE_UINT32:
560 packet.putUInt32(longValue);
561 break;
562 case MTP_TYPE_INT64:
563 packet.putInt64(longValue);
564 break;
565 case MTP_TYPE_UINT64:
566 packet.putUInt64(longValue);
567 break;
568 case MTP_TYPE_INT128:
569 packet.putInt128(longValue);
570 break;
571 case MTP_TYPE_UINT128:
572 packet.putInt128(longValue);
573 break;
574 case MTP_TYPE_STR:
575 {
576 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
577 packet.putString(str);
578 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
579 break;
580 }
581 default:
Steve Block3762c312012-01-06 19:20:56 +0000582 ALOGE("unsupported type in getDevicePropertyValue\n");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400583 return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
584 }
585
586 checkAndClearExceptionFromCallback(env, __FUNCTION__);
587 return MTP_RESPONSE_OK;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400588}
589
590MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
591 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400592 int type;
593
594 if (!getDevicePropertyInfo(property, type))
595 return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
596
597 JNIEnv* env = AndroidRuntime::getJNIEnv();
598 jlong longValue = 0;
599 jstring stringValue = NULL;
600
601 switch (type) {
602 case MTP_TYPE_INT8:
603 longValue = packet.getInt8();
604 break;
605 case MTP_TYPE_UINT8:
606 longValue = packet.getUInt8();
607 break;
608 case MTP_TYPE_INT16:
609 longValue = packet.getInt16();
610 break;
611 case MTP_TYPE_UINT16:
612 longValue = packet.getUInt16();
613 break;
614 case MTP_TYPE_INT32:
615 longValue = packet.getInt32();
616 break;
617 case MTP_TYPE_UINT32:
618 longValue = packet.getUInt32();
619 break;
620 case MTP_TYPE_INT64:
621 longValue = packet.getInt64();
622 break;
623 case MTP_TYPE_UINT64:
624 longValue = packet.getUInt64();
625 break;
626 case MTP_TYPE_STR:
627 {
628 MtpStringBuffer buffer;
629 packet.getString(buffer);
630 stringValue = env->NewStringUTF((const char *)buffer);
631 break;
632 }
633 default:
Steve Block3762c312012-01-06 19:20:56 +0000634 ALOGE("unsupported type in setDevicePropertyValue\n");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400635 return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
636 }
637
638 jint result = env->CallIntMethod(mDatabase, method_setDeviceProperty,
639 (jint)property, longValue, stringValue);
Mike Lockwood88394712010-09-27 10:01:00 -0400640 if (stringValue)
641 env->DeleteLocalRef(stringValue);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400642
643 checkAndClearExceptionFromCallback(env, __FUNCTION__);
644 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400645}
646
647MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty property) {
648 return -1;
649}
650
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400651MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500652 uint32_t format, uint32_t property,
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400653 int groupCode, int depth,
654 MtpDataPacket& packet) {
655 JNIEnv* env = AndroidRuntime::getJNIEnv();
656 jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500657 (jlong)handle, (jint)format, (jlong)property, (jint)groupCode, (jint)depth);
658 checkAndClearExceptionFromCallback(env, __FUNCTION__);
659 if (!list)
660 return MTP_RESPONSE_GENERAL_ERROR;
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400661 int count = env->GetIntField(list, field_mCount);
662 MtpResponseCode result = env->GetIntField(list, field_mResult);
663
664 packet.putUInt32(count);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400665 if (count > 0) {
666 jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
667 jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
668 jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
669 jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
670 jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
671
672 jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
673 jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
674 jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
675 jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
676
677 for (int i = 0; i < count; i++) {
678 packet.putUInt32(objectHandles[i]);
679 packet.putUInt16(propertyCodes[i]);
680 int type = dataTypes[i];
681 packet.putUInt16(type);
682
683 switch (type) {
684 case MTP_TYPE_INT8:
685 packet.putInt8(longValues[i]);
686 break;
687 case MTP_TYPE_UINT8:
688 packet.putUInt8(longValues[i]);
689 break;
690 case MTP_TYPE_INT16:
691 packet.putInt16(longValues[i]);
692 break;
693 case MTP_TYPE_UINT16:
694 packet.putUInt16(longValues[i]);
695 break;
696 case MTP_TYPE_INT32:
697 packet.putInt32(longValues[i]);
698 break;
699 case MTP_TYPE_UINT32:
700 packet.putUInt32(longValues[i]);
701 break;
702 case MTP_TYPE_INT64:
703 packet.putInt64(longValues[i]);
704 break;
705 case MTP_TYPE_UINT64:
706 packet.putUInt64(longValues[i]);
707 break;
708 case MTP_TYPE_INT128:
709 packet.putInt128(longValues[i]);
710 break;
711 case MTP_TYPE_UINT128:
712 packet.putUInt128(longValues[i]);
713 break;
714 case MTP_TYPE_STR: {
715 jstring value = (jstring)env->GetObjectArrayElement(stringValuesArray, i);
Mike Lockwood2711e492010-12-11 11:24:37 -0800716 const char *valueStr = (value ? env->GetStringUTFChars(value, NULL) : NULL);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400717 if (valueStr) {
718 packet.putString(valueStr);
719 env->ReleaseStringUTFChars(value, valueStr);
720 } else {
721 packet.putEmptyString();
722 }
723 env->DeleteLocalRef(value);
724 break;
725 }
726 default:
Steve Block3762c312012-01-06 19:20:56 +0000727 ALOGE("bad or unsupported data type in MyMtpDatabase::getObjectPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400728 break;
729 }
730 }
731
732 env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
733 env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
734 env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
735 if (longValues)
736 env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
737
738 env->DeleteLocalRef(objectHandlesArray);
739 env->DeleteLocalRef(propertyCodesArray);
740 env->DeleteLocalRef(dataTypesArray);
741 if (longValuesArray)
742 env->DeleteLocalRef(longValuesArray);
743 if (stringValuesArray)
744 env->DeleteLocalRef(stringValuesArray);
745 }
746
747 env->DeleteLocalRef(list);
748 checkAndClearExceptionFromCallback(env, __FUNCTION__);
749 return result;
750}
751
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400752MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700753 MtpObjectInfo& info) {
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700754 char date[20];
755 MtpString path;
756 int64_t length;
757 MtpObjectFormat format;
758
759 MtpResponseCode result = getObjectFilePath(handle, path, length, format);
760 if (result != MTP_RESPONSE_OK) {
761 return result;
762 }
763 info.mCompressedSize = (length > 0xFFFFFFFFLL ? 0xFFFFFFFF : (uint32_t)length);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400764
765 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700766 if (!env->CallBooleanMethod(mDatabase, method_getObjectInfo,
767 (jint)handle, mIntBuffer, mStringBuffer, mLongBuffer)) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400768 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700769 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400770
771 jint* intValues = env->GetIntArrayElements(mIntBuffer, 0);
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700772 info.mStorageID = intValues[0];
773 info.mFormat = intValues[1];
774 info.mParent = intValues[2];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400775 env->ReleaseIntArrayElements(mIntBuffer, intValues, 0);
776
777 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700778 info.mDateModified = longValues[0];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400779 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
780
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700781// info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ?
Mike Lockwood828d19d2010-08-10 15:20:35 -0400782// MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
783// MTP_ASSOCIATION_TYPE_UNDEFINED);
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700784 info.mAssociationType = MTP_ASSOCIATION_TYPE_UNDEFINED;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400785
786 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700787 MtpString temp(str);
788 info.mName = strdup((const char *)temp);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400789 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
790
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700791 // read EXIF data for thumbnail information
792 if (info.mFormat == MTP_FORMAT_EXIF_JPEG || info.mFormat == MTP_FORMAT_JFIF) {
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700793 ResetJpgfile();
794 // Start with an empty image information structure.
795 memset(&ImageInfo, 0, sizeof(ImageInfo));
796 ImageInfo.FlashUsed = -1;
797 ImageInfo.MeteringMode = -1;
798 ImageInfo.Whitebalance = -1;
799 strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
800 if (ReadJpegFile((const char*)path, READ_METADATA)) {
801 Section_t* section = FindSection(M_EXIF);
802 if (section) {
803 info.mThumbCompressedSize = ImageInfo.ThumbnailSize;
804 info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
805 info.mImagePixWidth = ImageInfo.Width;
806 info.mImagePixHeight = ImageInfo.Height;
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700807 }
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700808 }
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700809 DiscardData();
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700810 }
811
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400812 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400813 return MTP_RESPONSE_OK;
814}
815
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700816void* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) {
817 MtpString path;
818 int64_t length;
819 MtpObjectFormat format;
820 void* result = NULL;
821 outThumbSize = 0;
822
823 if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK
824 && (format == MTP_FORMAT_EXIF_JPEG || format == MTP_FORMAT_JFIF)) {
825 ResetJpgfile();
826 // Start with an empty image information structure.
827 memset(&ImageInfo, 0, sizeof(ImageInfo));
828 ImageInfo.FlashUsed = -1;
829 ImageInfo.MeteringMode = -1;
830 ImageInfo.Whitebalance = -1;
831 strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
832 if (ReadJpegFile((const char*)path, READ_METADATA)) {
833 Section_t* section = FindSection(M_EXIF);
834 if (section) {
835 outThumbSize = ImageInfo.ThumbnailSize;
836 result = malloc(outThumbSize);
837 if (result)
838 memcpy(result, section->Data + ImageInfo.ThumbnailOffset + 8, outThumbSize);
839 }
840 DiscardData();
841 }
842 }
843
844 return result;
845}
846
Mike Lockwood59c777a2010-08-02 10:37:41 -0400847MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle,
Mike Lockwood365e03e2010-12-08 16:08:01 -0800848 MtpString& outFilePath,
849 int64_t& outFileLength,
850 MtpObjectFormat& outFormat) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400851 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood59c777a2010-08-02 10:37:41 -0400852 jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400853 (jint)handle, mStringBuffer, mLongBuffer);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400854 if (result != MTP_RESPONSE_OK) {
855 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400856 return result;
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400857 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400858
859 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
Mike Lockwood365e03e2010-12-08 16:08:01 -0800860 outFilePath.setTo(str, strlen16(str));
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400861 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
862
863 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
Mike Lockwood365e03e2010-12-08 16:08:01 -0800864 outFileLength = longValues[0];
865 outFormat = longValues[1];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400866 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700867
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400868 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400869 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400870}
871
Mike Lockwood59c777a2010-08-02 10:37:41 -0400872MtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400873 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400874 MtpResponseCode result = env->CallIntMethod(mDatabase, method_deleteFile, (jint)handle);
875
876 checkAndClearExceptionFromCallback(env, __FUNCTION__);
877 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400878}
879
880struct PropertyTableEntry {
881 MtpObjectProperty property;
882 int type;
883};
884
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400885static const PropertyTableEntry kObjectPropertyTable[] = {
Mike Lockwoodd3bfecb2010-09-23 23:04:28 -0400886 { MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32 },
887 { MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16 },
888 { MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16 },
889 { MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64 },
890 { MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR },
891 { MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR },
892 { MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32 },
893 { MTP_PROPERTY_PERSISTENT_UID, MTP_TYPE_UINT128 },
894 { MTP_PROPERTY_NAME, MTP_TYPE_STR },
Mike Lockwoodae078f72010-09-26 12:35:51 -0400895 { MTP_PROPERTY_DISPLAY_NAME, MTP_TYPE_STR },
896 { MTP_PROPERTY_DATE_ADDED, MTP_TYPE_STR },
897 { MTP_PROPERTY_ARTIST, MTP_TYPE_STR },
898 { MTP_PROPERTY_ALBUM_NAME, MTP_TYPE_STR },
899 { MTP_PROPERTY_ALBUM_ARTIST, MTP_TYPE_STR },
900 { MTP_PROPERTY_TRACK, MTP_TYPE_UINT16 },
901 { MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_TYPE_STR },
902 { MTP_PROPERTY_GENRE, MTP_TYPE_STR },
903 { MTP_PROPERTY_COMPOSER, MTP_TYPE_STR },
904 { MTP_PROPERTY_DURATION, MTP_TYPE_UINT32 },
905 { MTP_PROPERTY_DESCRIPTION, MTP_TYPE_STR },
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400906};
907
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400908static const PropertyTableEntry kDevicePropertyTable[] = {
Mike Lockwoodea93fa12010-12-07 10:41:35 -0800909 { MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MTP_TYPE_STR },
910 { MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR },
911 { MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR },
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400912};
913
914bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
915 int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
916 const PropertyTableEntry* entry = kObjectPropertyTable;
917 for (int i = 0; i < count; i++, entry++) {
918 if (entry->property == property) {
919 type = entry->type;
920 return true;
921 }
922 }
923 return false;
924}
925
926bool MyMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) {
927 int count = sizeof(kDevicePropertyTable) / sizeof(kDevicePropertyTable[0]);
928 const PropertyTableEntry* entry = kDevicePropertyTable;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400929 for (int i = 0; i < count; i++, entry++) {
930 if (entry->property == property) {
931 type = entry->type;
932 return true;
933 }
934 }
935 return false;
936}
937
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400938MtpObjectHandleList* MyMtpDatabase::getObjectReferences(MtpObjectHandle handle) {
939 JNIEnv* env = AndroidRuntime::getJNIEnv();
940 jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectReferences,
941 (jint)handle);
942 if (!array)
943 return NULL;
944 MtpObjectHandleList* list = new MtpObjectHandleList();
945 jint* handles = env->GetIntArrayElements(array, 0);
946 jsize length = env->GetArrayLength(array);
947 for (int i = 0; i < length; i++)
948 list->push(handles[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400949 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400950 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400951
952 checkAndClearExceptionFromCallback(env, __FUNCTION__);
953 return list;
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400954}
955
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400956MtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle,
957 MtpObjectHandleList* references) {
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400958 JNIEnv* env = AndroidRuntime::getJNIEnv();
959 int count = references->size();
960 jintArray array = env->NewIntArray(count);
961 if (!array) {
Steve Block3762c312012-01-06 19:20:56 +0000962 ALOGE("out of memory in setObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400963 return false;
964 }
965 jint* handles = env->GetIntArrayElements(array, 0);
966 for (int i = 0; i < count; i++)
967 handles[i] = (*references)[i];
968 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400969 MtpResponseCode result = env->CallIntMethod(mDatabase, method_setObjectReferences,
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400970 (jint)handle, array);
Mike Lockwood88394712010-09-27 10:01:00 -0400971 env->DeleteLocalRef(array);
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400972
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400973 checkAndClearExceptionFromCallback(env, __FUNCTION__);
974 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400975}
976
Mike Lockwood828d19d2010-08-10 15:20:35 -0400977MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
978 MtpObjectFormat format) {
979 MtpProperty* result = NULL;
980 switch (property) {
981 case MTP_PROPERTY_OBJECT_FORMAT:
Mike Lockwood9b5e9c42010-12-07 18:53:50 -0800982 // use format as default value
983 result = new MtpProperty(property, MTP_TYPE_UINT16, false, format);
984 break;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400985 case MTP_PROPERTY_PROTECTION_STATUS:
Mike Lockwoodae078f72010-09-26 12:35:51 -0400986 case MTP_PROPERTY_TRACK:
Mike Lockwood828d19d2010-08-10 15:20:35 -0400987 result = new MtpProperty(property, MTP_TYPE_UINT16);
988 break;
989 case MTP_PROPERTY_STORAGE_ID:
990 case MTP_PROPERTY_PARENT_OBJECT:
Mike Lockwoodae078f72010-09-26 12:35:51 -0400991 case MTP_PROPERTY_DURATION:
Mike Lockwood828d19d2010-08-10 15:20:35 -0400992 result = new MtpProperty(property, MTP_TYPE_UINT32);
993 break;
994 case MTP_PROPERTY_OBJECT_SIZE:
995 result = new MtpProperty(property, MTP_TYPE_UINT64);
996 break;
997 case MTP_PROPERTY_PERSISTENT_UID:
998 result = new MtpProperty(property, MTP_TYPE_UINT128);
999 break;
Mike Lockwoodd3bfecb2010-09-23 23:04:28 -04001000 case MTP_PROPERTY_NAME:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001001 case MTP_PROPERTY_DISPLAY_NAME:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001002 case MTP_PROPERTY_ARTIST:
1003 case MTP_PROPERTY_ALBUM_NAME:
1004 case MTP_PROPERTY_ALBUM_ARTIST:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001005 case MTP_PROPERTY_GENRE:
1006 case MTP_PROPERTY_COMPOSER:
1007 case MTP_PROPERTY_DESCRIPTION:
Mike Lockwood828d19d2010-08-10 15:20:35 -04001008 result = new MtpProperty(property, MTP_TYPE_STR);
1009 break;
Mike Lockwood5b19af02010-11-23 18:38:55 -05001010 case MTP_PROPERTY_DATE_MODIFIED:
1011 case MTP_PROPERTY_DATE_ADDED:
1012 case MTP_PROPERTY_ORIGINAL_RELEASE_DATE:
1013 result = new MtpProperty(property, MTP_TYPE_STR);
1014 result->setFormDateTime();
1015 break;
Mike Lockwood5ebac832010-10-12 11:33:47 -04001016 case MTP_PROPERTY_OBJECT_FILE_NAME:
Mike Lockwood6a6a3af2010-10-12 14:19:51 -04001017 // We allow renaming files and folders
1018 result = new MtpProperty(property, MTP_TYPE_STR, true);
Mike Lockwood5ebac832010-10-12 11:33:47 -04001019 break;
Mike Lockwood828d19d2010-08-10 15:20:35 -04001020 }
1021
1022 return result;
1023}
1024
1025MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001026 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001027 MtpProperty* result = NULL;
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001028 bool writable = false;
1029
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001030 switch (property) {
1031 case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
1032 case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001033 writable = true;
1034 // fall through
1035 case MTP_DEVICE_PROPERTY_IMAGE_SIZE:
1036 result = new MtpProperty(property, MTP_TYPE_STR, writable);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001037
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001038 // get current value
Mike Lockwooda2a21282010-09-25 21:21:05 -04001039 jint ret = env->CallIntMethod(mDatabase, method_getDeviceProperty,
1040 (jint)property, mLongBuffer, mStringBuffer);
1041 if (ret == MTP_RESPONSE_OK) {
1042 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
1043 result->setCurrentValue(str);
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001044 // for read-only properties it is safe to assume current value is default value
1045 if (!writable)
1046 result->setDefaultValue(str);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001047 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
1048 } else {
Steve Block3762c312012-01-06 19:20:56 +00001049 ALOGE("unable to read device property, response: %04X", ret);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001050 }
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001051 break;
1052 }
1053
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001054 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001055 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -04001056}
1057
Mike Lockwood2837eef2010-08-31 16:25:12 -04001058void MyMtpDatabase::sessionStarted() {
1059 JNIEnv* env = AndroidRuntime::getJNIEnv();
1060 env->CallVoidMethod(mDatabase, method_sessionStarted);
1061 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1062}
1063
1064void MyMtpDatabase::sessionEnded() {
1065 JNIEnv* env = AndroidRuntime::getJNIEnv();
1066 env->CallVoidMethod(mDatabase, method_sessionEnded);
1067 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1068}
1069
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001070// ----------------------------------------------------------------------------
1071
1072static void
Mike Lockwood0cd01362010-12-30 11:54:33 -05001073android_mtp_MtpDatabase_setup(JNIEnv *env, jobject thiz)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001074{
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001075 MyMtpDatabase* database = new MyMtpDatabase(env, thiz);
1076 env->SetIntField(thiz, field_context, (int)database);
1077 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1078}
1079
1080static void
Mike Lockwood0cd01362010-12-30 11:54:33 -05001081android_mtp_MtpDatabase_finalize(JNIEnv *env, jobject thiz)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001082{
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001083 MyMtpDatabase* database = (MyMtpDatabase *)env->GetIntField(thiz, field_context);
1084 database->cleanup(env);
1085 delete database;
1086 env->SetIntField(thiz, field_context, 0);
1087 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1088}
1089
Mike Lockwood31599912010-11-15 13:43:30 -05001090static jstring
Mike Lockwood0cd01362010-12-30 11:54:33 -05001091android_mtp_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject thiz, jlong seconds)
Mike Lockwood31599912010-11-15 13:43:30 -05001092{
Mike Lockwood31599912010-11-15 13:43:30 -05001093 char date[20];
1094 formatDateTime(seconds, date, sizeof(date));
1095 return env->NewStringUTF(date);
Mike Lockwood31599912010-11-15 13:43:30 -05001096}
1097
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001098// ----------------------------------------------------------------------------
1099
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001100static JNINativeMethod gMtpDatabaseMethods[] = {
Mike Lockwood0cd01362010-12-30 11:54:33 -05001101 {"native_setup", "()V", (void *)android_mtp_MtpDatabase_setup},
1102 {"native_finalize", "()V", (void *)android_mtp_MtpDatabase_finalize},
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001103};
1104
1105static JNINativeMethod gMtpPropertyGroupMethods[] = {
Mike Lockwood31599912010-11-15 13:43:30 -05001106 {"format_date_time", "(J)Ljava/lang/String;",
Mike Lockwood0cd01362010-12-30 11:54:33 -05001107 (void *)android_mtp_MtpPropertyGroup_format_date_time},
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001108};
1109
Mike Lockwood0cd01362010-12-30 11:54:33 -05001110static const char* const kClassPathName = "android/mtp/MtpDatabase";
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001111
Mike Lockwood0cd01362010-12-30 11:54:33 -05001112int register_android_mtp_MtpDatabase(JNIEnv *env)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001113{
1114 jclass clazz;
1115
Mike Lockwood0cd01362010-12-30 11:54:33 -05001116 clazz = env->FindClass("android/mtp/MtpDatabase");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001117 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001118 ALOGE("Can't find android/mtp/MtpDatabase");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001119 return -1;
1120 }
Mike Lockwoodd815f792010-07-12 08:49:01 -04001121 method_beginSendObject = env->GetMethodID(clazz, "beginSendObject", "(Ljava/lang/String;IIIJJ)I");
1122 if (method_beginSendObject == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001123 ALOGE("Can't find beginSendObject");
Mike Lockwoodd815f792010-07-12 08:49:01 -04001124 return -1;
1125 }
Mike Lockwood7a0bd172011-01-18 11:06:19 -08001126 method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIZ)V");
Mike Lockwoodd815f792010-07-12 08:49:01 -04001127 if (method_endSendObject == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001128 ALOGE("Can't find endSendObject");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001129 return -1;
1130 }
1131 method_getObjectList = env->GetMethodID(clazz, "getObjectList", "(III)[I");
1132 if (method_getObjectList == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001133 ALOGE("Can't find getObjectList");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001134 return -1;
1135 }
Mike Lockwood7a047c82010-08-02 10:52:20 -04001136 method_getNumObjects = env->GetMethodID(clazz, "getNumObjects", "(III)I");
1137 if (method_getNumObjects == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001138 ALOGE("Can't find getNumObjects");
Mike Lockwood7a047c82010-08-02 10:52:20 -04001139 return -1;
1140 }
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001141 method_getSupportedPlaybackFormats = env->GetMethodID(clazz, "getSupportedPlaybackFormats", "()[I");
1142 if (method_getSupportedPlaybackFormats == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001143 ALOGE("Can't find getSupportedPlaybackFormats");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001144 return -1;
1145 }
1146 method_getSupportedCaptureFormats = env->GetMethodID(clazz, "getSupportedCaptureFormats", "()[I");
1147 if (method_getSupportedCaptureFormats == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001148 ALOGE("Can't find getSupportedCaptureFormats");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001149 return -1;
1150 }
1151 method_getSupportedObjectProperties = env->GetMethodID(clazz, "getSupportedObjectProperties", "(I)[I");
1152 if (method_getSupportedObjectProperties == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001153 ALOGE("Can't find getSupportedObjectProperties");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001154 return -1;
1155 }
1156 method_getSupportedDeviceProperties = env->GetMethodID(clazz, "getSupportedDeviceProperties", "()[I");
1157 if (method_getSupportedDeviceProperties == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001158 ALOGE("Can't find getSupportedDeviceProperties");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001159 return -1;
1160 }
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001161 method_setObjectProperty = env->GetMethodID(clazz, "setObjectProperty", "(IIJLjava/lang/String;)I");
1162 if (method_setObjectProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001163 ALOGE("Can't find setObjectProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001164 return -1;
1165 }
1166 method_getDeviceProperty = env->GetMethodID(clazz, "getDeviceProperty", "(I[J[C)I");
1167 if (method_getDeviceProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001168 ALOGE("Can't find getDeviceProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001169 return -1;
1170 }
1171 method_setDeviceProperty = env->GetMethodID(clazz, "setDeviceProperty", "(IJLjava/lang/String;)I");
1172 if (method_setDeviceProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001173 ALOGE("Can't find setDeviceProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001174 return -1;
1175 }
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001176 method_getObjectPropertyList = env->GetMethodID(clazz, "getObjectPropertyList",
Mike Lockwood0cd01362010-12-30 11:54:33 -05001177 "(JIJII)Landroid/mtp/MtpPropertyList;");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001178 if (method_getObjectPropertyList == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001179 ALOGE("Can't find getObjectPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001180 return -1;
1181 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001182 method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z");
1183 if (method_getObjectInfo == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001184 ALOGE("Can't find getObjectInfo");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001185 return -1;
1186 }
Mike Lockwood59c777a2010-08-02 10:37:41 -04001187 method_getObjectFilePath = env->GetMethodID(clazz, "getObjectFilePath", "(I[C[J)I");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001188 if (method_getObjectFilePath == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001189 ALOGE("Can't find getObjectFilePath");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001190 return -1;
1191 }
Mike Lockwood59c777a2010-08-02 10:37:41 -04001192 method_deleteFile = env->GetMethodID(clazz, "deleteFile", "(I)I");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001193 if (method_deleteFile == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001194 ALOGE("Can't find deleteFile");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001195 return -1;
1196 }
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001197 method_getObjectReferences = env->GetMethodID(clazz, "getObjectReferences", "(I)[I");
1198 if (method_getObjectReferences == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001199 ALOGE("Can't find getObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001200 return -1;
1201 }
1202 method_setObjectReferences = env->GetMethodID(clazz, "setObjectReferences", "(I[I)I");
1203 if (method_setObjectReferences == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001204 ALOGE("Can't find setObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001205 return -1;
1206 }
Mike Lockwood2837eef2010-08-31 16:25:12 -04001207 method_sessionStarted = env->GetMethodID(clazz, "sessionStarted", "()V");
1208 if (method_sessionStarted == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001209 ALOGE("Can't find sessionStarted");
Mike Lockwood2837eef2010-08-31 16:25:12 -04001210 return -1;
1211 }
1212 method_sessionEnded = env->GetMethodID(clazz, "sessionEnded", "()V");
1213 if (method_sessionEnded == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001214 ALOGE("Can't find sessionEnded");
Mike Lockwood2837eef2010-08-31 16:25:12 -04001215 return -1;
1216 }
1217
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001218 field_context = env->GetFieldID(clazz, "mNativeContext", "I");
1219 if (field_context == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001220 ALOGE("Can't find MtpDatabase.mNativeContext");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001221 return -1;
1222 }
1223
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001224 // now set up fields for MtpPropertyList class
Mike Lockwood0cd01362010-12-30 11:54:33 -05001225 clazz = env->FindClass("android/mtp/MtpPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001226 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001227 ALOGE("Can't find android/mtp/MtpPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001228 return -1;
1229 }
1230 field_mCount = env->GetFieldID(clazz, "mCount", "I");
1231 if (field_mCount == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001232 ALOGE("Can't find MtpPropertyList.mCount");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001233 return -1;
1234 }
1235 field_mResult = env->GetFieldID(clazz, "mResult", "I");
1236 if (field_mResult == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001237 ALOGE("Can't find MtpPropertyList.mResult");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001238 return -1;
1239 }
1240 field_mObjectHandles = env->GetFieldID(clazz, "mObjectHandles", "[I");
1241 if (field_mObjectHandles == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001242 ALOGE("Can't find MtpPropertyList.mObjectHandles");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001243 return -1;
1244 }
1245 field_mPropertyCodes = env->GetFieldID(clazz, "mPropertyCodes", "[I");
1246 if (field_mPropertyCodes == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001247 ALOGE("Can't find MtpPropertyList.mPropertyCodes");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001248 return -1;
1249 }
1250 field_mDataTypes = env->GetFieldID(clazz, "mDataTypes", "[I");
1251 if (field_mDataTypes == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001252 ALOGE("Can't find MtpPropertyList.mDataTypes");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001253 return -1;
1254 }
1255 field_mLongValues = env->GetFieldID(clazz, "mLongValues", "[J");
1256 if (field_mLongValues == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001257 ALOGE("Can't find MtpPropertyList.mLongValues");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001258 return -1;
1259 }
1260 field_mStringValues = env->GetFieldID(clazz, "mStringValues", "[Ljava/lang/String;");
1261 if (field_mStringValues == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001262 ALOGE("Can't find MtpPropertyList.mStringValues");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001263 return -1;
1264 }
1265
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001266 if (AndroidRuntime::registerNativeMethods(env,
Mike Lockwood0cd01362010-12-30 11:54:33 -05001267 "android/mtp/MtpDatabase", gMtpDatabaseMethods, NELEM(gMtpDatabaseMethods)))
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001268 return -1;
1269
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001270 return AndroidRuntime::registerNativeMethods(env,
Mike Lockwood0cd01362010-12-30 11:54:33 -05001271 "android/mtp/MtpPropertyGroup", gMtpPropertyGroupMethods, NELEM(gMtpPropertyGroupMethods));
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001272}