blob: 1a0675e3699a371bd005650a52bd215da8665fef [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 Nelissen3cd393c2014-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;
Mike Lockwood56c85242014-03-07 13:29:08 -080072static jfieldID field_batteryLevel;
73static jfieldID field_batteryScale;
Mike Lockwoodd21eac92010-07-03 00:44:05 -040074
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -040075// MtpPropertyList fields
76static jfieldID field_mCount;
77static jfieldID field_mResult;
78static jfieldID field_mObjectHandles;
79static jfieldID field_mPropertyCodes;
80static jfieldID field_mDataTypes;
81static jfieldID field_mLongValues;
82static jfieldID field_mStringValues;
83
84
Mike Lockwoodd21eac92010-07-03 00:44:05 -040085MtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) {
Ashok Bhate2e59322013-12-17 19:04:19 +000086 return (MtpDatabase *)env->GetLongField(database, field_context);
Mike Lockwoodd21eac92010-07-03 00:44:05 -040087}
88
89// ----------------------------------------------------------------------------
90
91class MyMtpDatabase : public MtpDatabase {
92private:
93 jobject mDatabase;
94 jintArray mIntBuffer;
95 jlongArray mLongBuffer;
96 jcharArray mStringBuffer;
97
98public:
99 MyMtpDatabase(JNIEnv *env, jobject client);
100 virtual ~MyMtpDatabase();
101 void cleanup(JNIEnv *env);
102
Mike Lockwoodd815f792010-07-12 08:49:01 -0400103 virtual MtpObjectHandle beginSendObject(const char* path,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400104 MtpObjectFormat format,
105 MtpObjectHandle parent,
106 MtpStorageID storage,
107 uint64_t size,
108 time_t modified);
109
Mike Lockwoodd815f792010-07-12 08:49:01 -0400110 virtual void endSendObject(const char* path,
111 MtpObjectHandle handle,
112 MtpObjectFormat format,
113 bool succeeded);
114
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400115 virtual MtpObjectHandleList* getObjectList(MtpStorageID storageID,
116 MtpObjectFormat format,
117 MtpObjectHandle parent);
118
Mike Lockwood7a047c82010-08-02 10:52:20 -0400119 virtual int getNumObjects(MtpStorageID storageID,
120 MtpObjectFormat format,
121 MtpObjectHandle parent);
122
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400123 // callee should delete[] the results from these
124 // results can be NULL
125 virtual MtpObjectFormatList* getSupportedPlaybackFormats();
126 virtual MtpObjectFormatList* getSupportedCaptureFormats();
127 virtual MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat format);
128 virtual MtpDevicePropertyList* getSupportedDeviceProperties();
129
Mike Lockwood828d19d2010-08-10 15:20:35 -0400130 virtual MtpResponseCode getObjectPropertyValue(MtpObjectHandle handle,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400131 MtpObjectProperty property,
132 MtpDataPacket& packet);
133
Mike Lockwood828d19d2010-08-10 15:20:35 -0400134 virtual MtpResponseCode setObjectPropertyValue(MtpObjectHandle handle,
135 MtpObjectProperty property,
136 MtpDataPacket& packet);
137
138 virtual MtpResponseCode getDevicePropertyValue(MtpDeviceProperty property,
139 MtpDataPacket& packet);
140
141 virtual MtpResponseCode setDevicePropertyValue(MtpDeviceProperty property,
142 MtpDataPacket& packet);
143
144 virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty property);
145
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400146 virtual MtpResponseCode getObjectPropertyList(MtpObjectHandle handle,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500147 uint32_t format, uint32_t property,
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400148 int groupCode, int depth,
149 MtpDataPacket& packet);
150
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400151 virtual MtpResponseCode getObjectInfo(MtpObjectHandle handle,
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700152 MtpObjectInfo& info);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400153
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700154 virtual void* getThumbnail(MtpObjectHandle handle, size_t& outThumbSize);
155
Mike Lockwood59c777a2010-08-02 10:37:41 -0400156 virtual MtpResponseCode getObjectFilePath(MtpObjectHandle handle,
Mike Lockwood365e03e2010-12-08 16:08:01 -0800157 MtpString& outFilePath,
158 int64_t& outFileLength,
159 MtpObjectFormat& outFormat);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400160 virtual MtpResponseCode deleteFile(MtpObjectHandle handle);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400161
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400162 bool getObjectPropertyInfo(MtpObjectProperty property, int& type);
163 bool getDevicePropertyInfo(MtpDeviceProperty property, int& type);
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400164
165 virtual MtpObjectHandleList* getObjectReferences(MtpObjectHandle handle);
166
167 virtual MtpResponseCode setObjectReferences(MtpObjectHandle handle,
168 MtpObjectHandleList* references);
Mike Lockwood828d19d2010-08-10 15:20:35 -0400169
170 virtual MtpProperty* getObjectPropertyDesc(MtpObjectProperty property,
171 MtpObjectFormat format);
172
173 virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property);
Mike Lockwood2837eef2010-08-31 16:25:12 -0400174
175 virtual void sessionStarted();
176
177 virtual void sessionEnded();
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400178};
179
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400180// ----------------------------------------------------------------------------
181
182static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
183 if (env->ExceptionCheck()) {
Steve Block3762c312012-01-06 19:20:56 +0000184 ALOGE("An exception was thrown by callback '%s'.", methodName);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400185 LOGE_EX(env);
186 env->ExceptionClear();
187 }
188}
189
190// ----------------------------------------------------------------------------
191
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400192MyMtpDatabase::MyMtpDatabase(JNIEnv *env, jobject client)
193 : mDatabase(env->NewGlobalRef(client)),
194 mIntBuffer(NULL),
195 mLongBuffer(NULL),
196 mStringBuffer(NULL)
197{
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400198 // create buffers for out arguments
199 // we don't need to be thread-safe so this is OK
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700200 jintArray intArray = env->NewIntArray(3);
201 if (!intArray) {
202 return; // Already threw.
203 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400204 mIntBuffer = (jintArray)env->NewGlobalRef(intArray);
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700205 jlongArray longArray = env->NewLongArray(2);
206 if (!longArray) {
207 return; // Already threw.
208 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400209 mLongBuffer = (jlongArray)env->NewGlobalRef(longArray);
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700210 jcharArray charArray = env->NewCharArray(256);
211 if (!charArray) {
212 return; // Already threw.
213 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400214 mStringBuffer = (jcharArray)env->NewGlobalRef(charArray);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400215}
216
217void MyMtpDatabase::cleanup(JNIEnv *env) {
218 env->DeleteGlobalRef(mDatabase);
219 env->DeleteGlobalRef(mIntBuffer);
220 env->DeleteGlobalRef(mLongBuffer);
221 env->DeleteGlobalRef(mStringBuffer);
222}
223
224MyMtpDatabase::~MyMtpDatabase() {
225}
226
Mike Lockwoodd815f792010-07-12 08:49:01 -0400227MtpObjectHandle MyMtpDatabase::beginSendObject(const char* path,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400228 MtpObjectFormat format,
229 MtpObjectHandle parent,
230 MtpStorageID storage,
231 uint64_t size,
232 time_t modified) {
233 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood88394712010-09-27 10:01:00 -0400234 jstring pathStr = env->NewStringUTF(path);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400235 MtpObjectHandle result = env->CallIntMethod(mDatabase, method_beginSendObject,
Mike Lockwood88394712010-09-27 10:01:00 -0400236 pathStr, (jint)format, (jint)parent, (jint)storage,
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400237 (jlong)size, (jlong)modified);
238
Mike Lockwood88394712010-09-27 10:01:00 -0400239 if (pathStr)
240 env->DeleteLocalRef(pathStr);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400241 checkAndClearExceptionFromCallback(env, __FUNCTION__);
242 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400243}
244
Mike Lockwoodd815f792010-07-12 08:49:01 -0400245void MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
Mike Lockwood7a0bd172011-01-18 11:06:19 -0800246 MtpObjectFormat format, bool succeeded) {
Mike Lockwoodd815f792010-07-12 08:49:01 -0400247 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood88394712010-09-27 10:01:00 -0400248 jstring pathStr = env->NewStringUTF(path);
249 env->CallVoidMethod(mDatabase, method_endSendObject, pathStr,
Mike Lockwood7a0bd172011-01-18 11:06:19 -0800250 (jint)handle, (jint)format, (jboolean)succeeded);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400251
Mike Lockwood88394712010-09-27 10:01:00 -0400252 if (pathStr)
253 env->DeleteLocalRef(pathStr);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400254 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodd815f792010-07-12 08:49:01 -0400255}
256
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400257MtpObjectHandleList* MyMtpDatabase::getObjectList(MtpStorageID storageID,
258 MtpObjectFormat format,
259 MtpObjectHandle parent) {
260 JNIEnv* env = AndroidRuntime::getJNIEnv();
261 jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectList,
262 (jint)storageID, (jint)format, (jint)parent);
263 if (!array)
264 return NULL;
265 MtpObjectHandleList* list = new MtpObjectHandleList();
266 jint* handles = env->GetIntArrayElements(array, 0);
267 jsize length = env->GetArrayLength(array);
Mike Lockwood7a047c82010-08-02 10:52:20 -0400268 for (int i = 0; i < length; i++)
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400269 list->push(handles[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400270 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400271 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400272
273 checkAndClearExceptionFromCallback(env, __FUNCTION__);
274 return list;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400275}
276
Mike Lockwood7a047c82010-08-02 10:52:20 -0400277int MyMtpDatabase::getNumObjects(MtpStorageID storageID,
278 MtpObjectFormat format,
279 MtpObjectHandle parent) {
280 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400281 int result = env->CallIntMethod(mDatabase, method_getNumObjects,
Mike Lockwood7a047c82010-08-02 10:52:20 -0400282 (jint)storageID, (jint)format, (jint)parent);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400283
284 checkAndClearExceptionFromCallback(env, __FUNCTION__);
285 return result;
Mike Lockwood7a047c82010-08-02 10:52:20 -0400286}
287
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400288MtpObjectFormatList* MyMtpDatabase::getSupportedPlaybackFormats() {
289 JNIEnv* env = AndroidRuntime::getJNIEnv();
290 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
291 method_getSupportedPlaybackFormats);
292 if (!array)
293 return NULL;
294 MtpObjectFormatList* list = new MtpObjectFormatList();
295 jint* formats = env->GetIntArrayElements(array, 0);
296 jsize length = env->GetArrayLength(array);
297 for (int i = 0; i < length; i++)
298 list->push(formats[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400299 env->ReleaseIntArrayElements(array, formats, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400300 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400301
302 checkAndClearExceptionFromCallback(env, __FUNCTION__);
303 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400304}
305
306MtpObjectFormatList* MyMtpDatabase::getSupportedCaptureFormats() {
307 JNIEnv* env = AndroidRuntime::getJNIEnv();
308 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
309 method_getSupportedCaptureFormats);
310 if (!array)
311 return NULL;
312 MtpObjectFormatList* list = new MtpObjectFormatList();
313 jint* formats = env->GetIntArrayElements(array, 0);
314 jsize length = env->GetArrayLength(array);
315 for (int i = 0; i < length; i++)
316 list->push(formats[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400317 env->ReleaseIntArrayElements(array, formats, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400318 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400319
320 checkAndClearExceptionFromCallback(env, __FUNCTION__);
321 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400322}
323
324MtpObjectPropertyList* MyMtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) {
325 JNIEnv* env = AndroidRuntime::getJNIEnv();
326 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
327 method_getSupportedObjectProperties, (jint)format);
328 if (!array)
329 return NULL;
330 MtpObjectPropertyList* list = new MtpObjectPropertyList();
331 jint* properties = env->GetIntArrayElements(array, 0);
332 jsize length = env->GetArrayLength(array);
333 for (int i = 0; i < length; i++)
334 list->push(properties[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400335 env->ReleaseIntArrayElements(array, properties, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400336 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400337
338 checkAndClearExceptionFromCallback(env, __FUNCTION__);
339 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400340}
341
342MtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
343 JNIEnv* env = AndroidRuntime::getJNIEnv();
344 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
345 method_getSupportedDeviceProperties);
346 if (!array)
347 return NULL;
348 MtpDevicePropertyList* list = new MtpDevicePropertyList();
349 jint* properties = env->GetIntArrayElements(array, 0);
350 jsize length = env->GetArrayLength(array);
351 for (int i = 0; i < length; i++)
352 list->push(properties[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400353 env->ReleaseIntArrayElements(array, properties, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400354 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400355
356 checkAndClearExceptionFromCallback(env, __FUNCTION__);
357 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400358}
359
Mike Lockwood828d19d2010-08-10 15:20:35 -0400360MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400361 MtpObjectProperty property,
362 MtpDataPacket& packet) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400363 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400364 jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500365 (jlong)handle, 0, (jlong)property, 0, 0);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400366 MtpResponseCode result = env->GetIntField(list, field_mResult);
367 int count = env->GetIntField(list, field_mCount);
368 if (result == MTP_RESPONSE_OK && count != 1)
369 result = MTP_RESPONSE_GENERAL_ERROR;
370
371 if (result == MTP_RESPONSE_OK) {
372 jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
373 jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
374 jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
375 jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
376 jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
377
378 jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
379 jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
380 jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
381 jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
382
383 int type = dataTypes[0];
384 jlong longValue = (longValues ? longValues[0] : 0);
385
386 // special case date properties, which are strings to MTP
387 // but stored internally as a uint64
388 if (property == MTP_PROPERTY_DATE_MODIFIED || property == MTP_PROPERTY_DATE_ADDED) {
389 char date[20];
390 formatDateTime(longValue, date, sizeof(date));
391 packet.putString(date);
392 goto out;
393 }
394 // release date is stored internally as just the year
395 if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) {
396 char date[20];
Mark Salyzynaeb75fc2014-03-20 12:09:01 -0700397 snprintf(date, sizeof(date), "%04" PRId64 "0101T000000", longValue);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400398 packet.putString(date);
399 goto out;
400 }
401
402 switch (type) {
403 case MTP_TYPE_INT8:
404 packet.putInt8(longValue);
405 break;
406 case MTP_TYPE_UINT8:
407 packet.putUInt8(longValue);
408 break;
409 case MTP_TYPE_INT16:
410 packet.putInt16(longValue);
411 break;
412 case MTP_TYPE_UINT16:
413 packet.putUInt16(longValue);
414 break;
415 case MTP_TYPE_INT32:
416 packet.putInt32(longValue);
417 break;
418 case MTP_TYPE_UINT32:
419 packet.putUInt32(longValue);
420 break;
421 case MTP_TYPE_INT64:
422 packet.putInt64(longValue);
423 break;
424 case MTP_TYPE_UINT64:
425 packet.putUInt64(longValue);
426 break;
427 case MTP_TYPE_INT128:
428 packet.putInt128(longValue);
429 break;
430 case MTP_TYPE_UINT128:
431 packet.putInt128(longValue);
432 break;
433 case MTP_TYPE_STR:
434 {
435 jstring stringValue = (jstring)env->GetObjectArrayElement(stringValuesArray, 0);
Martin Blumenstingl17a24c52014-05-31 15:50:38 +0200436 const char* str = (stringValue ? env->GetStringUTFChars(stringValue, NULL) : NULL);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400437 if (stringValue) {
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400438 packet.putString(str);
439 env->ReleaseStringUTFChars(stringValue, str);
440 } else {
441 packet.putEmptyString();
442 }
Martin Blumenstingl17a24c52014-05-31 15:50:38 +0200443 env->DeleteLocalRef(stringValue);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400444 break;
445 }
446 default:
Steve Block3762c312012-01-06 19:20:56 +0000447 ALOGE("unsupported type in getObjectPropertyValue\n");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400448 result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
449 }
450out:
451 env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
452 env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
453 env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
454 if (longValues)
455 env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
456
457 env->DeleteLocalRef(objectHandlesArray);
458 env->DeleteLocalRef(propertyCodesArray);
459 env->DeleteLocalRef(dataTypesArray);
460 if (longValuesArray)
461 env->DeleteLocalRef(longValuesArray);
462 if (stringValuesArray)
463 env->DeleteLocalRef(stringValuesArray);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400464 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400465
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400466 env->DeleteLocalRef(list);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400467 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400468 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400469}
470
Mike Lockwood828d19d2010-08-10 15:20:35 -0400471MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
472 MtpObjectProperty property,
473 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400474 int type;
475
476 if (!getObjectPropertyInfo(property, type))
477 return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
478
479 JNIEnv* env = AndroidRuntime::getJNIEnv();
480 jlong longValue = 0;
481 jstring stringValue = NULL;
482
483 switch (type) {
484 case MTP_TYPE_INT8:
485 longValue = packet.getInt8();
486 break;
487 case MTP_TYPE_UINT8:
488 longValue = packet.getUInt8();
489 break;
490 case MTP_TYPE_INT16:
491 longValue = packet.getInt16();
492 break;
493 case MTP_TYPE_UINT16:
494 longValue = packet.getUInt16();
495 break;
496 case MTP_TYPE_INT32:
497 longValue = packet.getInt32();
498 break;
499 case MTP_TYPE_UINT32:
500 longValue = packet.getUInt32();
501 break;
502 case MTP_TYPE_INT64:
503 longValue = packet.getInt64();
504 break;
505 case MTP_TYPE_UINT64:
506 longValue = packet.getUInt64();
507 break;
508 case MTP_TYPE_STR:
509 {
510 MtpStringBuffer buffer;
511 packet.getString(buffer);
512 stringValue = env->NewStringUTF((const char *)buffer);
513 break;
514 }
515 default:
Martin Blumenstingl986b46d2014-05-31 15:53:00 +0200516 ALOGE("unsupported type in setObjectPropertyValue\n");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400517 return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
518 }
519
520 jint result = env->CallIntMethod(mDatabase, method_setObjectProperty,
521 (jint)handle, (jint)property, longValue, stringValue);
Mike Lockwood88394712010-09-27 10:01:00 -0400522 if (stringValue)
523 env->DeleteLocalRef(stringValue);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400524
525 checkAndClearExceptionFromCallback(env, __FUNCTION__);
526 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400527}
528
529MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
530 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400531 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood56c85242014-03-07 13:29:08 -0800532
533 if (property == MTP_DEVICE_PROPERTY_BATTERY_LEVEL) {
534 // special case - implemented here instead of Java
535 packet.putUInt8((uint8_t)env->GetIntField(mDatabase, field_batteryLevel));
536 return MTP_RESPONSE_OK;
537 } else {
538 int type;
539
540 if (!getDevicePropertyInfo(property, type))
541 return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
542
543 jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
544 (jint)property, mLongBuffer, mStringBuffer);
545 if (result != MTP_RESPONSE_OK) {
546 checkAndClearExceptionFromCallback(env, __FUNCTION__);
547 return result;
548 }
549
550 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
551 jlong longValue = longValues[0];
552 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
553
554 switch (type) {
555 case MTP_TYPE_INT8:
556 packet.putInt8(longValue);
557 break;
558 case MTP_TYPE_UINT8:
559 packet.putUInt8(longValue);
560 break;
561 case MTP_TYPE_INT16:
562 packet.putInt16(longValue);
563 break;
564 case MTP_TYPE_UINT16:
565 packet.putUInt16(longValue);
566 break;
567 case MTP_TYPE_INT32:
568 packet.putInt32(longValue);
569 break;
570 case MTP_TYPE_UINT32:
571 packet.putUInt32(longValue);
572 break;
573 case MTP_TYPE_INT64:
574 packet.putInt64(longValue);
575 break;
576 case MTP_TYPE_UINT64:
577 packet.putUInt64(longValue);
578 break;
579 case MTP_TYPE_INT128:
580 packet.putInt128(longValue);
581 break;
582 case MTP_TYPE_UINT128:
583 packet.putInt128(longValue);
584 break;
585 case MTP_TYPE_STR:
586 {
587 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
588 packet.putString(str);
589 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
590 break;
591 }
592 default:
593 ALOGE("unsupported type in getDevicePropertyValue\n");
594 return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
595 }
596
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400597 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood56c85242014-03-07 13:29:08 -0800598 return MTP_RESPONSE_OK;
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400599 }
Mike Lockwood828d19d2010-08-10 15:20:35 -0400600}
601
602MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
603 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400604 int type;
605
606 if (!getDevicePropertyInfo(property, type))
607 return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
608
609 JNIEnv* env = AndroidRuntime::getJNIEnv();
610 jlong longValue = 0;
611 jstring stringValue = NULL;
612
613 switch (type) {
614 case MTP_TYPE_INT8:
615 longValue = packet.getInt8();
616 break;
617 case MTP_TYPE_UINT8:
618 longValue = packet.getUInt8();
619 break;
620 case MTP_TYPE_INT16:
621 longValue = packet.getInt16();
622 break;
623 case MTP_TYPE_UINT16:
624 longValue = packet.getUInt16();
625 break;
626 case MTP_TYPE_INT32:
627 longValue = packet.getInt32();
628 break;
629 case MTP_TYPE_UINT32:
630 longValue = packet.getUInt32();
631 break;
632 case MTP_TYPE_INT64:
633 longValue = packet.getInt64();
634 break;
635 case MTP_TYPE_UINT64:
636 longValue = packet.getUInt64();
637 break;
638 case MTP_TYPE_STR:
639 {
640 MtpStringBuffer buffer;
641 packet.getString(buffer);
642 stringValue = env->NewStringUTF((const char *)buffer);
643 break;
644 }
645 default:
Steve Block3762c312012-01-06 19:20:56 +0000646 ALOGE("unsupported type in setDevicePropertyValue\n");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400647 return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
648 }
649
650 jint result = env->CallIntMethod(mDatabase, method_setDeviceProperty,
651 (jint)property, longValue, stringValue);
Mike Lockwood88394712010-09-27 10:01:00 -0400652 if (stringValue)
653 env->DeleteLocalRef(stringValue);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400654
655 checkAndClearExceptionFromCallback(env, __FUNCTION__);
656 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400657}
658
Mark Salyzynaeb75fc2014-03-20 12:09:01 -0700659MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty /*property*/) {
Mike Lockwood828d19d2010-08-10 15:20:35 -0400660 return -1;
661}
662
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400663MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500664 uint32_t format, uint32_t property,
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400665 int groupCode, int depth,
666 MtpDataPacket& packet) {
667 JNIEnv* env = AndroidRuntime::getJNIEnv();
668 jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500669 (jlong)handle, (jint)format, (jlong)property, (jint)groupCode, (jint)depth);
670 checkAndClearExceptionFromCallback(env, __FUNCTION__);
671 if (!list)
672 return MTP_RESPONSE_GENERAL_ERROR;
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400673 int count = env->GetIntField(list, field_mCount);
674 MtpResponseCode result = env->GetIntField(list, field_mResult);
675
676 packet.putUInt32(count);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400677 if (count > 0) {
678 jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
679 jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
680 jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
681 jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
682 jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
683
684 jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
685 jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
686 jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
687 jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
688
689 for (int i = 0; i < count; i++) {
690 packet.putUInt32(objectHandles[i]);
691 packet.putUInt16(propertyCodes[i]);
692 int type = dataTypes[i];
693 packet.putUInt16(type);
694
695 switch (type) {
696 case MTP_TYPE_INT8:
697 packet.putInt8(longValues[i]);
698 break;
699 case MTP_TYPE_UINT8:
700 packet.putUInt8(longValues[i]);
701 break;
702 case MTP_TYPE_INT16:
703 packet.putInt16(longValues[i]);
704 break;
705 case MTP_TYPE_UINT16:
706 packet.putUInt16(longValues[i]);
707 break;
708 case MTP_TYPE_INT32:
709 packet.putInt32(longValues[i]);
710 break;
711 case MTP_TYPE_UINT32:
712 packet.putUInt32(longValues[i]);
713 break;
714 case MTP_TYPE_INT64:
715 packet.putInt64(longValues[i]);
716 break;
717 case MTP_TYPE_UINT64:
718 packet.putUInt64(longValues[i]);
719 break;
720 case MTP_TYPE_INT128:
721 packet.putInt128(longValues[i]);
722 break;
723 case MTP_TYPE_UINT128:
724 packet.putUInt128(longValues[i]);
725 break;
726 case MTP_TYPE_STR: {
727 jstring value = (jstring)env->GetObjectArrayElement(stringValuesArray, i);
Mike Lockwood2711e492010-12-11 11:24:37 -0800728 const char *valueStr = (value ? env->GetStringUTFChars(value, NULL) : NULL);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400729 if (valueStr) {
730 packet.putString(valueStr);
731 env->ReleaseStringUTFChars(value, valueStr);
732 } else {
733 packet.putEmptyString();
734 }
735 env->DeleteLocalRef(value);
736 break;
737 }
738 default:
Steve Block3762c312012-01-06 19:20:56 +0000739 ALOGE("bad or unsupported data type in MyMtpDatabase::getObjectPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400740 break;
741 }
742 }
743
744 env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
745 env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
746 env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
747 if (longValues)
748 env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
749
750 env->DeleteLocalRef(objectHandlesArray);
751 env->DeleteLocalRef(propertyCodesArray);
752 env->DeleteLocalRef(dataTypesArray);
753 if (longValuesArray)
754 env->DeleteLocalRef(longValuesArray);
755 if (stringValuesArray)
756 env->DeleteLocalRef(stringValuesArray);
757 }
758
759 env->DeleteLocalRef(list);
760 checkAndClearExceptionFromCallback(env, __FUNCTION__);
761 return result;
762}
763
Andreas Gampe5a15d0d2014-11-10 18:19:40 -0800764static void foreachentry(ExifEntry *entry, void* /* user */) {
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800765 char buf[1024];
766 ALOGI("entry %x, format %d, size %d: %s",
767 entry->tag, entry->format, entry->size, exif_entry_get_value(entry, buf, sizeof(buf)));
768}
769
770static void foreachcontent(ExifContent *content, void *user) {
771 ALOGI("content %d", exif_content_get_ifd(content));
772 exif_content_foreach_entry(content, foreachentry, user);
773}
774
775static long getLongFromExifEntry(ExifEntry *e) {
776 ExifByteOrder o = exif_data_get_byte_order(e->parent->parent);
777 return exif_get_long(e->data, o);
778}
779
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400780MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700781 MtpObjectInfo& info) {
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700782 MtpString path;
783 int64_t length;
784 MtpObjectFormat format;
785
786 MtpResponseCode result = getObjectFilePath(handle, path, length, format);
787 if (result != MTP_RESPONSE_OK) {
788 return result;
789 }
790 info.mCompressedSize = (length > 0xFFFFFFFFLL ? 0xFFFFFFFF : (uint32_t)length);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400791
792 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700793 if (!env->CallBooleanMethod(mDatabase, method_getObjectInfo,
794 (jint)handle, mIntBuffer, mStringBuffer, mLongBuffer)) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400795 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700796 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400797
798 jint* intValues = env->GetIntArrayElements(mIntBuffer, 0);
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700799 info.mStorageID = intValues[0];
800 info.mFormat = intValues[1];
801 info.mParent = intValues[2];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400802 env->ReleaseIntArrayElements(mIntBuffer, intValues, 0);
803
804 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
Mike Lockwood1341f1e2013-04-01 10:52:47 -0700805 info.mDateCreated = longValues[0];
806 info.mDateModified = longValues[1];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400807 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
808
Andreas Gampe5a15d0d2014-11-10 18:19:40 -0800809 if ((false)) {
810 info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ?
811 MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
812 MTP_ASSOCIATION_TYPE_UNDEFINED);
813 }
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700814 info.mAssociationType = MTP_ASSOCIATION_TYPE_UNDEFINED;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400815
816 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700817 MtpString temp(str);
818 info.mName = strdup((const char *)temp);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400819 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
820
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700821 // read EXIF data for thumbnail information
822 if (info.mFormat == MTP_FORMAT_EXIF_JPEG || info.mFormat == MTP_FORMAT_JFIF) {
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800823
824 ExifData *exifdata = exif_data_new_from_file(path);
825 if (exifdata) {
Andreas Gampe5a15d0d2014-11-10 18:19:40 -0800826 if ((false)) {
827 exif_data_foreach_content(exifdata, foreachcontent, NULL);
828 }
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800829
830 // XXX get this from exif, or parse jpeg header instead?
831 ExifEntry *w = exif_content_get_entry(
832 exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_X_DIMENSION);
833 ExifEntry *h = exif_content_get_entry(
834 exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_Y_DIMENSION);
835 info.mThumbCompressedSize = exifdata->data ? exifdata->size : 0;
836 info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
Marco Nelissen0937eed2014-01-22 15:10:57 -0800837 info.mImagePixWidth = w ? getLongFromExifEntry(w) : 0;
838 info.mImagePixHeight = h ? getLongFromExifEntry(h) : 0;
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800839 exif_data_unref(exifdata);
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700840 }
841 }
842
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400843 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400844 return MTP_RESPONSE_OK;
845}
846
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700847void* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) {
848 MtpString path;
849 int64_t length;
850 MtpObjectFormat format;
851 void* result = NULL;
852 outThumbSize = 0;
853
854 if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK
855 && (format == MTP_FORMAT_EXIF_JPEG || format == MTP_FORMAT_JFIF)) {
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800856
857 ExifData *exifdata = exif_data_new_from_file(path);
858 if (exifdata) {
859 if (exifdata->data) {
860 result = malloc(exifdata->size);
861 if (result) {
862 memcpy(result, exifdata->data, exifdata->size);
Mike Lockwoodc4367722014-04-21 08:49:30 -0700863 outThumbSize = exifdata->size;
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800864 }
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700865 }
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800866 exif_data_unref(exifdata);
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700867 }
868 }
869
870 return result;
871}
872
Mike Lockwood59c777a2010-08-02 10:37:41 -0400873MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle,
Mike Lockwood365e03e2010-12-08 16:08:01 -0800874 MtpString& outFilePath,
875 int64_t& outFileLength,
876 MtpObjectFormat& outFormat) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400877 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood59c777a2010-08-02 10:37:41 -0400878 jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400879 (jint)handle, mStringBuffer, mLongBuffer);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400880 if (result != MTP_RESPONSE_OK) {
881 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400882 return result;
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400883 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400884
885 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
Mike Lockwood365e03e2010-12-08 16:08:01 -0800886 outFilePath.setTo(str, strlen16(str));
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400887 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
888
889 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
Mike Lockwood365e03e2010-12-08 16:08:01 -0800890 outFileLength = longValues[0];
891 outFormat = longValues[1];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400892 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700893
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400894 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400895 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400896}
897
Mike Lockwood59c777a2010-08-02 10:37:41 -0400898MtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400899 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400900 MtpResponseCode result = env->CallIntMethod(mDatabase, method_deleteFile, (jint)handle);
901
902 checkAndClearExceptionFromCallback(env, __FUNCTION__);
903 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400904}
905
906struct PropertyTableEntry {
907 MtpObjectProperty property;
908 int type;
909};
910
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400911static const PropertyTableEntry kObjectPropertyTable[] = {
Mike Lockwoodd3bfecb2010-09-23 23:04:28 -0400912 { MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32 },
913 { MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16 },
914 { MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16 },
915 { MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64 },
916 { MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR },
917 { MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR },
918 { MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32 },
919 { MTP_PROPERTY_PERSISTENT_UID, MTP_TYPE_UINT128 },
920 { MTP_PROPERTY_NAME, MTP_TYPE_STR },
Mike Lockwoodae078f72010-09-26 12:35:51 -0400921 { MTP_PROPERTY_DISPLAY_NAME, MTP_TYPE_STR },
922 { MTP_PROPERTY_DATE_ADDED, MTP_TYPE_STR },
923 { MTP_PROPERTY_ARTIST, MTP_TYPE_STR },
924 { MTP_PROPERTY_ALBUM_NAME, MTP_TYPE_STR },
925 { MTP_PROPERTY_ALBUM_ARTIST, MTP_TYPE_STR },
926 { MTP_PROPERTY_TRACK, MTP_TYPE_UINT16 },
927 { MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_TYPE_STR },
928 { MTP_PROPERTY_GENRE, MTP_TYPE_STR },
929 { MTP_PROPERTY_COMPOSER, MTP_TYPE_STR },
930 { MTP_PROPERTY_DURATION, MTP_TYPE_UINT32 },
931 { MTP_PROPERTY_DESCRIPTION, MTP_TYPE_STR },
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400932};
933
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400934static const PropertyTableEntry kDevicePropertyTable[] = {
Mike Lockwoodea93fa12010-12-07 10:41:35 -0800935 { MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MTP_TYPE_STR },
936 { MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR },
937 { MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR },
Mike Lockwood56c85242014-03-07 13:29:08 -0800938 { MTP_DEVICE_PROPERTY_BATTERY_LEVEL, MTP_TYPE_UINT8 },
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400939};
940
941bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
942 int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
943 const PropertyTableEntry* entry = kObjectPropertyTable;
944 for (int i = 0; i < count; i++, entry++) {
945 if (entry->property == property) {
946 type = entry->type;
947 return true;
948 }
949 }
950 return false;
951}
952
953bool MyMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) {
954 int count = sizeof(kDevicePropertyTable) / sizeof(kDevicePropertyTable[0]);
955 const PropertyTableEntry* entry = kDevicePropertyTable;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400956 for (int i = 0; i < count; i++, entry++) {
957 if (entry->property == property) {
958 type = entry->type;
959 return true;
960 }
961 }
962 return false;
963}
964
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400965MtpObjectHandleList* MyMtpDatabase::getObjectReferences(MtpObjectHandle handle) {
966 JNIEnv* env = AndroidRuntime::getJNIEnv();
967 jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectReferences,
968 (jint)handle);
969 if (!array)
970 return NULL;
971 MtpObjectHandleList* list = new MtpObjectHandleList();
972 jint* handles = env->GetIntArrayElements(array, 0);
973 jsize length = env->GetArrayLength(array);
974 for (int i = 0; i < length; i++)
975 list->push(handles[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400976 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400977 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400978
979 checkAndClearExceptionFromCallback(env, __FUNCTION__);
980 return list;
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400981}
982
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400983MtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle,
984 MtpObjectHandleList* references) {
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400985 JNIEnv* env = AndroidRuntime::getJNIEnv();
986 int count = references->size();
987 jintArray array = env->NewIntArray(count);
988 if (!array) {
Steve Block3762c312012-01-06 19:20:56 +0000989 ALOGE("out of memory in setObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400990 return false;
991 }
992 jint* handles = env->GetIntArrayElements(array, 0);
993 for (int i = 0; i < count; i++)
994 handles[i] = (*references)[i];
995 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400996 MtpResponseCode result = env->CallIntMethod(mDatabase, method_setObjectReferences,
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400997 (jint)handle, array);
Mike Lockwood88394712010-09-27 10:01:00 -0400998 env->DeleteLocalRef(array);
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400999
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -04001000 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1001 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001002}
1003
Mike Lockwood828d19d2010-08-10 15:20:35 -04001004MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
1005 MtpObjectFormat format) {
Mike Lockwood92b53bc2014-03-13 14:51:29 -07001006 static const int channelEnum[] = {
1007 1, // mono
1008 2, // stereo
1009 3, // 2.1
1010 4, // 3
1011 5, // 3.1
1012 6, // 4
1013 7, // 4.1
1014 8, // 5
1015 9, // 5.1
1016 };
1017 static const int bitrateEnum[] = {
1018 1, // fixed rate
1019 2, // variable rate
1020 };
1021
Mike Lockwood828d19d2010-08-10 15:20:35 -04001022 MtpProperty* result = NULL;
1023 switch (property) {
1024 case MTP_PROPERTY_OBJECT_FORMAT:
Mike Lockwood9b5e9c42010-12-07 18:53:50 -08001025 // use format as default value
1026 result = new MtpProperty(property, MTP_TYPE_UINT16, false, format);
1027 break;
Mike Lockwood828d19d2010-08-10 15:20:35 -04001028 case MTP_PROPERTY_PROTECTION_STATUS:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001029 case MTP_PROPERTY_TRACK:
Mike Lockwood828d19d2010-08-10 15:20:35 -04001030 result = new MtpProperty(property, MTP_TYPE_UINT16);
1031 break;
1032 case MTP_PROPERTY_STORAGE_ID:
1033 case MTP_PROPERTY_PARENT_OBJECT:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001034 case MTP_PROPERTY_DURATION:
Mike Lockwood92b53bc2014-03-13 14:51:29 -07001035 case MTP_PROPERTY_AUDIO_WAVE_CODEC:
Mike Lockwood828d19d2010-08-10 15:20:35 -04001036 result = new MtpProperty(property, MTP_TYPE_UINT32);
1037 break;
1038 case MTP_PROPERTY_OBJECT_SIZE:
1039 result = new MtpProperty(property, MTP_TYPE_UINT64);
1040 break;
1041 case MTP_PROPERTY_PERSISTENT_UID:
1042 result = new MtpProperty(property, MTP_TYPE_UINT128);
1043 break;
Mike Lockwoodd3bfecb2010-09-23 23:04:28 -04001044 case MTP_PROPERTY_NAME:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001045 case MTP_PROPERTY_DISPLAY_NAME:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001046 case MTP_PROPERTY_ARTIST:
1047 case MTP_PROPERTY_ALBUM_NAME:
1048 case MTP_PROPERTY_ALBUM_ARTIST:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001049 case MTP_PROPERTY_GENRE:
1050 case MTP_PROPERTY_COMPOSER:
1051 case MTP_PROPERTY_DESCRIPTION:
Mike Lockwood828d19d2010-08-10 15:20:35 -04001052 result = new MtpProperty(property, MTP_TYPE_STR);
1053 break;
Mike Lockwood5b19af02010-11-23 18:38:55 -05001054 case MTP_PROPERTY_DATE_MODIFIED:
1055 case MTP_PROPERTY_DATE_ADDED:
1056 case MTP_PROPERTY_ORIGINAL_RELEASE_DATE:
1057 result = new MtpProperty(property, MTP_TYPE_STR);
1058 result->setFormDateTime();
1059 break;
Mike Lockwood5ebac832010-10-12 11:33:47 -04001060 case MTP_PROPERTY_OBJECT_FILE_NAME:
Mike Lockwood6a6a3af2010-10-12 14:19:51 -04001061 // We allow renaming files and folders
1062 result = new MtpProperty(property, MTP_TYPE_STR, true);
Mike Lockwood5ebac832010-10-12 11:33:47 -04001063 break;
Mike Lockwood92b53bc2014-03-13 14:51:29 -07001064 case MTP_PROPERTY_BITRATE_TYPE:
1065 result = new MtpProperty(property, MTP_TYPE_UINT16);
1066 result->setFormEnum(bitrateEnum, sizeof(bitrateEnum)/sizeof(bitrateEnum[0]));
1067 break;
1068 case MTP_PROPERTY_AUDIO_BITRATE:
1069 result = new MtpProperty(property, MTP_TYPE_UINT32);
1070 result->setFormRange(1, 1536000, 1);
1071 break;
1072 case MTP_PROPERTY_NUMBER_OF_CHANNELS:
1073 result = new MtpProperty(property, MTP_TYPE_UINT16);
1074 result->setFormEnum(channelEnum, sizeof(channelEnum)/sizeof(channelEnum[0]));
1075 break;
1076 case MTP_PROPERTY_SAMPLE_RATE:
1077 result = new MtpProperty(property, MTP_TYPE_UINT32);
1078 result->setFormRange(8000, 48000, 1);
1079 break;
Mike Lockwood828d19d2010-08-10 15:20:35 -04001080 }
1081
1082 return result;
1083}
1084
1085MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001086 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001087 MtpProperty* result = NULL;
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001088 bool writable = false;
1089
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001090 switch (property) {
1091 case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
1092 case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001093 writable = true;
1094 // fall through
Mike Lockwood56c85242014-03-07 13:29:08 -08001095 case MTP_DEVICE_PROPERTY_IMAGE_SIZE: {
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001096 result = new MtpProperty(property, MTP_TYPE_STR, writable);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001097
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001098 // get current value
Mike Lockwooda2a21282010-09-25 21:21:05 -04001099 jint ret = env->CallIntMethod(mDatabase, method_getDeviceProperty,
1100 (jint)property, mLongBuffer, mStringBuffer);
1101 if (ret == MTP_RESPONSE_OK) {
1102 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
1103 result->setCurrentValue(str);
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001104 // for read-only properties it is safe to assume current value is default value
1105 if (!writable)
1106 result->setDefaultValue(str);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001107 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
1108 } else {
Steve Block3762c312012-01-06 19:20:56 +00001109 ALOGE("unable to read device property, response: %04X", ret);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001110 }
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001111 break;
Mike Lockwood56c85242014-03-07 13:29:08 -08001112 }
1113 case MTP_DEVICE_PROPERTY_BATTERY_LEVEL:
1114 result = new MtpProperty(property, MTP_TYPE_UINT8);
1115 result->setFormRange(0, env->GetIntField(mDatabase, field_batteryScale), 1);
1116 result->mCurrentValue.u.u8 = (uint8_t)env->GetIntField(mDatabase, field_batteryLevel);
1117 break;
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001118 }
1119
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001120 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001121 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -04001122}
1123
Mike Lockwood2837eef2010-08-31 16:25:12 -04001124void MyMtpDatabase::sessionStarted() {
1125 JNIEnv* env = AndroidRuntime::getJNIEnv();
1126 env->CallVoidMethod(mDatabase, method_sessionStarted);
1127 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1128}
1129
1130void MyMtpDatabase::sessionEnded() {
1131 JNIEnv* env = AndroidRuntime::getJNIEnv();
1132 env->CallVoidMethod(mDatabase, method_sessionEnded);
1133 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1134}
1135
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001136// ----------------------------------------------------------------------------
1137
1138static void
Mike Lockwood0cd01362010-12-30 11:54:33 -05001139android_mtp_MtpDatabase_setup(JNIEnv *env, jobject thiz)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001140{
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001141 MyMtpDatabase* database = new MyMtpDatabase(env, thiz);
Ashok Bhate2e59322013-12-17 19:04:19 +00001142 env->SetLongField(thiz, field_context, (jlong)database);
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001143 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1144}
1145
1146static void
Mike Lockwood0cd01362010-12-30 11:54:33 -05001147android_mtp_MtpDatabase_finalize(JNIEnv *env, jobject thiz)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001148{
Ashok Bhate2e59322013-12-17 19:04:19 +00001149 MyMtpDatabase* database = (MyMtpDatabase *)env->GetLongField(thiz, field_context);
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001150 database->cleanup(env);
1151 delete database;
Ashok Bhate2e59322013-12-17 19:04:19 +00001152 env->SetLongField(thiz, field_context, 0);
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001153 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1154}
1155
Mike Lockwood31599912010-11-15 13:43:30 -05001156static jstring
Mark Salyzynaeb75fc2014-03-20 12:09:01 -07001157android_mtp_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject /*thiz*/, jlong seconds)
Mike Lockwood31599912010-11-15 13:43:30 -05001158{
Mike Lockwood31599912010-11-15 13:43:30 -05001159 char date[20];
1160 formatDateTime(seconds, date, sizeof(date));
1161 return env->NewStringUTF(date);
Mike Lockwood31599912010-11-15 13:43:30 -05001162}
1163
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001164// ----------------------------------------------------------------------------
1165
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001166static JNINativeMethod gMtpDatabaseMethods[] = {
Mike Lockwood0cd01362010-12-30 11:54:33 -05001167 {"native_setup", "()V", (void *)android_mtp_MtpDatabase_setup},
1168 {"native_finalize", "()V", (void *)android_mtp_MtpDatabase_finalize},
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001169};
1170
1171static JNINativeMethod gMtpPropertyGroupMethods[] = {
Mike Lockwood31599912010-11-15 13:43:30 -05001172 {"format_date_time", "(J)Ljava/lang/String;",
Mike Lockwood0cd01362010-12-30 11:54:33 -05001173 (void *)android_mtp_MtpPropertyGroup_format_date_time},
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001174};
1175
Mike Lockwood0cd01362010-12-30 11:54:33 -05001176static const char* const kClassPathName = "android/mtp/MtpDatabase";
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001177
Mike Lockwood0cd01362010-12-30 11:54:33 -05001178int register_android_mtp_MtpDatabase(JNIEnv *env)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001179{
1180 jclass clazz;
1181
Mike Lockwood0cd01362010-12-30 11:54:33 -05001182 clazz = env->FindClass("android/mtp/MtpDatabase");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001183 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001184 ALOGE("Can't find android/mtp/MtpDatabase");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001185 return -1;
1186 }
Mike Lockwoodd815f792010-07-12 08:49:01 -04001187 method_beginSendObject = env->GetMethodID(clazz, "beginSendObject", "(Ljava/lang/String;IIIJJ)I");
1188 if (method_beginSendObject == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001189 ALOGE("Can't find beginSendObject");
Mike Lockwoodd815f792010-07-12 08:49:01 -04001190 return -1;
1191 }
Mike Lockwood7a0bd172011-01-18 11:06:19 -08001192 method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIZ)V");
Mike Lockwoodd815f792010-07-12 08:49:01 -04001193 if (method_endSendObject == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001194 ALOGE("Can't find endSendObject");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001195 return -1;
1196 }
1197 method_getObjectList = env->GetMethodID(clazz, "getObjectList", "(III)[I");
1198 if (method_getObjectList == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001199 ALOGE("Can't find getObjectList");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001200 return -1;
1201 }
Mike Lockwood7a047c82010-08-02 10:52:20 -04001202 method_getNumObjects = env->GetMethodID(clazz, "getNumObjects", "(III)I");
1203 if (method_getNumObjects == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001204 ALOGE("Can't find getNumObjects");
Mike Lockwood7a047c82010-08-02 10:52:20 -04001205 return -1;
1206 }
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001207 method_getSupportedPlaybackFormats = env->GetMethodID(clazz, "getSupportedPlaybackFormats", "()[I");
1208 if (method_getSupportedPlaybackFormats == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001209 ALOGE("Can't find getSupportedPlaybackFormats");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001210 return -1;
1211 }
1212 method_getSupportedCaptureFormats = env->GetMethodID(clazz, "getSupportedCaptureFormats", "()[I");
1213 if (method_getSupportedCaptureFormats == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001214 ALOGE("Can't find getSupportedCaptureFormats");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001215 return -1;
1216 }
1217 method_getSupportedObjectProperties = env->GetMethodID(clazz, "getSupportedObjectProperties", "(I)[I");
1218 if (method_getSupportedObjectProperties == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001219 ALOGE("Can't find getSupportedObjectProperties");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001220 return -1;
1221 }
1222 method_getSupportedDeviceProperties = env->GetMethodID(clazz, "getSupportedDeviceProperties", "()[I");
1223 if (method_getSupportedDeviceProperties == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001224 ALOGE("Can't find getSupportedDeviceProperties");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001225 return -1;
1226 }
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001227 method_setObjectProperty = env->GetMethodID(clazz, "setObjectProperty", "(IIJLjava/lang/String;)I");
1228 if (method_setObjectProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001229 ALOGE("Can't find setObjectProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001230 return -1;
1231 }
1232 method_getDeviceProperty = env->GetMethodID(clazz, "getDeviceProperty", "(I[J[C)I");
1233 if (method_getDeviceProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001234 ALOGE("Can't find getDeviceProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001235 return -1;
1236 }
1237 method_setDeviceProperty = env->GetMethodID(clazz, "setDeviceProperty", "(IJLjava/lang/String;)I");
1238 if (method_setDeviceProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001239 ALOGE("Can't find setDeviceProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001240 return -1;
1241 }
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001242 method_getObjectPropertyList = env->GetMethodID(clazz, "getObjectPropertyList",
Mike Lockwood0cd01362010-12-30 11:54:33 -05001243 "(JIJII)Landroid/mtp/MtpPropertyList;");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001244 if (method_getObjectPropertyList == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001245 ALOGE("Can't find getObjectPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001246 return -1;
1247 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001248 method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z");
1249 if (method_getObjectInfo == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001250 ALOGE("Can't find getObjectInfo");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001251 return -1;
1252 }
Mike Lockwood59c777a2010-08-02 10:37:41 -04001253 method_getObjectFilePath = env->GetMethodID(clazz, "getObjectFilePath", "(I[C[J)I");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001254 if (method_getObjectFilePath == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001255 ALOGE("Can't find getObjectFilePath");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001256 return -1;
1257 }
Mike Lockwood59c777a2010-08-02 10:37:41 -04001258 method_deleteFile = env->GetMethodID(clazz, "deleteFile", "(I)I");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001259 if (method_deleteFile == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001260 ALOGE("Can't find deleteFile");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001261 return -1;
1262 }
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001263 method_getObjectReferences = env->GetMethodID(clazz, "getObjectReferences", "(I)[I");
1264 if (method_getObjectReferences == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001265 ALOGE("Can't find getObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001266 return -1;
1267 }
1268 method_setObjectReferences = env->GetMethodID(clazz, "setObjectReferences", "(I[I)I");
1269 if (method_setObjectReferences == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001270 ALOGE("Can't find setObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001271 return -1;
1272 }
Mike Lockwood2837eef2010-08-31 16:25:12 -04001273 method_sessionStarted = env->GetMethodID(clazz, "sessionStarted", "()V");
1274 if (method_sessionStarted == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001275 ALOGE("Can't find sessionStarted");
Mike Lockwood2837eef2010-08-31 16:25:12 -04001276 return -1;
1277 }
1278 method_sessionEnded = env->GetMethodID(clazz, "sessionEnded", "()V");
1279 if (method_sessionEnded == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001280 ALOGE("Can't find sessionEnded");
Mike Lockwood2837eef2010-08-31 16:25:12 -04001281 return -1;
1282 }
1283
Ashok Bhate2e59322013-12-17 19:04:19 +00001284 field_context = env->GetFieldID(clazz, "mNativeContext", "J");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001285 if (field_context == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001286 ALOGE("Can't find MtpDatabase.mNativeContext");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001287 return -1;
1288 }
Mike Lockwood56c85242014-03-07 13:29:08 -08001289 field_batteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
1290 if (field_batteryLevel == NULL) {
1291 ALOGE("Can't find MtpDatabase.mBatteryLevel");
1292 return -1;
1293 }
1294 field_batteryScale = env->GetFieldID(clazz, "mBatteryScale", "I");
1295 if (field_batteryScale == NULL) {
1296 ALOGE("Can't find MtpDatabase.mBatteryScale");
1297 return -1;
1298 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001299
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001300 // now set up fields for MtpPropertyList class
Mike Lockwood0cd01362010-12-30 11:54:33 -05001301 clazz = env->FindClass("android/mtp/MtpPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001302 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001303 ALOGE("Can't find android/mtp/MtpPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001304 return -1;
1305 }
1306 field_mCount = env->GetFieldID(clazz, "mCount", "I");
1307 if (field_mCount == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001308 ALOGE("Can't find MtpPropertyList.mCount");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001309 return -1;
1310 }
1311 field_mResult = env->GetFieldID(clazz, "mResult", "I");
1312 if (field_mResult == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001313 ALOGE("Can't find MtpPropertyList.mResult");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001314 return -1;
1315 }
1316 field_mObjectHandles = env->GetFieldID(clazz, "mObjectHandles", "[I");
1317 if (field_mObjectHandles == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001318 ALOGE("Can't find MtpPropertyList.mObjectHandles");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001319 return -1;
1320 }
1321 field_mPropertyCodes = env->GetFieldID(clazz, "mPropertyCodes", "[I");
1322 if (field_mPropertyCodes == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001323 ALOGE("Can't find MtpPropertyList.mPropertyCodes");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001324 return -1;
1325 }
1326 field_mDataTypes = env->GetFieldID(clazz, "mDataTypes", "[I");
1327 if (field_mDataTypes == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001328 ALOGE("Can't find MtpPropertyList.mDataTypes");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001329 return -1;
1330 }
1331 field_mLongValues = env->GetFieldID(clazz, "mLongValues", "[J");
1332 if (field_mLongValues == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001333 ALOGE("Can't find MtpPropertyList.mLongValues");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001334 return -1;
1335 }
1336 field_mStringValues = env->GetFieldID(clazz, "mStringValues", "[Ljava/lang/String;");
1337 if (field_mStringValues == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001338 ALOGE("Can't find MtpPropertyList.mStringValues");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001339 return -1;
1340 }
1341
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001342 if (AndroidRuntime::registerNativeMethods(env,
Mike Lockwood0cd01362010-12-30 11:54:33 -05001343 "android/mtp/MtpDatabase", gMtpDatabaseMethods, NELEM(gMtpDatabaseMethods)))
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001344 return -1;
1345
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001346 return AndroidRuntime::registerNativeMethods(env,
Mike Lockwood0cd01362010-12-30 11:54:33 -05001347 "android/mtp/MtpPropertyGroup", gMtpPropertyGroupMethods, NELEM(gMtpPropertyGroupMethods));
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001348}