blob: 62b4a3693a371359854855ad65c6c2324566b1a9 [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);
Mike Lockwood63ffd782014-09-24 10:55:19 -0700210 // Needs to be long enough to hold a file path for getObjectFilePath()
211 jcharArray charArray = env->NewCharArray(PATH_MAX + 1);
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700212 if (!charArray) {
213 return; // Already threw.
214 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400215 mStringBuffer = (jcharArray)env->NewGlobalRef(charArray);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400216}
217
218void MyMtpDatabase::cleanup(JNIEnv *env) {
219 env->DeleteGlobalRef(mDatabase);
220 env->DeleteGlobalRef(mIntBuffer);
221 env->DeleteGlobalRef(mLongBuffer);
222 env->DeleteGlobalRef(mStringBuffer);
223}
224
225MyMtpDatabase::~MyMtpDatabase() {
226}
227
Mike Lockwoodd815f792010-07-12 08:49:01 -0400228MtpObjectHandle MyMtpDatabase::beginSendObject(const char* path,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400229 MtpObjectFormat format,
230 MtpObjectHandle parent,
231 MtpStorageID storage,
232 uint64_t size,
233 time_t modified) {
234 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood88394712010-09-27 10:01:00 -0400235 jstring pathStr = env->NewStringUTF(path);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400236 MtpObjectHandle result = env->CallIntMethod(mDatabase, method_beginSendObject,
Mike Lockwood88394712010-09-27 10:01:00 -0400237 pathStr, (jint)format, (jint)parent, (jint)storage,
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400238 (jlong)size, (jlong)modified);
239
Mike Lockwood88394712010-09-27 10:01:00 -0400240 if (pathStr)
241 env->DeleteLocalRef(pathStr);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400242 checkAndClearExceptionFromCallback(env, __FUNCTION__);
243 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400244}
245
Mike Lockwoodd815f792010-07-12 08:49:01 -0400246void MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
Mike Lockwood7a0bd172011-01-18 11:06:19 -0800247 MtpObjectFormat format, bool succeeded) {
Mike Lockwoodd815f792010-07-12 08:49:01 -0400248 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood88394712010-09-27 10:01:00 -0400249 jstring pathStr = env->NewStringUTF(path);
250 env->CallVoidMethod(mDatabase, method_endSendObject, pathStr,
Mike Lockwood7a0bd172011-01-18 11:06:19 -0800251 (jint)handle, (jint)format, (jboolean)succeeded);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400252
Mike Lockwood88394712010-09-27 10:01:00 -0400253 if (pathStr)
254 env->DeleteLocalRef(pathStr);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400255 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodd815f792010-07-12 08:49:01 -0400256}
257
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400258MtpObjectHandleList* MyMtpDatabase::getObjectList(MtpStorageID storageID,
259 MtpObjectFormat format,
260 MtpObjectHandle parent) {
261 JNIEnv* env = AndroidRuntime::getJNIEnv();
262 jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectList,
263 (jint)storageID, (jint)format, (jint)parent);
264 if (!array)
265 return NULL;
266 MtpObjectHandleList* list = new MtpObjectHandleList();
267 jint* handles = env->GetIntArrayElements(array, 0);
268 jsize length = env->GetArrayLength(array);
Mike Lockwood7a047c82010-08-02 10:52:20 -0400269 for (int i = 0; i < length; i++)
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400270 list->push(handles[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400271 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400272 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400273
274 checkAndClearExceptionFromCallback(env, __FUNCTION__);
275 return list;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400276}
277
Mike Lockwood7a047c82010-08-02 10:52:20 -0400278int MyMtpDatabase::getNumObjects(MtpStorageID storageID,
279 MtpObjectFormat format,
280 MtpObjectHandle parent) {
281 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400282 int result = env->CallIntMethod(mDatabase, method_getNumObjects,
Mike Lockwood7a047c82010-08-02 10:52:20 -0400283 (jint)storageID, (jint)format, (jint)parent);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400284
285 checkAndClearExceptionFromCallback(env, __FUNCTION__);
286 return result;
Mike Lockwood7a047c82010-08-02 10:52:20 -0400287}
288
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400289MtpObjectFormatList* MyMtpDatabase::getSupportedPlaybackFormats() {
290 JNIEnv* env = AndroidRuntime::getJNIEnv();
291 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
292 method_getSupportedPlaybackFormats);
293 if (!array)
294 return NULL;
295 MtpObjectFormatList* list = new MtpObjectFormatList();
296 jint* formats = env->GetIntArrayElements(array, 0);
297 jsize length = env->GetArrayLength(array);
298 for (int i = 0; i < length; i++)
299 list->push(formats[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400300 env->ReleaseIntArrayElements(array, formats, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400301 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400302
303 checkAndClearExceptionFromCallback(env, __FUNCTION__);
304 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400305}
306
307MtpObjectFormatList* MyMtpDatabase::getSupportedCaptureFormats() {
308 JNIEnv* env = AndroidRuntime::getJNIEnv();
309 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
310 method_getSupportedCaptureFormats);
311 if (!array)
312 return NULL;
313 MtpObjectFormatList* list = new MtpObjectFormatList();
314 jint* formats = env->GetIntArrayElements(array, 0);
315 jsize length = env->GetArrayLength(array);
316 for (int i = 0; i < length; i++)
317 list->push(formats[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400318 env->ReleaseIntArrayElements(array, formats, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400319 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400320
321 checkAndClearExceptionFromCallback(env, __FUNCTION__);
322 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400323}
324
325MtpObjectPropertyList* MyMtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) {
326 JNIEnv* env = AndroidRuntime::getJNIEnv();
327 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
328 method_getSupportedObjectProperties, (jint)format);
329 if (!array)
330 return NULL;
331 MtpObjectPropertyList* list = new MtpObjectPropertyList();
332 jint* properties = env->GetIntArrayElements(array, 0);
333 jsize length = env->GetArrayLength(array);
334 for (int i = 0; i < length; i++)
335 list->push(properties[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400336 env->ReleaseIntArrayElements(array, properties, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400337 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400338
339 checkAndClearExceptionFromCallback(env, __FUNCTION__);
340 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400341}
342
343MtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
344 JNIEnv* env = AndroidRuntime::getJNIEnv();
345 jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
346 method_getSupportedDeviceProperties);
347 if (!array)
348 return NULL;
349 MtpDevicePropertyList* list = new MtpDevicePropertyList();
350 jint* properties = env->GetIntArrayElements(array, 0);
351 jsize length = env->GetArrayLength(array);
352 for (int i = 0; i < length; i++)
353 list->push(properties[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400354 env->ReleaseIntArrayElements(array, properties, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400355 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400356
357 checkAndClearExceptionFromCallback(env, __FUNCTION__);
358 return list;
Mike Lockwood4b322ce2010-08-10 07:37:50 -0400359}
360
Mike Lockwood828d19d2010-08-10 15:20:35 -0400361MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400362 MtpObjectProperty property,
363 MtpDataPacket& packet) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400364 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400365 jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500366 (jlong)handle, 0, (jlong)property, 0, 0);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400367 MtpResponseCode result = env->GetIntField(list, field_mResult);
368 int count = env->GetIntField(list, field_mCount);
369 if (result == MTP_RESPONSE_OK && count != 1)
370 result = MTP_RESPONSE_GENERAL_ERROR;
371
372 if (result == MTP_RESPONSE_OK) {
373 jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
374 jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
375 jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
376 jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
377 jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
378
379 jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
380 jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
381 jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
382 jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
383
384 int type = dataTypes[0];
385 jlong longValue = (longValues ? longValues[0] : 0);
386
387 // special case date properties, which are strings to MTP
388 // but stored internally as a uint64
389 if (property == MTP_PROPERTY_DATE_MODIFIED || property == MTP_PROPERTY_DATE_ADDED) {
390 char date[20];
391 formatDateTime(longValue, date, sizeof(date));
392 packet.putString(date);
393 goto out;
394 }
395 // release date is stored internally as just the year
396 if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) {
397 char date[20];
Mark Salyzynaeb75fc2014-03-20 12:09:01 -0700398 snprintf(date, sizeof(date), "%04" PRId64 "0101T000000", longValue);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400399 packet.putString(date);
400 goto out;
401 }
402
403 switch (type) {
404 case MTP_TYPE_INT8:
405 packet.putInt8(longValue);
406 break;
407 case MTP_TYPE_UINT8:
408 packet.putUInt8(longValue);
409 break;
410 case MTP_TYPE_INT16:
411 packet.putInt16(longValue);
412 break;
413 case MTP_TYPE_UINT16:
414 packet.putUInt16(longValue);
415 break;
416 case MTP_TYPE_INT32:
417 packet.putInt32(longValue);
418 break;
419 case MTP_TYPE_UINT32:
420 packet.putUInt32(longValue);
421 break;
422 case MTP_TYPE_INT64:
423 packet.putInt64(longValue);
424 break;
425 case MTP_TYPE_UINT64:
426 packet.putUInt64(longValue);
427 break;
428 case MTP_TYPE_INT128:
429 packet.putInt128(longValue);
430 break;
431 case MTP_TYPE_UINT128:
432 packet.putInt128(longValue);
433 break;
434 case MTP_TYPE_STR:
435 {
436 jstring stringValue = (jstring)env->GetObjectArrayElement(stringValuesArray, 0);
Martin Blumenstingl17a24c52014-05-31 15:50:38 +0200437 const char* str = (stringValue ? env->GetStringUTFChars(stringValue, NULL) : NULL);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400438 if (stringValue) {
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400439 packet.putString(str);
440 env->ReleaseStringUTFChars(stringValue, str);
441 } else {
442 packet.putEmptyString();
443 }
Martin Blumenstingl17a24c52014-05-31 15:50:38 +0200444 env->DeleteLocalRef(stringValue);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400445 break;
446 }
447 default:
Steve Block3762c312012-01-06 19:20:56 +0000448 ALOGE("unsupported type in getObjectPropertyValue\n");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400449 result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
450 }
451out:
452 env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
453 env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
454 env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
455 if (longValues)
456 env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
457
458 env->DeleteLocalRef(objectHandlesArray);
459 env->DeleteLocalRef(propertyCodesArray);
460 env->DeleteLocalRef(dataTypesArray);
461 if (longValuesArray)
462 env->DeleteLocalRef(longValuesArray);
463 if (stringValuesArray)
464 env->DeleteLocalRef(stringValuesArray);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400465 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400466
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400467 env->DeleteLocalRef(list);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400468 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400469 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400470}
471
Mike Lockwood828d19d2010-08-10 15:20:35 -0400472MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
473 MtpObjectProperty property,
474 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400475 int type;
476
477 if (!getObjectPropertyInfo(property, type))
478 return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
479
480 JNIEnv* env = AndroidRuntime::getJNIEnv();
481 jlong longValue = 0;
482 jstring stringValue = NULL;
483
484 switch (type) {
485 case MTP_TYPE_INT8:
486 longValue = packet.getInt8();
487 break;
488 case MTP_TYPE_UINT8:
489 longValue = packet.getUInt8();
490 break;
491 case MTP_TYPE_INT16:
492 longValue = packet.getInt16();
493 break;
494 case MTP_TYPE_UINT16:
495 longValue = packet.getUInt16();
496 break;
497 case MTP_TYPE_INT32:
498 longValue = packet.getInt32();
499 break;
500 case MTP_TYPE_UINT32:
501 longValue = packet.getUInt32();
502 break;
503 case MTP_TYPE_INT64:
504 longValue = packet.getInt64();
505 break;
506 case MTP_TYPE_UINT64:
507 longValue = packet.getUInt64();
508 break;
509 case MTP_TYPE_STR:
510 {
511 MtpStringBuffer buffer;
512 packet.getString(buffer);
513 stringValue = env->NewStringUTF((const char *)buffer);
514 break;
515 }
516 default:
Martin Blumenstingl986b46d2014-05-31 15:53:00 +0200517 ALOGE("unsupported type in setObjectPropertyValue\n");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400518 return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
519 }
520
521 jint result = env->CallIntMethod(mDatabase, method_setObjectProperty,
522 (jint)handle, (jint)property, longValue, stringValue);
Mike Lockwood88394712010-09-27 10:01:00 -0400523 if (stringValue)
524 env->DeleteLocalRef(stringValue);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400525
526 checkAndClearExceptionFromCallback(env, __FUNCTION__);
527 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400528}
529
530MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
531 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400532 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood56c85242014-03-07 13:29:08 -0800533
534 if (property == MTP_DEVICE_PROPERTY_BATTERY_LEVEL) {
535 // special case - implemented here instead of Java
536 packet.putUInt8((uint8_t)env->GetIntField(mDatabase, field_batteryLevel));
537 return MTP_RESPONSE_OK;
538 } else {
539 int type;
540
541 if (!getDevicePropertyInfo(property, type))
542 return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
543
544 jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
545 (jint)property, mLongBuffer, mStringBuffer);
546 if (result != MTP_RESPONSE_OK) {
547 checkAndClearExceptionFromCallback(env, __FUNCTION__);
548 return result;
549 }
550
551 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
552 jlong longValue = longValues[0];
553 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
554
555 switch (type) {
556 case MTP_TYPE_INT8:
557 packet.putInt8(longValue);
558 break;
559 case MTP_TYPE_UINT8:
560 packet.putUInt8(longValue);
561 break;
562 case MTP_TYPE_INT16:
563 packet.putInt16(longValue);
564 break;
565 case MTP_TYPE_UINT16:
566 packet.putUInt16(longValue);
567 break;
568 case MTP_TYPE_INT32:
569 packet.putInt32(longValue);
570 break;
571 case MTP_TYPE_UINT32:
572 packet.putUInt32(longValue);
573 break;
574 case MTP_TYPE_INT64:
575 packet.putInt64(longValue);
576 break;
577 case MTP_TYPE_UINT64:
578 packet.putUInt64(longValue);
579 break;
580 case MTP_TYPE_INT128:
581 packet.putInt128(longValue);
582 break;
583 case MTP_TYPE_UINT128:
584 packet.putInt128(longValue);
585 break;
586 case MTP_TYPE_STR:
587 {
588 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
589 packet.putString(str);
590 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
591 break;
592 }
593 default:
594 ALOGE("unsupported type in getDevicePropertyValue\n");
595 return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
596 }
597
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400598 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood56c85242014-03-07 13:29:08 -0800599 return MTP_RESPONSE_OK;
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400600 }
Mike Lockwood828d19d2010-08-10 15:20:35 -0400601}
602
603MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
604 MtpDataPacket& packet) {
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400605 int type;
606
607 if (!getDevicePropertyInfo(property, type))
608 return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
609
610 JNIEnv* env = AndroidRuntime::getJNIEnv();
611 jlong longValue = 0;
612 jstring stringValue = NULL;
613
614 switch (type) {
615 case MTP_TYPE_INT8:
616 longValue = packet.getInt8();
617 break;
618 case MTP_TYPE_UINT8:
619 longValue = packet.getUInt8();
620 break;
621 case MTP_TYPE_INT16:
622 longValue = packet.getInt16();
623 break;
624 case MTP_TYPE_UINT16:
625 longValue = packet.getUInt16();
626 break;
627 case MTP_TYPE_INT32:
628 longValue = packet.getInt32();
629 break;
630 case MTP_TYPE_UINT32:
631 longValue = packet.getUInt32();
632 break;
633 case MTP_TYPE_INT64:
634 longValue = packet.getInt64();
635 break;
636 case MTP_TYPE_UINT64:
637 longValue = packet.getUInt64();
638 break;
639 case MTP_TYPE_STR:
640 {
641 MtpStringBuffer buffer;
642 packet.getString(buffer);
643 stringValue = env->NewStringUTF((const char *)buffer);
644 break;
645 }
646 default:
Steve Block3762c312012-01-06 19:20:56 +0000647 ALOGE("unsupported type in setDevicePropertyValue\n");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400648 return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
649 }
650
651 jint result = env->CallIntMethod(mDatabase, method_setDeviceProperty,
652 (jint)property, longValue, stringValue);
Mike Lockwood88394712010-09-27 10:01:00 -0400653 if (stringValue)
654 env->DeleteLocalRef(stringValue);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400655
656 checkAndClearExceptionFromCallback(env, __FUNCTION__);
657 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -0400658}
659
Mark Salyzynaeb75fc2014-03-20 12:09:01 -0700660MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty /*property*/) {
Mike Lockwood828d19d2010-08-10 15:20:35 -0400661 return -1;
662}
663
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400664MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500665 uint32_t format, uint32_t property,
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400666 int groupCode, int depth,
667 MtpDataPacket& packet) {
668 JNIEnv* env = AndroidRuntime::getJNIEnv();
669 jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500670 (jlong)handle, (jint)format, (jlong)property, (jint)groupCode, (jint)depth);
671 checkAndClearExceptionFromCallback(env, __FUNCTION__);
672 if (!list)
673 return MTP_RESPONSE_GENERAL_ERROR;
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400674 int count = env->GetIntField(list, field_mCount);
675 MtpResponseCode result = env->GetIntField(list, field_mResult);
676
677 packet.putUInt32(count);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400678 if (count > 0) {
679 jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
680 jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
681 jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
682 jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
683 jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
684
685 jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
686 jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
687 jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
688 jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
689
690 for (int i = 0; i < count; i++) {
691 packet.putUInt32(objectHandles[i]);
692 packet.putUInt16(propertyCodes[i]);
693 int type = dataTypes[i];
694 packet.putUInt16(type);
695
696 switch (type) {
697 case MTP_TYPE_INT8:
698 packet.putInt8(longValues[i]);
699 break;
700 case MTP_TYPE_UINT8:
701 packet.putUInt8(longValues[i]);
702 break;
703 case MTP_TYPE_INT16:
704 packet.putInt16(longValues[i]);
705 break;
706 case MTP_TYPE_UINT16:
707 packet.putUInt16(longValues[i]);
708 break;
709 case MTP_TYPE_INT32:
710 packet.putInt32(longValues[i]);
711 break;
712 case MTP_TYPE_UINT32:
713 packet.putUInt32(longValues[i]);
714 break;
715 case MTP_TYPE_INT64:
716 packet.putInt64(longValues[i]);
717 break;
718 case MTP_TYPE_UINT64:
719 packet.putUInt64(longValues[i]);
720 break;
721 case MTP_TYPE_INT128:
722 packet.putInt128(longValues[i]);
723 break;
724 case MTP_TYPE_UINT128:
725 packet.putUInt128(longValues[i]);
726 break;
727 case MTP_TYPE_STR: {
728 jstring value = (jstring)env->GetObjectArrayElement(stringValuesArray, i);
Mike Lockwood2711e492010-12-11 11:24:37 -0800729 const char *valueStr = (value ? env->GetStringUTFChars(value, NULL) : NULL);
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400730 if (valueStr) {
731 packet.putString(valueStr);
732 env->ReleaseStringUTFChars(value, valueStr);
733 } else {
734 packet.putEmptyString();
735 }
736 env->DeleteLocalRef(value);
737 break;
738 }
739 default:
Steve Block3762c312012-01-06 19:20:56 +0000740 ALOGE("bad or unsupported data type in MyMtpDatabase::getObjectPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -0400741 break;
742 }
743 }
744
745 env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
746 env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
747 env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
748 if (longValues)
749 env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
750
751 env->DeleteLocalRef(objectHandlesArray);
752 env->DeleteLocalRef(propertyCodesArray);
753 env->DeleteLocalRef(dataTypesArray);
754 if (longValuesArray)
755 env->DeleteLocalRef(longValuesArray);
756 if (stringValuesArray)
757 env->DeleteLocalRef(stringValuesArray);
758 }
759
760 env->DeleteLocalRef(list);
761 checkAndClearExceptionFromCallback(env, __FUNCTION__);
762 return result;
763}
764
Mike Lockwood63ffd782014-09-24 10:55:19 -0700765static void foreachentry(ExifEntry *entry, void * /*user*/) {
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800766 char buf[1024];
767 ALOGI("entry %x, format %d, size %d: %s",
768 entry->tag, entry->format, entry->size, exif_entry_get_value(entry, buf, sizeof(buf)));
769}
770
771static void foreachcontent(ExifContent *content, void *user) {
772 ALOGI("content %d", exif_content_get_ifd(content));
773 exif_content_foreach_entry(content, foreachentry, user);
774}
775
776static long getLongFromExifEntry(ExifEntry *e) {
777 ExifByteOrder o = exif_data_get_byte_order(e->parent->parent);
778 return exif_get_long(e->data, o);
779}
780
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400781MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700782 MtpObjectInfo& info) {
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700783 char date[20];
784 MtpString path;
785 int64_t length;
786 MtpObjectFormat format;
787
788 MtpResponseCode result = getObjectFilePath(handle, path, length, format);
789 if (result != MTP_RESPONSE_OK) {
790 return result;
791 }
792 info.mCompressedSize = (length > 0xFFFFFFFFLL ? 0xFFFFFFFF : (uint32_t)length);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400793
794 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700795 if (!env->CallBooleanMethod(mDatabase, method_getObjectInfo,
796 (jint)handle, mIntBuffer, mStringBuffer, mLongBuffer)) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400797 return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
Mike Lockwoodf6f16612012-09-12 15:50:59 -0700798 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400799
800 jint* intValues = env->GetIntArrayElements(mIntBuffer, 0);
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700801 info.mStorageID = intValues[0];
802 info.mFormat = intValues[1];
803 info.mParent = intValues[2];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400804 env->ReleaseIntArrayElements(mIntBuffer, intValues, 0);
805
806 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
Mike Lockwood1341f1e2013-04-01 10:52:47 -0700807 info.mDateCreated = longValues[0];
808 info.mDateModified = longValues[1];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400809 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
810
Mike Lockwood9df53fae2011-04-21 17:05:55 -0700811// info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ?
Mike Lockwood828d19d2010-08-10 15:20:35 -0400812// MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
813// MTP_ASSOCIATION_TYPE_UNDEFINED);
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) {
826 //exif_data_foreach_content(exifdata, foreachcontent, NULL);
827
828 // XXX get this from exif, or parse jpeg header instead?
829 ExifEntry *w = exif_content_get_entry(
830 exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_X_DIMENSION);
831 ExifEntry *h = exif_content_get_entry(
832 exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_Y_DIMENSION);
833 info.mThumbCompressedSize = exifdata->data ? exifdata->size : 0;
834 info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
Marco Nelissen0937eed2014-01-22 15:10:57 -0800835 info.mImagePixWidth = w ? getLongFromExifEntry(w) : 0;
836 info.mImagePixHeight = h ? getLongFromExifEntry(h) : 0;
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800837 exif_data_unref(exifdata);
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700838 }
839 }
840
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400841 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400842 return MTP_RESPONSE_OK;
843}
844
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700845void* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) {
846 MtpString path;
847 int64_t length;
848 MtpObjectFormat format;
849 void* result = NULL;
850 outThumbSize = 0;
851
852 if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK
853 && (format == MTP_FORMAT_EXIF_JPEG || format == MTP_FORMAT_JFIF)) {
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800854
855 ExifData *exifdata = exif_data_new_from_file(path);
856 if (exifdata) {
857 if (exifdata->data) {
858 result = malloc(exifdata->size);
859 if (result) {
860 memcpy(result, exifdata->data, exifdata->size);
Mike Lockwoodc4367722014-04-21 08:49:30 -0700861 outThumbSize = exifdata->size;
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800862 }
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700863 }
Marco Nelissen3cd393c2014-01-10 10:39:27 -0800864 exif_data_unref(exifdata);
Mike Lockwoodc89f2222011-04-24 18:40:17 -0700865 }
866 }
867
868 return result;
869}
870
Mike Lockwood59c777a2010-08-02 10:37:41 -0400871MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle,
Mike Lockwood365e03e2010-12-08 16:08:01 -0800872 MtpString& outFilePath,
873 int64_t& outFileLength,
874 MtpObjectFormat& outFormat) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400875 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood59c777a2010-08-02 10:37:41 -0400876 jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath,
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400877 (jint)handle, mStringBuffer, mLongBuffer);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400878 if (result != MTP_RESPONSE_OK) {
879 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400880 return result;
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400881 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400882
883 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
Mike Lockwood365e03e2010-12-08 16:08:01 -0800884 outFilePath.setTo(str, strlen16(str));
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400885 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
886
887 jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
Mike Lockwood365e03e2010-12-08 16:08:01 -0800888 outFileLength = longValues[0];
889 outFormat = longValues[1];
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400890 env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
Elliott Hughes15dd15f2011-04-08 17:42:34 -0700891
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400892 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59c777a2010-08-02 10:37:41 -0400893 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400894}
895
Mike Lockwood59c777a2010-08-02 10:37:41 -0400896MtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) {
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400897 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400898 MtpResponseCode result = env->CallIntMethod(mDatabase, method_deleteFile, (jint)handle);
899
900 checkAndClearExceptionFromCallback(env, __FUNCTION__);
901 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400902}
903
904struct PropertyTableEntry {
905 MtpObjectProperty property;
906 int type;
907};
908
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400909static const PropertyTableEntry kObjectPropertyTable[] = {
Mike Lockwoodd3bfecb2010-09-23 23:04:28 -0400910 { MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32 },
911 { MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16 },
912 { MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16 },
913 { MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64 },
914 { MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR },
915 { MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR },
916 { MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32 },
917 { MTP_PROPERTY_PERSISTENT_UID, MTP_TYPE_UINT128 },
918 { MTP_PROPERTY_NAME, MTP_TYPE_STR },
Mike Lockwoodae078f72010-09-26 12:35:51 -0400919 { MTP_PROPERTY_DISPLAY_NAME, MTP_TYPE_STR },
920 { MTP_PROPERTY_DATE_ADDED, MTP_TYPE_STR },
921 { MTP_PROPERTY_ARTIST, MTP_TYPE_STR },
922 { MTP_PROPERTY_ALBUM_NAME, MTP_TYPE_STR },
923 { MTP_PROPERTY_ALBUM_ARTIST, MTP_TYPE_STR },
924 { MTP_PROPERTY_TRACK, MTP_TYPE_UINT16 },
925 { MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_TYPE_STR },
926 { MTP_PROPERTY_GENRE, MTP_TYPE_STR },
927 { MTP_PROPERTY_COMPOSER, MTP_TYPE_STR },
928 { MTP_PROPERTY_DURATION, MTP_TYPE_UINT32 },
929 { MTP_PROPERTY_DESCRIPTION, MTP_TYPE_STR },
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400930};
931
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400932static const PropertyTableEntry kDevicePropertyTable[] = {
Mike Lockwoodea93fa12010-12-07 10:41:35 -0800933 { MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MTP_TYPE_STR },
934 { MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR },
935 { MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR },
Mike Lockwood56c85242014-03-07 13:29:08 -0800936 { MTP_DEVICE_PROPERTY_BATTERY_LEVEL, MTP_TYPE_UINT8 },
Mike Lockwood59e3f0d2010-09-02 14:57:30 -0400937};
938
939bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
940 int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
941 const PropertyTableEntry* entry = kObjectPropertyTable;
942 for (int i = 0; i < count; i++, entry++) {
943 if (entry->property == property) {
944 type = entry->type;
945 return true;
946 }
947 }
948 return false;
949}
950
951bool MyMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) {
952 int count = sizeof(kDevicePropertyTable) / sizeof(kDevicePropertyTable[0]);
953 const PropertyTableEntry* entry = kDevicePropertyTable;
Mike Lockwoodd21eac92010-07-03 00:44:05 -0400954 for (int i = 0; i < count; i++, entry++) {
955 if (entry->property == property) {
956 type = entry->type;
957 return true;
958 }
959 }
960 return false;
961}
962
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400963MtpObjectHandleList* MyMtpDatabase::getObjectReferences(MtpObjectHandle handle) {
964 JNIEnv* env = AndroidRuntime::getJNIEnv();
965 jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectReferences,
966 (jint)handle);
967 if (!array)
968 return NULL;
969 MtpObjectHandleList* list = new MtpObjectHandleList();
970 jint* handles = env->GetIntArrayElements(array, 0);
971 jsize length = env->GetArrayLength(array);
972 for (int i = 0; i < length; i++)
973 list->push(handles[i]);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400974 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood88394712010-09-27 10:01:00 -0400975 env->DeleteLocalRef(array);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400976
977 checkAndClearExceptionFromCallback(env, __FUNCTION__);
978 return list;
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400979}
980
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400981MtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle,
982 MtpObjectHandleList* references) {
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400983 JNIEnv* env = AndroidRuntime::getJNIEnv();
984 int count = references->size();
985 jintArray array = env->NewIntArray(count);
986 if (!array) {
Steve Block3762c312012-01-06 19:20:56 +0000987 ALOGE("out of memory in setObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400988 return false;
989 }
990 jint* handles = env->GetIntArrayElements(array, 0);
991 for (int i = 0; i < count; i++)
992 handles[i] = (*references)[i];
993 env->ReleaseIntArrayElements(array, handles, 0);
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400994 MtpResponseCode result = env->CallIntMethod(mDatabase, method_setObjectReferences,
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400995 (jint)handle, array);
Mike Lockwood88394712010-09-27 10:01:00 -0400996 env->DeleteLocalRef(array);
Mike Lockwood9a2046f2010-08-03 15:30:09 -0400997
Mike Lockwood0a7fa0a2010-08-24 11:25:28 -0400998 checkAndClearExceptionFromCallback(env, __FUNCTION__);
999 return result;
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001000}
1001
Mike Lockwood828d19d2010-08-10 15:20:35 -04001002MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
1003 MtpObjectFormat format) {
Mike Lockwood92b53bc2014-03-13 14:51:29 -07001004 static const int channelEnum[] = {
1005 1, // mono
1006 2, // stereo
1007 3, // 2.1
1008 4, // 3
1009 5, // 3.1
1010 6, // 4
1011 7, // 4.1
1012 8, // 5
1013 9, // 5.1
1014 };
1015 static const int bitrateEnum[] = {
1016 1, // fixed rate
1017 2, // variable rate
1018 };
1019
Mike Lockwood828d19d2010-08-10 15:20:35 -04001020 MtpProperty* result = NULL;
1021 switch (property) {
1022 case MTP_PROPERTY_OBJECT_FORMAT:
Mike Lockwood9b5e9c42010-12-07 18:53:50 -08001023 // use format as default value
1024 result = new MtpProperty(property, MTP_TYPE_UINT16, false, format);
1025 break;
Mike Lockwood828d19d2010-08-10 15:20:35 -04001026 case MTP_PROPERTY_PROTECTION_STATUS:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001027 case MTP_PROPERTY_TRACK:
Mike Lockwood828d19d2010-08-10 15:20:35 -04001028 result = new MtpProperty(property, MTP_TYPE_UINT16);
1029 break;
1030 case MTP_PROPERTY_STORAGE_ID:
1031 case MTP_PROPERTY_PARENT_OBJECT:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001032 case MTP_PROPERTY_DURATION:
Mike Lockwood92b53bc2014-03-13 14:51:29 -07001033 case MTP_PROPERTY_AUDIO_WAVE_CODEC:
Mike Lockwood828d19d2010-08-10 15:20:35 -04001034 result = new MtpProperty(property, MTP_TYPE_UINT32);
1035 break;
1036 case MTP_PROPERTY_OBJECT_SIZE:
1037 result = new MtpProperty(property, MTP_TYPE_UINT64);
1038 break;
1039 case MTP_PROPERTY_PERSISTENT_UID:
1040 result = new MtpProperty(property, MTP_TYPE_UINT128);
1041 break;
Mike Lockwoodd3bfecb2010-09-23 23:04:28 -04001042 case MTP_PROPERTY_NAME:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001043 case MTP_PROPERTY_DISPLAY_NAME:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001044 case MTP_PROPERTY_ARTIST:
1045 case MTP_PROPERTY_ALBUM_NAME:
1046 case MTP_PROPERTY_ALBUM_ARTIST:
Mike Lockwoodae078f72010-09-26 12:35:51 -04001047 case MTP_PROPERTY_GENRE:
1048 case MTP_PROPERTY_COMPOSER:
1049 case MTP_PROPERTY_DESCRIPTION:
Mike Lockwood828d19d2010-08-10 15:20:35 -04001050 result = new MtpProperty(property, MTP_TYPE_STR);
1051 break;
Mike Lockwood5b19af02010-11-23 18:38:55 -05001052 case MTP_PROPERTY_DATE_MODIFIED:
1053 case MTP_PROPERTY_DATE_ADDED:
1054 case MTP_PROPERTY_ORIGINAL_RELEASE_DATE:
1055 result = new MtpProperty(property, MTP_TYPE_STR);
1056 result->setFormDateTime();
1057 break;
Mike Lockwood5ebac832010-10-12 11:33:47 -04001058 case MTP_PROPERTY_OBJECT_FILE_NAME:
Mike Lockwood6a6a3af2010-10-12 14:19:51 -04001059 // We allow renaming files and folders
1060 result = new MtpProperty(property, MTP_TYPE_STR, true);
Mike Lockwood5ebac832010-10-12 11:33:47 -04001061 break;
Mike Lockwood92b53bc2014-03-13 14:51:29 -07001062 case MTP_PROPERTY_BITRATE_TYPE:
1063 result = new MtpProperty(property, MTP_TYPE_UINT16);
1064 result->setFormEnum(bitrateEnum, sizeof(bitrateEnum)/sizeof(bitrateEnum[0]));
1065 break;
1066 case MTP_PROPERTY_AUDIO_BITRATE:
1067 result = new MtpProperty(property, MTP_TYPE_UINT32);
1068 result->setFormRange(1, 1536000, 1);
1069 break;
1070 case MTP_PROPERTY_NUMBER_OF_CHANNELS:
1071 result = new MtpProperty(property, MTP_TYPE_UINT16);
1072 result->setFormEnum(channelEnum, sizeof(channelEnum)/sizeof(channelEnum[0]));
1073 break;
1074 case MTP_PROPERTY_SAMPLE_RATE:
1075 result = new MtpProperty(property, MTP_TYPE_UINT32);
1076 result->setFormRange(8000, 48000, 1);
1077 break;
Mike Lockwood828d19d2010-08-10 15:20:35 -04001078 }
1079
1080 return result;
1081}
1082
1083MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001084 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001085 MtpProperty* result = NULL;
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001086 bool writable = false;
1087
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001088 switch (property) {
1089 case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
1090 case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001091 writable = true;
1092 // fall through
Mike Lockwood56c85242014-03-07 13:29:08 -08001093 case MTP_DEVICE_PROPERTY_IMAGE_SIZE: {
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001094 result = new MtpProperty(property, MTP_TYPE_STR, writable);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001095
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001096 // get current value
Mike Lockwooda2a21282010-09-25 21:21:05 -04001097 jint ret = env->CallIntMethod(mDatabase, method_getDeviceProperty,
1098 (jint)property, mLongBuffer, mStringBuffer);
1099 if (ret == MTP_RESPONSE_OK) {
1100 jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
1101 result->setCurrentValue(str);
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001102 // for read-only properties it is safe to assume current value is default value
1103 if (!writable)
1104 result->setDefaultValue(str);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001105 env->ReleaseCharArrayElements(mStringBuffer, str, 0);
1106 } else {
Steve Block3762c312012-01-06 19:20:56 +00001107 ALOGE("unable to read device property, response: %04X", ret);
Mike Lockwooda2a21282010-09-25 21:21:05 -04001108 }
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001109 break;
Mike Lockwood56c85242014-03-07 13:29:08 -08001110 }
1111 case MTP_DEVICE_PROPERTY_BATTERY_LEVEL:
1112 result = new MtpProperty(property, MTP_TYPE_UINT8);
1113 result->setFormRange(0, env->GetIntField(mDatabase, field_batteryScale), 1);
1114 result->mCurrentValue.u.u8 = (uint8_t)env->GetIntField(mDatabase, field_batteryLevel);
1115 break;
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001116 }
1117
Mike Lockwoodea93fa12010-12-07 10:41:35 -08001118 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001119 return result;
Mike Lockwood828d19d2010-08-10 15:20:35 -04001120}
1121
Mike Lockwood2837eef2010-08-31 16:25:12 -04001122void MyMtpDatabase::sessionStarted() {
1123 JNIEnv* env = AndroidRuntime::getJNIEnv();
1124 env->CallVoidMethod(mDatabase, method_sessionStarted);
1125 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1126}
1127
1128void MyMtpDatabase::sessionEnded() {
1129 JNIEnv* env = AndroidRuntime::getJNIEnv();
1130 env->CallVoidMethod(mDatabase, method_sessionEnded);
1131 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1132}
1133
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001134// ----------------------------------------------------------------------------
1135
1136static void
Mike Lockwood0cd01362010-12-30 11:54:33 -05001137android_mtp_MtpDatabase_setup(JNIEnv *env, jobject thiz)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001138{
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001139 MyMtpDatabase* database = new MyMtpDatabase(env, thiz);
Ashok Bhate2e59322013-12-17 19:04:19 +00001140 env->SetLongField(thiz, field_context, (jlong)database);
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001141 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1142}
1143
1144static void
Mike Lockwood0cd01362010-12-30 11:54:33 -05001145android_mtp_MtpDatabase_finalize(JNIEnv *env, jobject thiz)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001146{
Ashok Bhate2e59322013-12-17 19:04:19 +00001147 MyMtpDatabase* database = (MyMtpDatabase *)env->GetLongField(thiz, field_context);
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001148 database->cleanup(env);
1149 delete database;
Ashok Bhate2e59322013-12-17 19:04:19 +00001150 env->SetLongField(thiz, field_context, 0);
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001151 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1152}
1153
Mike Lockwood31599912010-11-15 13:43:30 -05001154static jstring
Mark Salyzynaeb75fc2014-03-20 12:09:01 -07001155android_mtp_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject /*thiz*/, jlong seconds)
Mike Lockwood31599912010-11-15 13:43:30 -05001156{
Mike Lockwood31599912010-11-15 13:43:30 -05001157 char date[20];
1158 formatDateTime(seconds, date, sizeof(date));
1159 return env->NewStringUTF(date);
Mike Lockwood31599912010-11-15 13:43:30 -05001160}
1161
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001162// ----------------------------------------------------------------------------
1163
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001164static JNINativeMethod gMtpDatabaseMethods[] = {
Mike Lockwood0cd01362010-12-30 11:54:33 -05001165 {"native_setup", "()V", (void *)android_mtp_MtpDatabase_setup},
1166 {"native_finalize", "()V", (void *)android_mtp_MtpDatabase_finalize},
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001167};
1168
1169static JNINativeMethod gMtpPropertyGroupMethods[] = {
Mike Lockwood31599912010-11-15 13:43:30 -05001170 {"format_date_time", "(J)Ljava/lang/String;",
Mike Lockwood0cd01362010-12-30 11:54:33 -05001171 (void *)android_mtp_MtpPropertyGroup_format_date_time},
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001172};
1173
Mike Lockwood0cd01362010-12-30 11:54:33 -05001174static const char* const kClassPathName = "android/mtp/MtpDatabase";
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001175
Mike Lockwood0cd01362010-12-30 11:54:33 -05001176int register_android_mtp_MtpDatabase(JNIEnv *env)
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001177{
1178 jclass clazz;
1179
Mike Lockwood0cd01362010-12-30 11:54:33 -05001180 clazz = env->FindClass("android/mtp/MtpDatabase");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001181 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001182 ALOGE("Can't find android/mtp/MtpDatabase");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001183 return -1;
1184 }
Mike Lockwoodd815f792010-07-12 08:49:01 -04001185 method_beginSendObject = env->GetMethodID(clazz, "beginSendObject", "(Ljava/lang/String;IIIJJ)I");
1186 if (method_beginSendObject == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001187 ALOGE("Can't find beginSendObject");
Mike Lockwoodd815f792010-07-12 08:49:01 -04001188 return -1;
1189 }
Mike Lockwood7a0bd172011-01-18 11:06:19 -08001190 method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIZ)V");
Mike Lockwoodd815f792010-07-12 08:49:01 -04001191 if (method_endSendObject == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001192 ALOGE("Can't find endSendObject");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001193 return -1;
1194 }
1195 method_getObjectList = env->GetMethodID(clazz, "getObjectList", "(III)[I");
1196 if (method_getObjectList == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001197 ALOGE("Can't find getObjectList");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001198 return -1;
1199 }
Mike Lockwood7a047c82010-08-02 10:52:20 -04001200 method_getNumObjects = env->GetMethodID(clazz, "getNumObjects", "(III)I");
1201 if (method_getNumObjects == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001202 ALOGE("Can't find getNumObjects");
Mike Lockwood7a047c82010-08-02 10:52:20 -04001203 return -1;
1204 }
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001205 method_getSupportedPlaybackFormats = env->GetMethodID(clazz, "getSupportedPlaybackFormats", "()[I");
1206 if (method_getSupportedPlaybackFormats == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001207 ALOGE("Can't find getSupportedPlaybackFormats");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001208 return -1;
1209 }
1210 method_getSupportedCaptureFormats = env->GetMethodID(clazz, "getSupportedCaptureFormats", "()[I");
1211 if (method_getSupportedCaptureFormats == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001212 ALOGE("Can't find getSupportedCaptureFormats");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001213 return -1;
1214 }
1215 method_getSupportedObjectProperties = env->GetMethodID(clazz, "getSupportedObjectProperties", "(I)[I");
1216 if (method_getSupportedObjectProperties == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001217 ALOGE("Can't find getSupportedObjectProperties");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001218 return -1;
1219 }
1220 method_getSupportedDeviceProperties = env->GetMethodID(clazz, "getSupportedDeviceProperties", "()[I");
1221 if (method_getSupportedDeviceProperties == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001222 ALOGE("Can't find getSupportedDeviceProperties");
Mike Lockwood4b322ce2010-08-10 07:37:50 -04001223 return -1;
1224 }
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001225 method_setObjectProperty = env->GetMethodID(clazz, "setObjectProperty", "(IIJLjava/lang/String;)I");
1226 if (method_setObjectProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001227 ALOGE("Can't find setObjectProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001228 return -1;
1229 }
1230 method_getDeviceProperty = env->GetMethodID(clazz, "getDeviceProperty", "(I[J[C)I");
1231 if (method_getDeviceProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001232 ALOGE("Can't find getDeviceProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001233 return -1;
1234 }
1235 method_setDeviceProperty = env->GetMethodID(clazz, "setDeviceProperty", "(IJLjava/lang/String;)I");
1236 if (method_setDeviceProperty == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001237 ALOGE("Can't find setDeviceProperty");
Mike Lockwood59e3f0d2010-09-02 14:57:30 -04001238 return -1;
1239 }
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001240 method_getObjectPropertyList = env->GetMethodID(clazz, "getObjectPropertyList",
Mike Lockwood0cd01362010-12-30 11:54:33 -05001241 "(JIJII)Landroid/mtp/MtpPropertyList;");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001242 if (method_getObjectPropertyList == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001243 ALOGE("Can't find getObjectPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001244 return -1;
1245 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001246 method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z");
1247 if (method_getObjectInfo == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001248 ALOGE("Can't find getObjectInfo");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001249 return -1;
1250 }
Mike Lockwood59c777a2010-08-02 10:37:41 -04001251 method_getObjectFilePath = env->GetMethodID(clazz, "getObjectFilePath", "(I[C[J)I");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001252 if (method_getObjectFilePath == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001253 ALOGE("Can't find getObjectFilePath");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001254 return -1;
1255 }
Mike Lockwood59c777a2010-08-02 10:37:41 -04001256 method_deleteFile = env->GetMethodID(clazz, "deleteFile", "(I)I");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001257 if (method_deleteFile == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001258 ALOGE("Can't find deleteFile");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001259 return -1;
1260 }
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001261 method_getObjectReferences = env->GetMethodID(clazz, "getObjectReferences", "(I)[I");
1262 if (method_getObjectReferences == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001263 ALOGE("Can't find getObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001264 return -1;
1265 }
1266 method_setObjectReferences = env->GetMethodID(clazz, "setObjectReferences", "(I[I)I");
1267 if (method_setObjectReferences == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001268 ALOGE("Can't find setObjectReferences");
Mike Lockwood9a2046f2010-08-03 15:30:09 -04001269 return -1;
1270 }
Mike Lockwood2837eef2010-08-31 16:25:12 -04001271 method_sessionStarted = env->GetMethodID(clazz, "sessionStarted", "()V");
1272 if (method_sessionStarted == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001273 ALOGE("Can't find sessionStarted");
Mike Lockwood2837eef2010-08-31 16:25:12 -04001274 return -1;
1275 }
1276 method_sessionEnded = env->GetMethodID(clazz, "sessionEnded", "()V");
1277 if (method_sessionEnded == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001278 ALOGE("Can't find sessionEnded");
Mike Lockwood2837eef2010-08-31 16:25:12 -04001279 return -1;
1280 }
1281
Ashok Bhate2e59322013-12-17 19:04:19 +00001282 field_context = env->GetFieldID(clazz, "mNativeContext", "J");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001283 if (field_context == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001284 ALOGE("Can't find MtpDatabase.mNativeContext");
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001285 return -1;
1286 }
Mike Lockwood56c85242014-03-07 13:29:08 -08001287 field_batteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
1288 if (field_batteryLevel == NULL) {
1289 ALOGE("Can't find MtpDatabase.mBatteryLevel");
1290 return -1;
1291 }
1292 field_batteryScale = env->GetFieldID(clazz, "mBatteryScale", "I");
1293 if (field_batteryScale == NULL) {
1294 ALOGE("Can't find MtpDatabase.mBatteryScale");
1295 return -1;
1296 }
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001297
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001298 // now set up fields for MtpPropertyList class
Mike Lockwood0cd01362010-12-30 11:54:33 -05001299 clazz = env->FindClass("android/mtp/MtpPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001300 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001301 ALOGE("Can't find android/mtp/MtpPropertyList");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001302 return -1;
1303 }
1304 field_mCount = env->GetFieldID(clazz, "mCount", "I");
1305 if (field_mCount == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001306 ALOGE("Can't find MtpPropertyList.mCount");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001307 return -1;
1308 }
1309 field_mResult = env->GetFieldID(clazz, "mResult", "I");
1310 if (field_mResult == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001311 ALOGE("Can't find MtpPropertyList.mResult");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001312 return -1;
1313 }
1314 field_mObjectHandles = env->GetFieldID(clazz, "mObjectHandles", "[I");
1315 if (field_mObjectHandles == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001316 ALOGE("Can't find MtpPropertyList.mObjectHandles");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001317 return -1;
1318 }
1319 field_mPropertyCodes = env->GetFieldID(clazz, "mPropertyCodes", "[I");
1320 if (field_mPropertyCodes == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001321 ALOGE("Can't find MtpPropertyList.mPropertyCodes");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001322 return -1;
1323 }
1324 field_mDataTypes = env->GetFieldID(clazz, "mDataTypes", "[I");
1325 if (field_mDataTypes == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001326 ALOGE("Can't find MtpPropertyList.mDataTypes");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001327 return -1;
1328 }
1329 field_mLongValues = env->GetFieldID(clazz, "mLongValues", "[J");
1330 if (field_mLongValues == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001331 ALOGE("Can't find MtpPropertyList.mLongValues");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001332 return -1;
1333 }
1334 field_mStringValues = env->GetFieldID(clazz, "mStringValues", "[Ljava/lang/String;");
1335 if (field_mStringValues == NULL) {
Steve Block3762c312012-01-06 19:20:56 +00001336 ALOGE("Can't find MtpPropertyList.mStringValues");
Mike Lockwoode2ad6ec2010-10-14 18:03:25 -04001337 return -1;
1338 }
1339
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001340 if (AndroidRuntime::registerNativeMethods(env,
Mike Lockwood0cd01362010-12-30 11:54:33 -05001341 "android/mtp/MtpDatabase", gMtpDatabaseMethods, NELEM(gMtpDatabaseMethods)))
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001342 return -1;
1343
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001344 return AndroidRuntime::registerNativeMethods(env,
Mike Lockwood0cd01362010-12-30 11:54:33 -05001345 "android/mtp/MtpPropertyGroup", gMtpPropertyGroupMethods, NELEM(gMtpPropertyGroupMethods));
Mike Lockwoodd21eac92010-07-03 00:44:05 -04001346}