blob: 82c00966e6428a8159ec4d6aa215938a27aedf5b [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
Mike Lockwoodd21eac92010-07-03 00:44:05 -040020#include <assert.h>
Mike Lockwoodd21eac92010-07-03 00:44:05 -040021#include <fcntl.h>
Mark Salyzynaeb75fc2014-03-20 12:09:01 -070022#include <inttypes.h>
23#include <limits.h>
24#include <stdio.h>
25#include <unistd.h>
Mike Lockwoodd21eac92010-07-03 00:44:05 -040026
27#include "jni.h"
28#include "JNIHelp.h"
29#include "android_runtime/AndroidRuntime.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070030#include "android_runtime/Log.h"
Mike Lockwoodd21eac92010-07-03 00:44:05 -040031
32#include "MtpDatabase.h"
33#include "MtpDataPacket.h"
Mike Lockwood9df53fae2011-04-21 17:05:55 -070034#include "MtpObjectInfo.h"
Mike Lockwood828d19d2010-08-10 15:20:35 -040035#include "MtpProperty.h"
Mike Lockwood59e3f0d2010-09-02 14:57:30 -040036#include "MtpStringBuffer.h"
Mike Lockwoodd21eac92010-07-03 00:44:05 -040037#include "MtpUtils.h"
38#include "mtp.h"
39
Mike Lockwoodc89f2222011-04-24 18:40:17 -070040extern "C" {
Marco Nelissenaefa4272014-01-10 10:39:27 -080041#include "libexif/exif-content.h"
42#include "libexif/exif-data.h"
43#include "libexif/exif-tag.h"
44#include "libexif/exif-utils.h"
Mike Lockwoodc89f2222011-04-24 18:40:17 -070045}
46
Mike Lockwoodd21eac92010-07-03 00:44:05 -040047using namespace android;
48
49// ----------------------------------------------------------------------------
50
Mike Lockwoodd815f792010-07-12 08:49:01 -040051static jmethodID method_beginSendObject;
52static jmethodID method_endSendObject;
Mike Lockwoodd21eac92010-07-03 00:44:05 -040053static jmethodID method_getObjectList;
Mike Lockwood7a047c82010-08-02 10:52:20 -040054static jmethodID method_getNumObjects;
Mike Lockwood4b322ce2010-08-10 07:37:50 -040055static jmethodID method_getSupportedPlaybackFormats;
56static jmethodID method_getSupportedCaptureFormats;
57static jmethodID method_getSupportedObjectProperties;
58static jmethodID method_getSupportedDeviceProperties;
Mike Lockwood828d19d2010-08-10 15:20:35 -040059static jmethodID method_setObjectProperty;
Mike Lockwood59e3f0d2010-09-02 14:57:30 -040060static jmethodID method_getDeviceProperty;
61static jmethodID method_setDeviceProperty;
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -040062static jmethodID method_getObjectPropertyList;
Mike Lockwoodd21eac92010-07-03 00:44:05 -040063static jmethodID method_getObjectInfo;
64static jmethodID method_getObjectFilePath;
65static jmethodID method_deleteFile;
Mike Lockwood9a2046f2010-08-03 15:30:09 -040066static jmethodID method_getObjectReferences;
67static jmethodID method_setObjectReferences;
Mike Lockwood2837eef2010-08-31 16:25:12 -040068static jmethodID method_sessionStarted;
69static jmethodID method_sessionEnded;
70
Mike Lockwoodd21eac92010-07-03 00:44:05 -040071static jfieldID field_context;
72
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -040073// MtpPropertyList fields
74static jfieldID field_mCount;
75static jfieldID field_mResult;
76static jfieldID field_mObjectHandles;
77static jfieldID field_mPropertyCodes;
78static jfieldID field_mDataTypes;
79static jfieldID field_mLongValues;
80static jfieldID field_mStringValues;
81
82
Mike Lockwoodd21eac92010-07-03 00:44:05 -040083MtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) {
Ashok Bhate2e59322013-12-17 19:04:19 +000084 return (MtpDatabase *)env->GetLongField(database, field_context);
Mike Lockwoodd21eac92010-07-03 00:44:05 -040085}
86
87// ----------------------------------------------------------------------------
88
89class MyMtpDatabase : public MtpDatabase {
90private:
91 jobject mDatabase;
92 jintArray mIntBuffer;
93 jlongArray mLongBuffer;
94 jcharArray mStringBuffer;
95
96public:
97 MyMtpDatabase(JNIEnv *env, jobject client);
98 virtual ~MyMtpDatabase();
99 void cleanup(JNIEnv *env);
100
Mike Lockwoodd815f792010-07-12 08:49:01 -0400101 virtual MtpObjectHandle beginSendObject(const char* path,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400102 MtpObjectFormat format,
103 MtpObjectHandle parent,
104 MtpStorageID storage,
105 uint64_t size,
106 time_t modified);
107
Mike Lockwoodd815f792010-07-12 08:49:01 -0400108 virtual void endSendObject(const char* path,
109 MtpObjectHandle handle,
110 MtpObjectFormat format,
111 bool succeeded);
112
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400113 virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID,
114 MtpObjectFormat format,
115 MtpObjectHandle parent);
116
Mike Lockwood7a047c82010-08-02 10:52:20 -0400117 virtual int getNumObjects(MtpStorageID storageID,
118 MtpObjectFormat format,
119 MtpObjectHandle parent);
120
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400121 // callee should delete[] the results from these
122 // results can be NULL
123 virtual MtpObjectFormatList* getSupportedPlaybackFormats();
124 virtual MtpObjectFormatList* getSupportedCaptureFormats();
125 virtual MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat format);
126 virtual MtpDevicePropertyList* getSupportedDeviceProperties();
127
Mike Lockwood828d19d2010-08-10 15:20:35 -0400128 virtual MtpResponseCode getObjectPropertyValue(MtpObjectHandle handle,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400129 MtpObjectProperty property,
130 MtpDataPacket& packet);
131
Mike Lockwood828d19d2010-08-10 15:20:35 -0400132 virtual MtpResponseCode setObjectPropertyValue(MtpObjectHandle handle,
133 MtpObjectProperty property,
134 MtpDataPacket& packet);
135
136 virtual MtpResponseCode getDevicePropertyValue(MtpDeviceProperty property,
137 MtpDataPacket& packet);
138
139 virtual MtpResponseCode setDevicePropertyValue(MtpDeviceProperty property,
140 MtpDataPacket& packet);
141
142 virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty property);
143
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400144 virtual MtpResponseCode getObjectPropertyList(MtpObjectHandle handle,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500145 uint32_t format, uint32_t property,
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400146 int groupCode, int depth,
147 MtpDataPacket& packet);
148
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400149 virtual MtpResponseCode getObjectInfo(MtpObjectHandle handle,
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700150 MtpObjectInfo& info);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400151
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700152 virtual void* getThumbnail(MtpObjectHandle handle, size_t& outThumbSize);
153
Mike Lockwood59c777a2010-08-02 10:37:41 -0400154 virtual MtpResponseCode getObjectFilePath(MtpObjectHandle handle,
Mike Lockwood365e03e2010-12-08 16:08:01 -0800155 MtpString& outFilePath,
156 int64_t& outFileLength,
157 MtpObjectFormat& outFormat);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400158 virtual MtpResponseCode deleteFile(MtpObjectHandle handle);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400159
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400160 bool getObjectPropertyInfo(MtpObjectProperty property, int& type);
161 bool getDevicePropertyInfo(MtpDeviceProperty property, int& type);
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400162
163 virtual MtpObjectHandleList* getObjectReferences(MtpObjectHandle handle);
164
165 virtual MtpResponseCode setObjectReferences(MtpObjectHandle handle,
166 MtpObjectHandleList* references);
Mike Lockwood828d19d2010-08-10 15:20:35 -0400167
168 virtual MtpProperty* getObjectPropertyDesc(MtpObjectProperty property,
169 MtpObjectFormat format);
170
171 virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property);
Mike Lockwood2837eef2010-08-31 16:25:12 -0400172
173 virtual void sessionStarted();
174
175 virtual void sessionEnded();
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400176};
177
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400178// ----------------------------------------------------------------------------
179
180static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
181 if (env->ExceptionCheck()) {
Steve Block3762c312012-01-06 19:20:56 +0000182 ALOGE("An exception was thrown by callback '%s'.", methodName);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400183 LOGE_EX(env);
184 env->ExceptionClear();
185 }
186}
187
188// ----------------------------------------------------------------------------
189
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400190MyMtpDatabase::MyMtpDatabase(JNIEnv *env, jobject client)
191 : mDatabase(env->NewGlobalRef(client)),
192 mIntBuffer(NULL),
193 mLongBuffer(NULL),
194 mStringBuffer(NULL)
195{
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400196 // create buffers for out arguments
197 // we don't need to be thread-safe so this is OK
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700198 jintArray intArray = env->NewIntArray(3);
199 if (!intArray) {
200 return; // Already threw.
201 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400202 mIntBuffer = (jintArray)env->NewGlobalRef(intArray);
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700203 jlongArray longArray = env->NewLongArray(2);
204 if (!longArray) {
205 return; // Already threw.
206 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400207 mLongBuffer = (jlongArray)env->NewGlobalRef(longArray);
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700208 jcharArray charArray = env->NewCharArray(256);
209 if (!charArray) {
210 return; // Already threw.
211 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400212 mStringBuffer = (jcharArray)env->NewGlobalRef(charArray);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400213}
214
215void MyMtpDatabase::cleanup(JNIEnv *env) {
216 env->DeleteGlobalRef(mDatabase);
217 env->DeleteGlobalRef(mIntBuffer);
218 env->DeleteGlobalRef(mLongBuffer);
219 env->DeleteGlobalRef(mStringBuffer);
220}
221
222MyMtpDatabase::~MyMtpDatabase() {
223}
224
Mike Lockwoodd815f792010-07-12 08:49:01 -0400225MtpObjectHandle MyMtpDatabase::beginSendObject(const char* path,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400226 MtpObjectFormat format,
227 MtpObjectHandle parent,
228 MtpStorageID storage,
229 uint64_t size,
230 time_t modified) {
231 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood88394712010-09-27 10:01:00 -0400232 jstring pathStr = env->NewStringUTF(path);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400233 MtpObjectHandle result = env->CallIntMethod(mDatabase, method_beginSendObject,
Mike Lockwood88394712010-09-27 10:01:00 -0400234 pathStr, (jint)format, (jint)parent, (jint)storage,
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400235 (jlong)size, (jlong)modified);
236
Mike Lockwood88394712010-09-27 10:01:00 -0400237 if (pathStr)
238 env->DeleteLocalRef(pathStr);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400239 checkAndClearExceptionFromCallback(env, __FUNCTION__);
240 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400241}
242
Mike Lockwoodd815f792010-07-12 08:49:01 -0400243void MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
Mike Lockwood7a0bd172011-01-18 11:06:19 -0800244 MtpObjectFormat format, bool succeeded) {
Mike Lockwoodd815f792010-07-12 08:49:01 -0400245 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood88394712010-09-27 10:01:00 -0400246 jstring pathStr = env->NewStringUTF(path);
247 env->CallVoidMethod(mDatabase, method_endSendObject, pathStr,
Mike Lockwood7a0bd172011-01-18 11:06:19 -0800248 (jint)handle, (jint)format, (jboolean)succeeded);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400249
Mike Lockwood88394712010-09-27 10:01:00 -0400250 if (pathStr)
251 env->DeleteLocalRef(pathStr);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400252 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodd815f792010-07-12 08:49:01 -0400253}
254
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400255MtpObjectHandleList* MyMtpDatabase::getObjectList(MtpStorageID storageID,
256 MtpObjectFormat format,
257 MtpObjectHandle parent) {
258 JNIEnv* env = AndroidRuntime::getJNIEnv();
259 jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectList,
260 (jint)storageID, (jint)format, (jint)parent);
261 if (!array)
262 return NULL;
263 MtpObjectHandleList* list = new MtpObjectHandleList();
264 jint* handles = env->GetIntArrayElements(array, 0);
265 jsize length = env->GetArrayLength(array);
Mike Lockwood7a047c82010-08-02 10:52:20 -0400266 for (int i = 0; i < length; i++)
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400267 list->push(handles[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400268 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400269 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400270
271 checkAndClearExceptionFromCallback(env, __FUNCTION__);
272 return list;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400273}
274
Mike Lockwood7a047c82010-08-02 10:52:20 -0400275int MyMtpDatabase::getNumObjects(MtpStorageID storageID,
276 MtpObjectFormat format,
277 MtpObjectHandle parent) {
278 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400279 int result = env->CallIntMethod(mDatabase, method_getNumObjects,
Mike Lockwood7a047c82010-08-02 10:52:20 -0400280 (jint)storageID, (jint)format, (jint)parent);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400281
282 checkAndClearExceptionFromCallback(env, __FUNCTION__);
283 return result;
Mike Lockwood7a047c82010-08-02 10:52:20 -0400284}
285
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400286MtpObjectFormatList* MyMtpDatabase::getSupportedPlaybackFormats() {
287 JNIEnv* env = AndroidRuntime::getJNIEnv();
288 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
289 method_getSupportedPlaybackFormats);
290 if (!array)
291 return NULL;
292 MtpObjectFormatList* list = new MtpObjectFormatList();
293 jint* formats = env->GetIntArrayElements(array, 0);
294 jsize length = env->GetArrayLength(array);
295 for (int i = 0; i < length; i++)
296 list->push(formats[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400297 env->ReleaseIntArrayElements(array, formats, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400298 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400299
300 checkAndClearExceptionFromCallback(env, __FUNCTION__);
301 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400302}
303
304MtpObjectFormatList* MyMtpDatabase::getSupportedCaptureFormats() {
305 JNIEnv* env = AndroidRuntime::getJNIEnv();
306 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
307 method_getSupportedCaptureFormats);
308 if (!array)
309 return NULL;
310 MtpObjectFormatList* list = new MtpObjectFormatList();
311 jint* formats = env->GetIntArrayElements(array, 0);
312 jsize length = env->GetArrayLength(array);
313 for (int i = 0; i < length; i++)
314 list->push(formats[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400315 env->ReleaseIntArrayElements(array, formats, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400316 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400317
318 checkAndClearExceptionFromCallback(env, __FUNCTION__);
319 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400320}
321
322MtpObjectPropertyList* MyMtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) {
323 JNIEnv* env = AndroidRuntime::getJNIEnv();
324 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
325 method_getSupportedObjectProperties, (jint)format);
326 if (!array)
327 return NULL;
328 MtpObjectPropertyList* list = new MtpObjectPropertyList();
329 jint* properties = env->GetIntArrayElements(array, 0);
330 jsize length = env->GetArrayLength(array);
331 for (int i = 0; i < length; i++)
332 list->push(properties[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400333 env->ReleaseIntArrayElements(array, properties, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400334 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400335
336 checkAndClearExceptionFromCallback(env, __FUNCTION__);
337 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400338}
339
340MtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
341 JNIEnv* env = AndroidRuntime::getJNIEnv();
342 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
343 method_getSupportedDeviceProperties);
344 if (!array)
345 return NULL;
346 MtpDevicePropertyList* list = new MtpDevicePropertyList();
347 jint* properties = env->GetIntArrayElements(array, 0);
348 jsize length = env->GetArrayLength(array);
349 for (int i = 0; i < length; i++)
350 list->push(properties[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400351 env->ReleaseIntArrayElements(array, properties, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400352 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400353
354 checkAndClearExceptionFromCallback(env, __FUNCTION__);
355 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400356}
357
Mike Lockwood828d19d2010-08-10 15:20:35 -0400358MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400359 MtpObjectProperty property,
360 MtpDataPacket& packet) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400361 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400362 jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500363 (jlong)handle, 0, (jlong)property, 0, 0);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400364 MtpResponseCode result = env->GetIntField(list, field_mResult);
365 int count = env->GetIntField(list, field_mCount);
366 if (result == MTP_RESPONSE_OK && count != 1)
367 result = MTP_RESPONSE_GENERAL_ERROR;
368
369 if (result == MTP_RESPONSE_OK) {
370 jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
371 jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
372 jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
373 jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
374 jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
375
376 jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
377 jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
378 jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
379 jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
380
381 int type = dataTypes[0];
382 jlong longValue = (longValues ? longValues[0] : 0);
383
384 // special case date properties, which are strings to MTP
385 // but stored internally as a uint64
386 if (property == MTP_PROPERTY_DATE_MODIFIED || property == MTP_PROPERTY_DATE_ADDED) {
387 char date[20];
388 formatDateTime(longValue, date, sizeof(date));
389 packet.putString(date);
390 goto out;
391 }
392 // release date is stored internally as just the year
393 if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) {
394 char date[20];
Mark Salyzynaeb75fc2014-03-20 12:09:01 -0700395 snprintf(date, sizeof(date), "%04" PRId64 "0101T000000", longValue);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400396 packet.putString(date);
397 goto out;
398 }
399
400 switch (type) {
401 case MTP_TYPE_INT8:
402 packet.putInt8(longValue);
403 break;
404 case MTP_TYPE_UINT8:
405 packet.putUInt8(longValue);
406 break;
407 case MTP_TYPE_INT16:
408 packet.putInt16(longValue);
409 break;
410 case MTP_TYPE_UINT16:
411 packet.putUInt16(longValue);
412 break;
413 case MTP_TYPE_INT32:
414 packet.putInt32(longValue);
415 break;
416 case MTP_TYPE_UINT32:
417 packet.putUInt32(longValue);
418 break;
419 case MTP_TYPE_INT64:
420 packet.putInt64(longValue);
421 break;
422 case MTP_TYPE_UINT64:
423 packet.putUInt64(longValue);
424 break;
425 case MTP_TYPE_INT128:
426 packet.putInt128(longValue);
427 break;
428 case MTP_TYPE_UINT128:
429 packet.putInt128(longValue);
430 break;
431 case MTP_TYPE_STR:
432 {
433 jstring stringValue = (jstring)env->GetObjectArrayElement(stringValuesArray, 0);
Martin Blumenstingl17a24c52014-05-31 15:50:38 +0200434 const char* str = (stringValue ? env->GetStringUTFChars(stringValue, NULL) : NULL);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400435 if (stringValue) {
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400436 packet.putString(str);
437 env->ReleaseStringUTFChars(stringValue, str);
438 } else {
439 packet.putEmptyString();
440 }
Martin Blumenstingl17a24c52014-05-31 15:50:38 +0200441 env->DeleteLocalRef(stringValue);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400442 break;
443 }
444 default:
Steve Block3762c312012-01-06 19:20:56 +0000445 ALOGE("unsupported type in getObjectPropertyValue\n");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400446 result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
447 }
448out:
449 env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
450 env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
451 env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
452 if (longValues)
453 env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
454
455 env->DeleteLocalRef(objectHandlesArray);
456 env->DeleteLocalRef(propertyCodesArray);
457 env->DeleteLocalRef(dataTypesArray);
458 if (longValuesArray)
459 env->DeleteLocalRef(longValuesArray);
460 if (stringValuesArray)
461 env->DeleteLocalRef(stringValuesArray);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400462 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400463
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400464 env->DeleteLocalRef(list);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400465 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400466 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400467}
468
Mike Lockwood828d19d2010-08-10 15:20:35 -0400469MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
470 MtpObjectProperty property,
471 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400472 int type;
473
474 if (!getObjectPropertyInfo(property, type))
475 return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
476
477 JNIEnv* env = AndroidRuntime::getJNIEnv();
478 jlong longValue = 0;
479 jstring stringValue = NULL;
480
481 switch (type) {
482 case MTP_TYPE_INT8:
483 longValue = packet.getInt8();
484 break;
485 case MTP_TYPE_UINT8:
486 longValue = packet.getUInt8();
487 break;
488 case MTP_TYPE_INT16:
489 longValue = packet.getInt16();
490 break;
491 case MTP_TYPE_UINT16:
492 longValue = packet.getUInt16();
493 break;
494 case MTP_TYPE_INT32:
495 longValue = packet.getInt32();
496 break;
497 case MTP_TYPE_UINT32:
498 longValue = packet.getUInt32();
499 break;
500 case MTP_TYPE_INT64:
501 longValue = packet.getInt64();
502 break;
503 case MTP_TYPE_UINT64:
504 longValue = packet.getUInt64();
505 break;
506 case MTP_TYPE_STR:
507 {
508 MtpStringBuffer buffer;
509 packet.getString(buffer);
510 stringValue = env->NewStringUTF((const char *)buffer);
511 break;
512 }
513 default:
Martin Blumenstingl986b46d2014-05-31 15:53:00 +0200514 ALOGE("unsupported type in setObjectPropertyValue\n");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400515 return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
516 }
517
518 jint result = env->CallIntMethod(mDatabase, method_setObjectProperty,
519 (jint)handle, (jint)property, longValue, stringValue);
Mike Lockwood88394712010-09-27 10:01:00 -0400520 if (stringValue)
521 env->DeleteLocalRef(stringValue);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400522
523 checkAndClearExceptionFromCallback(env, __FUNCTION__);
524 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400525}
526
527MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
528 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400529 int type;
530
531 if (!getDevicePropertyInfo(property, type))
532 return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
533
534 JNIEnv* env = AndroidRuntime::getJNIEnv();
535 jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
536 (jint)property, mLongBuffer, mStringBuffer);
537 if (result != MTP_RESPONSE_OK) {
538 checkAndClearExceptionFromCallback(env, __FUNCTION__);
539 return result;
540 }
541
542 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
543 jlong longValue = longValues[0];
544 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
545
546 switch (type) {
547 case MTP_TYPE_INT8:
548 packet.putInt8(longValue);
549 break;
550 case MTP_TYPE_UINT8:
551 packet.putUInt8(longValue);
552 break;
553 case MTP_TYPE_INT16:
554 packet.putInt16(longValue);
555 break;
556 case MTP_TYPE_UINT16:
557 packet.putUInt16(longValue);
558 break;
559 case MTP_TYPE_INT32:
560 packet.putInt32(longValue);
561 break;
562 case MTP_TYPE_UINT32:
563 packet.putUInt32(longValue);
564 break;
565 case MTP_TYPE_INT64:
566 packet.putInt64(longValue);
567 break;
568 case MTP_TYPE_UINT64:
569 packet.putUInt64(longValue);
570 break;
571 case MTP_TYPE_INT128:
572 packet.putInt128(longValue);
573 break;
574 case MTP_TYPE_UINT128:
575 packet.putInt128(longValue);
576 break;
577 case MTP_TYPE_STR:
578 {
579 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
580 packet.putString(str);
581 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
582 break;
583 }
584 default:
Steve Block3762c312012-01-06 19:20:56 +0000585 ALOGE("unsupported type in getDevicePropertyValue\n");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400586 return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
587 }
588
589 checkAndClearExceptionFromCallback(env, __FUNCTION__);
590 return MTP_RESPONSE_OK;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400591}
592
593MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
594 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400595 int type;
596
597 if (!getDevicePropertyInfo(property, type))
598 return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
599
600 JNIEnv* env = AndroidRuntime::getJNIEnv();
601 jlong longValue = 0;
602 jstring stringValue = NULL;
603
604 switch (type) {
605 case MTP_TYPE_INT8:
606 longValue = packet.getInt8();
607 break;
608 case MTP_TYPE_UINT8:
609 longValue = packet.getUInt8();
610 break;
611 case MTP_TYPE_INT16:
612 longValue = packet.getInt16();
613 break;
614 case MTP_TYPE_UINT16:
615 longValue = packet.getUInt16();
616 break;
617 case MTP_TYPE_INT32:
618 longValue = packet.getInt32();
619 break;
620 case MTP_TYPE_UINT32:
621 longValue = packet.getUInt32();
622 break;
623 case MTP_TYPE_INT64:
624 longValue = packet.getInt64();
625 break;
626 case MTP_TYPE_UINT64:
627 longValue = packet.getUInt64();
628 break;
629 case MTP_TYPE_STR:
630 {
631 MtpStringBuffer buffer;
632 packet.getString(buffer);
633 stringValue = env->NewStringUTF((const char *)buffer);
634 break;
635 }
636 default:
Steve Block3762c312012-01-06 19:20:56 +0000637 ALOGE("unsupported type in setDevicePropertyValue\n");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400638 return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
639 }
640
641 jint result = env->CallIntMethod(mDatabase, method_setDeviceProperty,
642 (jint)property, longValue, stringValue);
Mike Lockwood88394712010-09-27 10:01:00 -0400643 if (stringValue)
644 env->DeleteLocalRef(stringValue);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400645
646 checkAndClearExceptionFromCallback(env, __FUNCTION__);
647 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400648}
649
Mark Salyzynaeb75fc2014-03-20 12:09:01 -0700650MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty /*property*/) {
Mike Lockwood828d19d2010-08-10 15:20:35 -0400651 return -1;
652}
653
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400654MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500655 uint32_t format, uint32_t property,
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400656 int groupCode, int depth,
657 MtpDataPacket& packet) {
658 JNIEnv* env = AndroidRuntime::getJNIEnv();
659 jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500660 (jlong)handle, (jint)format, (jlong)property, (jint)groupCode, (jint)depth);
661 checkAndClearExceptionFromCallback(env, __FUNCTION__);
662 if (!list)
663 return MTP_RESPONSE_GENERAL_ERROR;
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400664 int count = env->GetIntField(list, field_mCount);
665 MtpResponseCode result = env->GetIntField(list, field_mResult);
666
667 packet.putUInt32(count);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400668 if (count > 0) {
669 jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
670 jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
671 jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
672 jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
673 jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
674
675 jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
676 jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
677 jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
678 jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
679
680 for (int i = 0; i < count; i++) {
681 packet.putUInt32(objectHandles[i]);
682 packet.putUInt16(propertyCodes[i]);
683 int type = dataTypes[i];
684 packet.putUInt16(type);
685
686 switch (type) {
687 case MTP_TYPE_INT8:
688 packet.putInt8(longValues[i]);
689 break;
690 case MTP_TYPE_UINT8:
691 packet.putUInt8(longValues[i]);
692 break;
693 case MTP_TYPE_INT16:
694 packet.putInt16(longValues[i]);
695 break;
696 case MTP_TYPE_UINT16:
697 packet.putUInt16(longValues[i]);
698 break;
699 case MTP_TYPE_INT32:
700 packet.putInt32(longValues[i]);
701 break;
702 case MTP_TYPE_UINT32:
703 packet.putUInt32(longValues[i]);
704 break;
705 case MTP_TYPE_INT64:
706 packet.putInt64(longValues[i]);
707 break;
708 case MTP_TYPE_UINT64:
709 packet.putUInt64(longValues[i]);
710 break;
711 case MTP_TYPE_INT128:
712 packet.putInt128(longValues[i]);
713 break;
714 case MTP_TYPE_UINT128:
715 packet.putUInt128(longValues[i]);
716 break;
717 case MTP_TYPE_STR: {
718 jstring value = (jstring)env->GetObjectArrayElement(stringValuesArray, i);
Mike Lockwood2711e492010-12-11 11:24:37 -0800719 const char *valueStr = (value ? env->GetStringUTFChars(value, NULL) : NULL);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400720 if (valueStr) {
721 packet.putString(valueStr);
722 env->ReleaseStringUTFChars(value, valueStr);
723 } else {
724 packet.putEmptyString();
725 }
726 env->DeleteLocalRef(value);
727 break;
728 }
729 default:
Steve Block3762c312012-01-06 19:20:56 +0000730 ALOGE("bad or unsupported data type in MyMtpDatabase::getObjectPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400731 break;
732 }
733 }
734
735 env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
736 env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
737 env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
738 if (longValues)
739 env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
740
741 env->DeleteLocalRef(objectHandlesArray);
742 env->DeleteLocalRef(propertyCodesArray);
743 env->DeleteLocalRef(dataTypesArray);
744 if (longValuesArray)
745 env->DeleteLocalRef(longValuesArray);
746 if (stringValuesArray)
747 env->DeleteLocalRef(stringValuesArray);
748 }
749
750 env->DeleteLocalRef(list);
751 checkAndClearExceptionFromCallback(env, __FUNCTION__);
752 return result;
753}
754
Marco Nelissenaefa4272014-01-10 10:39:27 -0800755static void foreachentry(ExifEntry *entry, void *user) {
756 char buf[1024];
757 ALOGI("entry %x, format %d, size %d: %s",
758 entry->tag, entry->format, entry->size, exif_entry_get_value(entry, buf, sizeof(buf)));
759}
760
761static void foreachcontent(ExifContent *content, void *user) {
762 ALOGI("content %d", exif_content_get_ifd(content));
763 exif_content_foreach_entry(content, foreachentry, user);
764}
765
766static long getLongFromExifEntry(ExifEntry *e) {
767 ExifByteOrder o = exif_data_get_byte_order(e->parent->parent);
768 return exif_get_long(e->data, o);
769}
770
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400771MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700772 MtpObjectInfo& info) {
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700773 char date[20];
774 MtpString path;
775 int64_t length;
776 MtpObjectFormat format;
777
778 MtpResponseCode result = getObjectFilePath(handle, path, length, format);
779 if (result != MTP_RESPONSE_OK) {
780 return result;
781 }
782 info.mCompressedSize = (length > 0xFFFFFFFFLL ? 0xFFFFFFFF : (uint32_t)length);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400783
784 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700785 if (!env->CallBooleanMethod(mDatabase, method_getObjectInfo,
786 (jint)handle, mIntBuffer, mStringBuffer, mLongBuffer)) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400787 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700788 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400789
790 jint* intValues = env->GetIntArrayElements(mIntBuffer, 0);
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700791 info.mStorageID = intValues[0];
792 info.mFormat = intValues[1];
793 info.mParent = intValues[2];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400794 env->ReleaseIntArrayElements(mIntBuffer, intValues, 0);
795
796 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
Mike Lockwood1341f1e2013-04-01 10:52:47 -0700797 info.mDateCreated = longValues[0];
798 info.mDateModified = longValues[1];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400799 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
800
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700801// info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ?
Mike Lockwood828d19d2010-08-10 15:20:35 -0400802// MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
803// MTP_ASSOCIATION_TYPE_UNDEFINED);
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700804 info.mAssociationType = MTP_ASSOCIATION_TYPE_UNDEFINED;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400805
806 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700807 MtpString temp(str);
808 info.mName = strdup((const char *)temp);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400809 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
810
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700811 // read EXIF data for thumbnail information
812 if (info.mFormat == MTP_FORMAT_EXIF_JPEG || info.mFormat == MTP_FORMAT_JFIF) {
Marco Nelissenaefa4272014-01-10 10:39:27 -0800813
814 ExifData *exifdata = exif_data_new_from_file(path);
815 if (exifdata) {
816 //exif_data_foreach_content(exifdata, foreachcontent, NULL);
817
818 // XXX get this from exif, or parse jpeg header instead?
819 ExifEntry *w = exif_content_get_entry(
820 exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_X_DIMENSION);
821 ExifEntry *h = exif_content_get_entry(
822 exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_Y_DIMENSION);
823 info.mThumbCompressedSize = exifdata->data ? exifdata->size : 0;
824 info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
825 info.mImagePixWidth = w ? getLongFromExifEntry(w) : 0;
826 info.mImagePixHeight = h ? getLongFromExifEntry(h) : 0;
827 exif_data_unref(exifdata);
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700828 }
829 }
830
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400831 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400832 return MTP_RESPONSE_OK;
833}
834
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700835void* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) {
836 MtpString path;
837 int64_t length;
838 MtpObjectFormat format;
839 void* result = NULL;
840 outThumbSize = 0;
841
842 if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK
843 && (format == MTP_FORMAT_EXIF_JPEG || format == MTP_FORMAT_JFIF)) {
Marco Nelissenaefa4272014-01-10 10:39:27 -0800844
845 ExifData *exifdata = exif_data_new_from_file(path);
846 if (exifdata) {
847 if (exifdata->data) {
848 result = malloc(exifdata->size);
849 if (result) {
850 memcpy(result, exifdata->data, exifdata->size);
Mike Lockwoodc4367722014-04-21 08:49:30 -0700851 outThumbSize = exifdata->size;
Marco Nelissenaefa4272014-01-10 10:39:27 -0800852 }
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700853 }
Marco Nelissenaefa4272014-01-10 10:39:27 -0800854 exif_data_unref(exifdata);
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700855 }
856 }
857
858 return result;
859}
860
Mike Lockwood59c777a2010-08-02 10:37:41 -0400861MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle,
Mike Lockwood365e03e2010-12-08 16:08:01 -0800862 MtpString& outFilePath,
863 int64_t& outFileLength,
864 MtpObjectFormat& outFormat) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400865 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood59c777a2010-08-02 10:37:41 -0400866 jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400867 (jint)handle, mStringBuffer, mLongBuffer);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400868 if (result != MTP_RESPONSE_OK) {
869 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400870 return result;
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400871 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400872
873 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
Mike Lockwood365e03e2010-12-08 16:08:01 -0800874 outFilePath.setTo(str, strlen16(str));
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400875 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
876
877 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
Mike Lockwood365e03e2010-12-08 16:08:01 -0800878 outFileLength = longValues[0];
879 outFormat = longValues[1];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400880 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700881
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400882 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400883 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400884}
885
Mike Lockwood59c777a2010-08-02 10:37:41 -0400886MtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400887 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400888 MtpResponseCode result = env->CallIntMethod(mDatabase, method_deleteFile, (jint)handle);
889
890 checkAndClearExceptionFromCallback(env, __FUNCTION__);
891 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400892}
893
894struct PropertyTableEntry {
895 MtpObjectProperty property;
896 int type;
897};
898
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400899static const PropertyTableEntry kObjectPropertyTable[] = {
Mike Lockwoodd3bfecb2010-09-23 23:04:28 -0400900 { MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32 },
901 { MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16 },
902 { MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16 },
903 { MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64 },
904 { MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR },
905 { MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR },
906 { MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32 },
907 { MTP_PROPERTY_PERSISTENT_UID, MTP_TYPE_UINT128 },
908 { MTP_PROPERTY_NAME, MTP_TYPE_STR },
Mike Lockwoodae078f72010-09-26 12:35:51 -0400909 { MTP_PROPERTY_DISPLAY_NAME, MTP_TYPE_STR },
910 { MTP_PROPERTY_DATE_ADDED, MTP_TYPE_STR },
911 { MTP_PROPERTY_ARTIST, MTP_TYPE_STR },
912 { MTP_PROPERTY_ALBUM_NAME, MTP_TYPE_STR },
913 { MTP_PROPERTY_ALBUM_ARTIST, MTP_TYPE_STR },
914 { MTP_PROPERTY_TRACK, MTP_TYPE_UINT16 },
915 { MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_TYPE_STR },
916 { MTP_PROPERTY_GENRE, MTP_TYPE_STR },
917 { MTP_PROPERTY_COMPOSER, MTP_TYPE_STR },
918 { MTP_PROPERTY_DURATION, MTP_TYPE_UINT32 },
919 { MTP_PROPERTY_DESCRIPTION, MTP_TYPE_STR },
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400920};
921
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400922static const PropertyTableEntry kDevicePropertyTable[] = {
Mike Lockwoodea93fa12010-12-07 10:41:35 -0800923 { MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MTP_TYPE_STR },
924 { MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR },
925 { MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR },
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400926};
927
928bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
929 int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
930 const PropertyTableEntry* entry = kObjectPropertyTable;
931 for (int i = 0; i < count; i++, entry++) {
932 if (entry->property == property) {
933 type = entry->type;
934 return true;
935 }
936 }
937 return false;
938}
939
940bool MyMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) {
941 int count = sizeof(kDevicePropertyTable) / sizeof(kDevicePropertyTable[0]);
942 const PropertyTableEntry* entry = kDevicePropertyTable;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400943 for (int i = 0; i < count; i++, entry++) {
944 if (entry->property == property) {
945 type = entry->type;
946 return true;
947 }
948 }
949 return false;
950}
951
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400952MtpObjectHandleList* MyMtpDatabase::getObjectReferences(MtpObjectHandle handle) {
953 JNIEnv* env = AndroidRuntime::getJNIEnv();
954 jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectReferences,
955 (jint)handle);
956 if (!array)
957 return NULL;
958 MtpObjectHandleList* list = new MtpObjectHandleList();
959 jint* handles = env->GetIntArrayElements(array, 0);
960 jsize length = env->GetArrayLength(array);
961 for (int i = 0; i < length; i++)
962 list->push(handles[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400963 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400964 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400965
966 checkAndClearExceptionFromCallback(env, __FUNCTION__);
967 return list;
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400968}
969
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400970MtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle,
971 MtpObjectHandleList* references) {
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400972 JNIEnv* env = AndroidRuntime::getJNIEnv();
973 int count = references->size();
974 jintArray array = env->NewIntArray(count);
975 if (!array) {
Steve Block3762c312012-01-06 19:20:56 +0000976 ALOGE("out of memory in setObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400977 return false;
978 }
979 jint* handles = env->GetIntArrayElements(array, 0);
980 for (int i = 0; i < count; i++)
981 handles[i] = (*references)[i];
982 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400983 MtpResponseCode result = env->CallIntMethod(mDatabase, method_setObjectReferences,
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400984 (jint)handle, array);
Mike Lockwood88394712010-09-27 10:01:00 -0400985 env->DeleteLocalRef(array);
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400986
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400987 checkAndClearExceptionFromCallback(env, __FUNCTION__);
988 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400989}
990
Mike Lockwood828d19d2010-08-10 15:20:35 -0400991MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
992 MtpObjectFormat format) {
993 MtpProperty* result = NULL;
994 switch (property) {
995 case MTP_PROPERTY_OBJECT_FORMAT:
Mike Lockwood9b5e9c42010-12-07 18:53:50 -0800996 // use format as default value
997 result = new MtpProperty(property, MTP_TYPE_UINT16, false, format);
998 break;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400999 case MTP_PROPERTY_PROTECTION_STATUS:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001000 case MTP_PROPERTY_TRACK:
Mike Lockwood828d19d2010-08-10 15:20:35 -04001001 result = new MtpProperty(property, MTP_TYPE_UINT16);
1002 break;
1003 case MTP_PROPERTY_STORAGE_ID:
1004 case MTP_PROPERTY_PARENT_OBJECT:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001005 case MTP_PROPERTY_DURATION:
Mike Lockwood828d19d2010-08-10 15:20:35 -04001006 result = new MtpProperty(property, MTP_TYPE_UINT32);
1007 break;
1008 case MTP_PROPERTY_OBJECT_SIZE:
1009 result = new MtpProperty(property, MTP_TYPE_UINT64);
1010 break;
1011 case MTP_PROPERTY_PERSISTENT_UID:
1012 result = new MtpProperty(property, MTP_TYPE_UINT128);
1013 break;
Mike Lockwoodd3bfecb2010-09-23 23:04:28 -04001014 case MTP_PROPERTY_NAME:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001015 case MTP_PROPERTY_DISPLAY_NAME:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001016 case MTP_PROPERTY_ARTIST:
1017 case MTP_PROPERTY_ALBUM_NAME:
1018 case MTP_PROPERTY_ALBUM_ARTIST:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001019 case MTP_PROPERTY_GENRE:
1020 case MTP_PROPERTY_COMPOSER:
1021 case MTP_PROPERTY_DESCRIPTION:
Mike Lockwood828d19d2010-08-10 15:20:35 -04001022 result = new MtpProperty(property, MTP_TYPE_STR);
1023 break;
Mike Lockwood5b19af02010-11-23 18:38:55 -05001024 case MTP_PROPERTY_DATE_MODIFIED:
1025 case MTP_PROPERTY_DATE_ADDED:
1026 case MTP_PROPERTY_ORIGINAL_RELEASE_DATE:
1027 result = new MtpProperty(property, MTP_TYPE_STR);
1028 result->setFormDateTime();
1029 break;
Mike Lockwood5ebac832010-10-12 11:33:47 -04001030 case MTP_PROPERTY_OBJECT_FILE_NAME:
Mike Lockwood6a6a3af2010-10-12 14:19:51 -04001031 // We allow renaming files and folders
1032 result = new MtpProperty(property, MTP_TYPE_STR, true);
Mike Lockwood5ebac832010-10-12 11:33:47 -04001033 break;
Mike Lockwood828d19d2010-08-10 15:20:35 -04001034 }
1035
1036 return result;
1037}
1038
1039MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001040 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001041 MtpProperty* result = NULL;
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001042 bool writable = false;
1043
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001044 switch (property) {
1045 case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
1046 case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001047 writable = true;
1048 // fall through
1049 case MTP_DEVICE_PROPERTY_IMAGE_SIZE:
1050 result = new MtpProperty(property, MTP_TYPE_STR, writable);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001051
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001052 // get current value
Mike Lockwooda2a21282010-09-25 21:21:05 -04001053 jint ret = env->CallIntMethod(mDatabase, method_getDeviceProperty,
1054 (jint)property, mLongBuffer, mStringBuffer);
1055 if (ret == MTP_RESPONSE_OK) {
1056 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
1057 result->setCurrentValue(str);
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001058 // for read-only properties it is safe to assume current value is default value
1059 if (!writable)
1060 result->setDefaultValue(str);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001061 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
1062 } else {
Steve Block3762c312012-01-06 19:20:56 +00001063 ALOGE("unable to read device property, response: %04X", ret);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001064 }
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001065 break;
1066 }
1067
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001068 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001069 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -04001070}
1071
Mike Lockwood2837eef2010-08-31 16:25:12 -04001072void MyMtpDatabase::sessionStarted() {
1073 JNIEnv* env = AndroidRuntime::getJNIEnv();
1074 env->CallVoidMethod(mDatabase, method_sessionStarted);
1075 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1076}
1077
1078void MyMtpDatabase::sessionEnded() {
1079 JNIEnv* env = AndroidRuntime::getJNIEnv();
1080 env->CallVoidMethod(mDatabase, method_sessionEnded);
1081 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1082}
1083
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001084// ----------------------------------------------------------------------------
1085
1086static void
Mike Lockwood0cd01362010-12-30 11:54:33 -05001087android_mtp_MtpDatabase_setup(JNIEnv *env, jobject thiz)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001088{
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001089 MyMtpDatabase* database = new MyMtpDatabase(env, thiz);
Ashok Bhate2e59322013-12-17 19:04:19 +00001090 env->SetLongField(thiz, field_context, (jlong)database);
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001091 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1092}
1093
1094static void
Mike Lockwood0cd01362010-12-30 11:54:33 -05001095android_mtp_MtpDatabase_finalize(JNIEnv *env, jobject thiz)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001096{
Ashok Bhate2e59322013-12-17 19:04:19 +00001097 MyMtpDatabase* database = (MyMtpDatabase *)env->GetLongField(thiz, field_context);
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001098 database->cleanup(env);
1099 delete database;
Ashok Bhate2e59322013-12-17 19:04:19 +00001100 env->SetLongField(thiz, field_context, 0);
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001101 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1102}
1103
Mike Lockwood31599912010-11-15 13:43:30 -05001104static jstring
Mark Salyzynaeb75fc2014-03-20 12:09:01 -07001105android_mtp_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject /*thiz*/, jlong seconds)
Mike Lockwood31599912010-11-15 13:43:30 -05001106{
Mike Lockwood31599912010-11-15 13:43:30 -05001107 char date[20];
1108 formatDateTime(seconds, date, sizeof(date));
1109 return env->NewStringUTF(date);
Mike Lockwood31599912010-11-15 13:43:30 -05001110}
1111
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001112// ----------------------------------------------------------------------------
1113
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001114static JNINativeMethod gMtpDatabaseMethods[] = {
Mike Lockwood0cd01362010-12-30 11:54:33 -05001115 {"native_setup", "()V", (void *)android_mtp_MtpDatabase_setup},
1116 {"native_finalize", "()V", (void *)android_mtp_MtpDatabase_finalize},
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001117};
1118
1119static JNINativeMethod gMtpPropertyGroupMethods[] = {
Mike Lockwood31599912010-11-15 13:43:30 -05001120 {"format_date_time", "(J)Ljava/lang/String;",
Mike Lockwood0cd01362010-12-30 11:54:33 -05001121 (void *)android_mtp_MtpPropertyGroup_format_date_time},
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001122};
1123
Mike Lockwood0cd01362010-12-30 11:54:33 -05001124static const char* const kClassPathName = "android/mtp/MtpDatabase";
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001125
Mike Lockwood0cd01362010-12-30 11:54:33 -05001126int register_android_mtp_MtpDatabase(JNIEnv *env)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001127{
1128 jclass clazz;
1129
Mike Lockwood0cd01362010-12-30 11:54:33 -05001130 clazz = env->FindClass("android/mtp/MtpDatabase");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001131 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001132 ALOGE("Can't find android/mtp/MtpDatabase");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001133 return -1;
1134 }
Mike Lockwoodd815f792010-07-12 08:49:01 -04001135 method_beginSendObject = env->GetMethodID(clazz, "beginSendObject", "(Ljava/lang/String;IIIJJ)I");
1136 if (method_beginSendObject == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001137 ALOGE("Can't find beginSendObject");
Mike Lockwoodd815f792010-07-12 08:49:01 -04001138 return -1;
1139 }
Mike Lockwood7a0bd172011-01-18 11:06:19 -08001140 method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIZ)V");
Mike Lockwoodd815f792010-07-12 08:49:01 -04001141 if (method_endSendObject == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001142 ALOGE("Can't find endSendObject");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001143 return -1;
1144 }
1145 method_getObjectList = env->GetMethodID(clazz, "getObjectList", "(III)[I");
1146 if (method_getObjectList == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001147 ALOGE("Can't find getObjectList");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001148 return -1;
1149 }
Mike Lockwood7a047c82010-08-02 10:52:20 -04001150 method_getNumObjects = env->GetMethodID(clazz, "getNumObjects", "(III)I");
1151 if (method_getNumObjects == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001152 ALOGE("Can't find getNumObjects");
Mike Lockwood7a047c82010-08-02 10:52:20 -04001153 return -1;
1154 }
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001155 method_getSupportedPlaybackFormats = env->GetMethodID(clazz, "getSupportedPlaybackFormats", "()[I");
1156 if (method_getSupportedPlaybackFormats == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001157 ALOGE("Can't find getSupportedPlaybackFormats");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001158 return -1;
1159 }
1160 method_getSupportedCaptureFormats = env->GetMethodID(clazz, "getSupportedCaptureFormats", "()[I");
1161 if (method_getSupportedCaptureFormats == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001162 ALOGE("Can't find getSupportedCaptureFormats");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001163 return -1;
1164 }
1165 method_getSupportedObjectProperties = env->GetMethodID(clazz, "getSupportedObjectProperties", "(I)[I");
1166 if (method_getSupportedObjectProperties == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001167 ALOGE("Can't find getSupportedObjectProperties");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001168 return -1;
1169 }
1170 method_getSupportedDeviceProperties = env->GetMethodID(clazz, "getSupportedDeviceProperties", "()[I");
1171 if (method_getSupportedDeviceProperties == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001172 ALOGE("Can't find getSupportedDeviceProperties");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001173 return -1;
1174 }
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001175 method_setObjectProperty = env->GetMethodID(clazz, "setObjectProperty", "(IIJLjava/lang/String;)I");
1176 if (method_setObjectProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001177 ALOGE("Can't find setObjectProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001178 return -1;
1179 }
1180 method_getDeviceProperty = env->GetMethodID(clazz, "getDeviceProperty", "(I[J[C)I");
1181 if (method_getDeviceProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001182 ALOGE("Can't find getDeviceProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001183 return -1;
1184 }
1185 method_setDeviceProperty = env->GetMethodID(clazz, "setDeviceProperty", "(IJLjava/lang/String;)I");
1186 if (method_setDeviceProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001187 ALOGE("Can't find setDeviceProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001188 return -1;
1189 }
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001190 method_getObjectPropertyList = env->GetMethodID(clazz, "getObjectPropertyList",
Mike Lockwood0cd01362010-12-30 11:54:33 -05001191 "(JIJII)Landroid/mtp/MtpPropertyList;");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001192 if (method_getObjectPropertyList == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001193 ALOGE("Can't find getObjectPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001194 return -1;
1195 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001196 method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z");
1197 if (method_getObjectInfo == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001198 ALOGE("Can't find getObjectInfo");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001199 return -1;
1200 }
Mike Lockwood59c777a2010-08-02 10:37:41 -04001201 method_getObjectFilePath = env->GetMethodID(clazz, "getObjectFilePath", "(I[C[J)I");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001202 if (method_getObjectFilePath == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001203 ALOGE("Can't find getObjectFilePath");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001204 return -1;
1205 }
Mike Lockwood59c777a2010-08-02 10:37:41 -04001206 method_deleteFile = env->GetMethodID(clazz, "deleteFile", "(I)I");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001207 if (method_deleteFile == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001208 ALOGE("Can't find deleteFile");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001209 return -1;
1210 }
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001211 method_getObjectReferences = env->GetMethodID(clazz, "getObjectReferences", "(I)[I");
1212 if (method_getObjectReferences == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001213 ALOGE("Can't find getObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001214 return -1;
1215 }
1216 method_setObjectReferences = env->GetMethodID(clazz, "setObjectReferences", "(I[I)I");
1217 if (method_setObjectReferences == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001218 ALOGE("Can't find setObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001219 return -1;
1220 }
Mike Lockwood2837eef2010-08-31 16:25:12 -04001221 method_sessionStarted = env->GetMethodID(clazz, "sessionStarted", "()V");
1222 if (method_sessionStarted == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001223 ALOGE("Can't find sessionStarted");
Mike Lockwood2837eef2010-08-31 16:25:12 -04001224 return -1;
1225 }
1226 method_sessionEnded = env->GetMethodID(clazz, "sessionEnded", "()V");
1227 if (method_sessionEnded == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001228 ALOGE("Can't find sessionEnded");
Mike Lockwood2837eef2010-08-31 16:25:12 -04001229 return -1;
1230 }
1231
Ashok Bhate2e59322013-12-17 19:04:19 +00001232 field_context = env->GetFieldID(clazz, "mNativeContext", "J");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001233 if (field_context == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001234 ALOGE("Can't find MtpDatabase.mNativeContext");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001235 return -1;
1236 }
1237
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001238 // now set up fields for MtpPropertyList class
Mike Lockwood0cd01362010-12-30 11:54:33 -05001239 clazz = env->FindClass("android/mtp/MtpPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001240 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001241 ALOGE("Can't find android/mtp/MtpPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001242 return -1;
1243 }
1244 field_mCount = env->GetFieldID(clazz, "mCount", "I");
1245 if (field_mCount == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001246 ALOGE("Can't find MtpPropertyList.mCount");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001247 return -1;
1248 }
1249 field_mResult = env->GetFieldID(clazz, "mResult", "I");
1250 if (field_mResult == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001251 ALOGE("Can't find MtpPropertyList.mResult");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001252 return -1;
1253 }
1254 field_mObjectHandles = env->GetFieldID(clazz, "mObjectHandles", "[I");
1255 if (field_mObjectHandles == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001256 ALOGE("Can't find MtpPropertyList.mObjectHandles");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001257 return -1;
1258 }
1259 field_mPropertyCodes = env->GetFieldID(clazz, "mPropertyCodes", "[I");
1260 if (field_mPropertyCodes == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001261 ALOGE("Can't find MtpPropertyList.mPropertyCodes");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001262 return -1;
1263 }
1264 field_mDataTypes = env->GetFieldID(clazz, "mDataTypes", "[I");
1265 if (field_mDataTypes == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001266 ALOGE("Can't find MtpPropertyList.mDataTypes");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001267 return -1;
1268 }
1269 field_mLongValues = env->GetFieldID(clazz, "mLongValues", "[J");
1270 if (field_mLongValues == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001271 ALOGE("Can't find MtpPropertyList.mLongValues");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001272 return -1;
1273 }
1274 field_mStringValues = env->GetFieldID(clazz, "mStringValues", "[Ljava/lang/String;");
1275 if (field_mStringValues == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001276 ALOGE("Can't find MtpPropertyList.mStringValues");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001277 return -1;
1278 }
1279
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001280 if (AndroidRuntime::registerNativeMethods(env,
Mike Lockwood0cd01362010-12-30 11:54:33 -05001281 "android/mtp/MtpDatabase", gMtpDatabaseMethods, NELEM(gMtpDatabaseMethods)))
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001282 return -1;
1283
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001284 return AndroidRuntime::registerNativeMethods(env,
Mike Lockwood0cd01362010-12-30 11:54:33 -05001285 "android/mtp/MtpPropertyGroup", gMtpPropertyGroupMethods, NELEM(gMtpPropertyGroupMethods));
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001286}