android_mtp_MtpDatabase.cpp revision 9b5e9c407d35eab4f37c208d81bdf0b8bcdbdf93
1d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood/*
2d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * Copyright (C) 2010 The Android Open Source Project
3d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood *
4d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
5d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * you may not use this file except in compliance with the License.
6d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * You may obtain a copy of the License at
7d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood *
8d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
9d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood *
10d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * Unless required by applicable law or agreed to in writing, software
11d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
12d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * See the License for the specific language governing permissions and
14d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * limitations under the License.
15d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood */
16d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
17d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#define LOG_TAG "MtpDatabaseJNI"
18d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "utils/Log.h"
19d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
20d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include <stdio.h>
21d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include <assert.h>
22d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include <limits.h>
23d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include <unistd.h>
24d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include <fcntl.h>
25d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
26d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "jni.h"
27d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "JNIHelp.h"
28d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "android_runtime/AndroidRuntime.h"
29d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
30d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "MtpDatabase.h"
31d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "MtpDataPacket.h"
32828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood#include "MtpProperty.h"
3359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood#include "MtpStringBuffer.h"
34d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "MtpUtils.h"
35d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "mtp.h"
36d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
37d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodusing namespace android;
38d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
39d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
40d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
41d815f79766984fce499e147ecbacc01914683f74Mike Lockwoodstatic jmethodID method_beginSendObject;
42d815f79766984fce499e147ecbacc01914683f74Mike Lockwoodstatic jmethodID method_endSendObject;
43d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_getObjectList;
447a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwoodstatic jmethodID method_getNumObjects;
454b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedPlaybackFormats;
464b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedCaptureFormats;
474b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedObjectProperties;
484b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedDeviceProperties;
49828d19dd96b05fa99abdc517701e5366543c324fMike Lockwoodstatic jmethodID method_setObjectProperty;
5059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic jmethodID method_getDeviceProperty;
5159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic jmethodID method_setDeviceProperty;
52e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jmethodID method_getObjectPropertyList;
53d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_getObjectInfo;
54d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_getObjectFilePath;
55d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_deleteFile;
569a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodstatic jmethodID method_getObjectReferences;
579a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodstatic jmethodID method_setObjectReferences;
582837eefc5459427138c080d445bb491c75630163Mike Lockwoodstatic jmethodID method_sessionStarted;
592837eefc5459427138c080d445bb491c75630163Mike Lockwoodstatic jmethodID method_sessionEnded;
602837eefc5459427138c080d445bb491c75630163Mike Lockwood
61d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jfieldID field_context;
62d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
63e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood// MtpPropertyList fields
64e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mCount;
65e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mResult;
66e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mObjectHandles;
67e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mPropertyCodes;
68e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mDataTypes;
69e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mLongValues;
70e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mStringValues;
71e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
72e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
73d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) {
74d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return (MtpDatabase *)env->GetIntField(database, field_context);
75d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
76d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
77ff164a7d6f839c194a52572136cfa320609598e0Mike Lockwood#ifdef HAVE_ANDROID_OS
78d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
79d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
80d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodclass MyMtpDatabase : public MtpDatabase {
81d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodprivate:
82d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jobject         mDatabase;
83d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jintArray       mIntBuffer;
84d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jlongArray      mLongBuffer;
85d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jcharArray      mStringBuffer;
86d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
87d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodpublic:
88d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MyMtpDatabase(JNIEnv *env, jobject client);
89d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    virtual                         ~MyMtpDatabase();
90d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    void                            cleanup(JNIEnv *env);
91d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
92d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    virtual MtpObjectHandle         beginSendObject(const char* path,
93d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectFormat format,
94d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectHandle parent,
95d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpStorageID storage,
96d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            uint64_t size,
97d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            time_t modified);
98d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
99d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    virtual void                    endSendObject(const char* path,
100d815f79766984fce499e147ecbacc01914683f74Mike Lockwood                                            MtpObjectHandle handle,
101d815f79766984fce499e147ecbacc01914683f74Mike Lockwood                                            MtpObjectFormat format,
102413577d8600413bb1dca3730d4ccf20892b929b4Mike Lockwood                                            int64_t actualSize,
103d815f79766984fce499e147ecbacc01914683f74Mike Lockwood                                            bool succeeded);
104d815f79766984fce499e147ecbacc01914683f74Mike Lockwood
105d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    virtual MtpObjectHandleList*    getObjectList(MtpStorageID storageID,
106d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectFormat format,
107d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectHandle parent);
108d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1097a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    virtual int                     getNumObjects(MtpStorageID storageID,
1107a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                            MtpObjectFormat format,
1117a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                            MtpObjectHandle parent);
1127a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood
1134b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    // callee should delete[] the results from these
1144b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    // results can be NULL
1154b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpObjectFormatList*    getSupportedPlaybackFormats();
1164b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpObjectFormatList*    getSupportedCaptureFormats();
1174b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpObjectPropertyList*  getSupportedObjectProperties(MtpObjectFormat format);
1184b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpDevicePropertyList*  getSupportedDeviceProperties();
1194b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
120828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         getObjectPropertyValue(MtpObjectHandle handle,
121d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectProperty property,
122d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpDataPacket& packet);
123d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
124828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         setObjectPropertyValue(MtpObjectHandle handle,
125828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectProperty property,
126828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet);
127828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
128828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         getDevicePropertyValue(MtpDeviceProperty property,
129828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet);
130828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
131828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         setDevicePropertyValue(MtpDeviceProperty property,
132828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet);
133828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
134828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         resetDeviceProperty(MtpDeviceProperty property);
135828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
136e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    virtual MtpResponseCode         getObjectPropertyList(MtpObjectHandle handle,
1377d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                            uint32_t format, uint32_t property,
138e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            int groupCode, int depth,
139e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            MtpDataPacket& packet);
140e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
141d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    virtual MtpResponseCode         getObjectInfo(MtpObjectHandle handle,
142d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpDataPacket& packet);
143d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
14459c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    virtual MtpResponseCode         getObjectFilePath(MtpObjectHandle handle,
145d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpString& filePath,
146d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            int64_t& fileLength);
14759c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    virtual MtpResponseCode         deleteFile(MtpObjectHandle handle);
148d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
14959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    bool                            getObjectPropertyInfo(MtpObjectProperty property, int& type);
15059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    bool                            getDevicePropertyInfo(MtpDeviceProperty property, int& type);
1519a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
1529a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    virtual MtpObjectHandleList*    getObjectReferences(MtpObjectHandle handle);
1539a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
1549a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    virtual MtpResponseCode         setObjectReferences(MtpObjectHandle handle,
1559a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                                            MtpObjectHandleList* references);
156828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
157828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpProperty*            getObjectPropertyDesc(MtpObjectProperty property,
158828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectFormat format);
159828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
160828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpProperty*            getDevicePropertyDesc(MtpDeviceProperty property);
1612837eefc5459427138c080d445bb491c75630163Mike Lockwood
1622837eefc5459427138c080d445bb491c75630163Mike Lockwood    virtual void                    sessionStarted();
1632837eefc5459427138c080d445bb491c75630163Mike Lockwood
1642837eefc5459427138c080d445bb491c75630163Mike Lockwood    virtual void                    sessionEnded();
165d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
166d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1670a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood// ----------------------------------------------------------------------------
1680a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
1690a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwoodstatic void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
1700a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    if (env->ExceptionCheck()) {
1710a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood        LOGE("An exception was thrown by callback '%s'.", methodName);
1720a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood        LOGE_EX(env);
1730a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood        env->ExceptionClear();
1740a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    }
1750a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood}
1760a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
1770a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood// ----------------------------------------------------------------------------
1780a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
179d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMyMtpDatabase::MyMtpDatabase(JNIEnv *env, jobject client)
180d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    :   mDatabase(env->NewGlobalRef(client)),
181d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mIntBuffer(NULL),
182d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mLongBuffer(NULL),
183d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mStringBuffer(NULL)
184d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
185d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jintArray intArray;
186d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jlongArray longArray;
187d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jcharArray charArray;
188d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
189d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    // create buffers for out arguments
190d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    // we don't need to be thread-safe so this is OK
191d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    intArray = env->NewIntArray(3);
192d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (!intArray)
193d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        goto out_of_memory;
194d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    mIntBuffer = (jintArray)env->NewGlobalRef(intArray);
195d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    longArray = env->NewLongArray(2);
196d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (!longArray)
197d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        goto out_of_memory;
198d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    mLongBuffer = (jlongArray)env->NewGlobalRef(longArray);
199d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    charArray = env->NewCharArray(256);
200d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (!charArray)
201d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        goto out_of_memory;
202d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    mStringBuffer = (jcharArray)env->NewGlobalRef(charArray);
203d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return;
204d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
205d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodout_of_memory:
206d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), NULL);
207d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
208d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
209d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodvoid MyMtpDatabase::cleanup(JNIEnv *env) {
210d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mDatabase);
211d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mIntBuffer);
212d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mLongBuffer);
213d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mStringBuffer);
214d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
215d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
216d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMyMtpDatabase::~MyMtpDatabase() {
217d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
218d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
219d815f79766984fce499e147ecbacc01914683f74Mike LockwoodMtpObjectHandle MyMtpDatabase::beginSendObject(const char* path,
220d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectFormat format,
221d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectHandle parent,
222d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpStorageID storage,
223d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            uint64_t size,
224d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            time_t modified) {
225d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2268839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    jstring pathStr = env->NewStringUTF(path);
2270a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    MtpObjectHandle result = env->CallIntMethod(mDatabase, method_beginSendObject,
2288839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood            pathStr, (jint)format, (jint)parent, (jint)storage,
2290a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood            (jlong)size, (jlong)modified);
2300a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2318839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (pathStr)
2328839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(pathStr);
2330a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
2340a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
235d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
236d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
237d815f79766984fce499e147ecbacc01914683f74Mike Lockwoodvoid MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
238413577d8600413bb1dca3730d4ccf20892b929b4Mike Lockwood                                MtpObjectFormat format, int64_t actualSize, bool succeeded) {
239d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2408839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    jstring pathStr = env->NewStringUTF(path);
2418839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->CallVoidMethod(mDatabase, method_endSendObject, pathStr,
242413577d8600413bb1dca3730d4ccf20892b929b4Mike Lockwood                        (jint)handle, (jint)format, (jlong)actualSize, (jboolean)succeeded);
2430a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2448839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (pathStr)
2458839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(pathStr);
2460a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
247d815f79766984fce499e147ecbacc01914683f74Mike Lockwood}
248d815f79766984fce499e147ecbacc01914683f74Mike Lockwood
249d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMtpObjectHandleList* MyMtpDatabase::getObjectList(MtpStorageID storageID,
250d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectFormat format,
251d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectHandle parent) {
252d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
253d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectList,
254d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                (jint)storageID, (jint)format, (jint)parent);
255d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (!array)
256d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return NULL;
257d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MtpObjectHandleList* list = new MtpObjectHandleList();
258d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jint* handles = env->GetIntArrayElements(array, 0);
259d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jsize length = env->GetArrayLength(array);
2607a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    for (int i = 0; i < length; i++)
261d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        list->push(handles[i]);
2620a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, handles, 0);
2638839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
2640a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2650a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
2660a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
267d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
268d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
2697a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwoodint MyMtpDatabase::getNumObjects(MtpStorageID storageID,
2707a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                MtpObjectFormat format,
2717a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                MtpObjectHandle parent) {
2727a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2730a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    int result = env->CallIntMethod(mDatabase, method_getNumObjects,
2747a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                (jint)storageID, (jint)format, (jint)parent);
2750a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2760a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
2770a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
2787a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood}
2797a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood
2804b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpObjectFormatList* MyMtpDatabase::getSupportedPlaybackFormats() {
2814b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2824b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
2834b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedPlaybackFormats);
2844b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
2854b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
2864b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpObjectFormatList* list = new MtpObjectFormatList();
2874b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* formats = env->GetIntArrayElements(array, 0);
2884b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
2894b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
2904b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(formats[i]);
2910a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, formats, 0);
2928839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
2930a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2940a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
2950a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
2964b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
2974b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
2984b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpObjectFormatList* MyMtpDatabase::getSupportedCaptureFormats() {
2994b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
3004b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
3014b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedCaptureFormats);
3024b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
3034b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
3044b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpObjectFormatList* list = new MtpObjectFormatList();
3054b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* formats = env->GetIntArrayElements(array, 0);
3064b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
3074b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
3084b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(formats[i]);
3090a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, formats, 0);
3108839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
3110a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
3120a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
3130a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
3144b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
3154b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
3164b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpObjectPropertyList* MyMtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) {
3174b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
3184b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
3194b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedObjectProperties, (jint)format);
3204b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
3214b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
3224b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpObjectPropertyList* list = new MtpObjectPropertyList();
3234b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* properties = env->GetIntArrayElements(array, 0);
3244b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
3254b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
3264b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(properties[i]);
3270a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, properties, 0);
3288839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
3290a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
3300a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
3310a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
3324b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
3334b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
3344b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
3354b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
3364b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
3374b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedDeviceProperties);
3384b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
3394b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
3404b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpDevicePropertyList* list = new MtpDevicePropertyList();
3414b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* properties = env->GetIntArrayElements(array, 0);
3424b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
3434b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
3444b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(properties[i]);
3450a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, properties, 0);
3468839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
3470a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
3480a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
3490a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
3504b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
3514b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
352828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
353d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectProperty property,
354d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpDataPacket& packet) {
355d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
356e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
3577d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                (jlong)handle, 0, (jlong)property, 0, 0);
358e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    MtpResponseCode result = env->GetIntField(list, field_mResult);
359e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    int count = env->GetIntField(list, field_mCount);
360e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (result == MTP_RESPONSE_OK && count != 1)
361e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        result = MTP_RESPONSE_GENERAL_ERROR;
362e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
363e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (result == MTP_RESPONSE_OK) {
364e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
365e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
366e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
367e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
368e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
369e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
370e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
371e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
372e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
373e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
374e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
375e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        int type = dataTypes[0];
376e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlong longValue = (longValues ? longValues[0] : 0);
377e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
378e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        // special case date properties, which are strings to MTP
379e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        // but stored internally as a uint64
380e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (property == MTP_PROPERTY_DATE_MODIFIED || property == MTP_PROPERTY_DATE_ADDED) {
381e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            char    date[20];
382e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            formatDateTime(longValue, date, sizeof(date));
383e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putString(date);
384e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            goto out;
385e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
386e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        // release date is stored internally as just the year
387e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) {
388e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            char    date[20];
389e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            snprintf(date, sizeof(date), "%04lld0101T000000", longValue);
390e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putString(date);
391e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            goto out;
392e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
393828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
394e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        switch (type) {
395e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT8:
396e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt8(longValue);
397e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
398e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT8:
399e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt8(longValue);
400e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
401e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT16:
402e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt16(longValue);
403e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
404e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT16:
405e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt16(longValue);
406e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
407e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT32:
408e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt32(longValue);
409e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
410e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT32:
411e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt32(longValue);
412e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
413e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT64:
414e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt64(longValue);
415e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
416e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT64:
417e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt64(longValue);
418e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
419e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT128:
420e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt128(longValue);
421e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
422e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT128:
423e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt128(longValue);
424e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
425e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_STR:
426e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            {
427e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                jstring stringValue = (jstring)env->GetObjectArrayElement(stringValuesArray, 0);
428e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                if (stringValue) {
429e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    const char* str = env->GetStringUTFChars(stringValue, NULL);
430e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putString(str);
431e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    env->ReleaseStringUTFChars(stringValue, str);
432e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                } else {
433e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putEmptyString();
434e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                }
435e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
436e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood             }
437e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            default:
438e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                LOGE("unsupported type in getObjectPropertyValue\n");
439e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
440e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
441e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodout:
442e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
443e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
444e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
445e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValues)
446e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
447e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
448e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(objectHandlesArray);
449e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(propertyCodesArray);
450e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(dataTypesArray);
451e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValuesArray)
452e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(longValuesArray);
453e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (stringValuesArray)
454e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(stringValuesArray);
455d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
4560a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
457e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    env->DeleteLocalRef(list);
4580a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
459e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    return result;
460d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
461d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
462828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
463828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectProperty property,
464828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet) {
46559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int         type;
46659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
46759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (!getObjectPropertyInfo(property, type))
46859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
46959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
47059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
47159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jlong longValue = 0;
47259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jstring stringValue = NULL;
47359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
47459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    switch (type) {
47559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT8:
47659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt8();
47759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
47859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT8:
47959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt8();
48059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
48159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT16:
48259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt16();
48359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
48459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT16:
48559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt16();
48659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
48759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT32:
48859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt32();
48959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
49059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT32:
49159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt32();
49259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
49359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT64:
49459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt64();
49559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
49659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT64:
49759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt64();
49859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
49959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_STR:
50059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        {
50159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            MtpStringBuffer buffer;
50259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.getString(buffer);
50359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            stringValue = env->NewStringUTF((const char *)buffer);
50459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
50559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood         }
50659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        default:
50759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            LOGE("unsupported type in getObjectPropertyValue\n");
50859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
50959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
51059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
51159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jint result = env->CallIntMethod(mDatabase, method_setObjectProperty,
51259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood                (jint)handle, (jint)property, longValue, stringValue);
5138839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (stringValue)
5148839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(stringValue);
51559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
51659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
51759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return result;
518828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
519828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
520828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
521828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet) {
52259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int         type;
52359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
52459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (!getDevicePropertyInfo(property, type))
52559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
52659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
52759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
52859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
52959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood                (jint)property, mLongBuffer, mStringBuffer);
53059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (result != MTP_RESPONSE_OK) {
53159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        checkAndClearExceptionFromCallback(env, __FUNCTION__);
53259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return result;
53359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
53459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
53559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
53659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jlong longValue = longValues[0];
53759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
53859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
53959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    switch (type) {
54059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT8:
54159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt8(longValue);
54259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
54359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT8:
54459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putUInt8(longValue);
54559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
54659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT16:
54759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt16(longValue);
54859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
54959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT16:
55059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putUInt16(longValue);
55159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
55259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT32:
55359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt32(longValue);
55459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
55559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT32:
55659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putUInt32(longValue);
55759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
55859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT64:
55959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt64(longValue);
56059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
56159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT64:
56259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putUInt64(longValue);
56359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
56459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT128:
56559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt128(longValue);
56659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
56759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT128:
56859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt128(longValue);
56959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
57059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_STR:
57159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        {
57259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
57359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putString(str);
57459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            env->ReleaseCharArrayElements(mStringBuffer, str, 0);
57559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
57659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood         }
57759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        default:
57859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            LOGE("unsupported type in getDevicePropertyValue\n");
57959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
58059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
58159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
58259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
58359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return MTP_RESPONSE_OK;
584828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
585828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
586828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
587828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet) {
58859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int         type;
58959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
59059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (!getDevicePropertyInfo(property, type))
59159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
59259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
59359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
59459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jlong longValue = 0;
59559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jstring stringValue = NULL;
59659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
59759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    switch (type) {
59859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT8:
59959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt8();
60059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
60159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT8:
60259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt8();
60359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
60459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT16:
60559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt16();
60659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
60759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT16:
60859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt16();
60959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
61059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT32:
61159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt32();
61259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
61359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT32:
61459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt32();
61559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
61659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT64:
61759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt64();
61859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
61959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT64:
62059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt64();
62159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
62259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_STR:
62359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        {
62459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            MtpStringBuffer buffer;
62559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.getString(buffer);
62659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            stringValue = env->NewStringUTF((const char *)buffer);
62759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
62859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood         }
62959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        default:
63059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            LOGE("unsupported type in setDevicePropertyValue\n");
63159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
63259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
63359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
63459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jint result = env->CallIntMethod(mDatabase, method_setDeviceProperty,
63559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood                (jint)property, longValue, stringValue);
6368839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (stringValue)
6378839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(stringValue);
63859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
63959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
64059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return result;
641828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
642828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
643828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty property) {
644828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    return -1;
645828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
646828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
647e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike LockwoodMtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
6487d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                            uint32_t format, uint32_t property,
649e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            int groupCode, int depth,
650e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            MtpDataPacket& packet) {
651e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
652e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
6537d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                (jlong)handle, (jint)format, (jlong)property, (jint)groupCode, (jint)depth);
6547d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
6557d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    if (!list)
6567d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        return MTP_RESPONSE_GENERAL_ERROR;
657e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    int count = env->GetIntField(list, field_mCount);
658e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    MtpResponseCode result = env->GetIntField(list, field_mResult);
659e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
660e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    packet.putUInt32(count);
661e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (count > 0) {
662e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
663e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
664e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
665e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
666e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
667e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
668e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
669e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
670e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
671e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
672e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
673e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        for (int i = 0; i < count; i++) {
674e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putUInt32(objectHandles[i]);
675e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putUInt16(propertyCodes[i]);
676e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            int type = dataTypes[i];
677e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putUInt16(type);
678e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
679e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            switch (type) {
680e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT8:
681e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt8(longValues[i]);
682e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
683e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT8:
684e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt8(longValues[i]);
685e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
686e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT16:
687e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt16(longValues[i]);
688e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
689e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT16:
690e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt16(longValues[i]);
691e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
692e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT32:
693e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt32(longValues[i]);
694e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
695e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT32:
696e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt32(longValues[i]);
697e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
698e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT64:
699e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt64(longValues[i]);
700e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
701e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT64:
702e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt64(longValues[i]);
703e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
704e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT128:
705e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt128(longValues[i]);
706e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
707e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT128:
708e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt128(longValues[i]);
709e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
710e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_STR: {
711e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    jstring value = (jstring)env->GetObjectArrayElement(stringValuesArray, i);
712e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    const char *valueStr = env->GetStringUTFChars(value, NULL);
713e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    if (valueStr) {
714e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                        packet.putString(valueStr);
715e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                        env->ReleaseStringUTFChars(value, valueStr);
716e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    } else {
717e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                        packet.putEmptyString();
718e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    }
719e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    env->DeleteLocalRef(value);
720e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
721e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                }
722e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                default:
723e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    LOGE("bad or unsupported data type in MyMtpDatabase::getObjectPropertyList");
724e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
725e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            }
726e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
727e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
728e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
729e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
730e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
731e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValues)
732e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
733e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
734e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(objectHandlesArray);
735e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(propertyCodesArray);
736e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(dataTypesArray);
737e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValuesArray)
738e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(longValuesArray);
739e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (stringValuesArray)
740e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(stringValuesArray);
741e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
742e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
743e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    env->DeleteLocalRef(list);
744e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
745e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    return result;
746e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood}
747e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
748d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
749d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpDataPacket& packet) {
750d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    char    date[20];
751d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
752d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
753d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jboolean result = env->CallBooleanMethod(mDatabase, method_getObjectInfo,
754d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                (jint)handle, mIntBuffer, mStringBuffer, mLongBuffer);
755d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (!result)
756d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
757d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
758d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jint* intValues = env->GetIntArrayElements(mIntBuffer, 0);
759d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MtpStorageID storageID = intValues[0];
760d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MtpObjectFormat format = intValues[1];
761d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MtpObjectHandle parent = intValues[2];
762d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseIntArrayElements(mIntBuffer, intValues, 0);
763d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
764d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
765d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    uint64_t size = longValues[0];
766d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    uint64_t modified = longValues[1];
767d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
768d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
769828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood//    int associationType = (format == MTP_FORMAT_ASSOCIATION ?
770828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood//                            MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
771828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood//                            MTP_ASSOCIATION_TYPE_UNDEFINED);
772828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    int associationType = MTP_ASSOCIATION_TYPE_UNDEFINED;
773d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
774d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt32(storageID);
775d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt16(format);
776d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt16(0);   // protection status
777d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt32((size > 0xFFFFFFFFLL ? 0xFFFFFFFF : size));
778d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt16(0);   // thumb format
779d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt32(0);   // thumb compressed size
780d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt32(0);   // thumb pix width
781d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt32(0);   // thumb pix height
782d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt32(0);   // image pix width
783d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt32(0);   // image pix height
784d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt32(0);   // image bit depth
785d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt32(parent);
786d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt16(associationType);
787d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt32(0);   // association desc
788d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putUInt32(0);   // sequence number
789d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
790d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
791d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putString(str);   // file name
792d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseCharArrayElements(mStringBuffer, str, 0);
793d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
794d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putEmptyString();
795d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    formatDateTime(modified, date, sizeof(date));
796d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putString(date);   // date modified
797d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    packet.putEmptyString();   // keywords
798d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
7990a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
800d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return MTP_RESPONSE_OK;
801d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
802d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
80359c777a24a2c639dfd84b7bf17e430e6d3424866Mike LockwoodMtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle,
804d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpString& filePath,
805d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            int64_t& fileLength) {
806d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
80759c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath,
808d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                (jint)handle, mStringBuffer, mLongBuffer);
80959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (result != MTP_RESPONSE_OK) {
81059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        checkAndClearExceptionFromCallback(env, __FUNCTION__);
81159c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood        return result;
81259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
813d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
814d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
815d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    filePath.setTo(str, strlen16(str));
816d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseCharArrayElements(mStringBuffer, str, 0);
817d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
818d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
819d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    fileLength = longValues[0];
820d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
821d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
8220a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
82359c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    return result;
824d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
825d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
82659c777a24a2c639dfd84b7bf17e430e6d3424866Mike LockwoodMtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) {
827d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
8280a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    MtpResponseCode result = env->CallIntMethod(mDatabase, method_deleteFile, (jint)handle);
8290a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
8300a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
8310a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
832d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
833d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
834d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstruct PropertyTableEntry {
835d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MtpObjectProperty   property;
836d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    int                 type;
837d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
838d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
83959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic const PropertyTableEntry   kObjectPropertyTable[] = {
840d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_STORAGE_ID,        MTP_TYPE_UINT32     },
841d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_OBJECT_FORMAT,     MTP_TYPE_UINT16     },
842d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16     },
843d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_OBJECT_SIZE,       MTP_TYPE_UINT64     },
844d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_OBJECT_FILE_NAME,  MTP_TYPE_STR        },
845d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_DATE_MODIFIED,     MTP_TYPE_STR        },
846d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_PARENT_OBJECT,     MTP_TYPE_UINT32     },
847d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_PERSISTENT_UID,    MTP_TYPE_UINT128    },
848d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_NAME,              MTP_TYPE_STR        },
849ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DISPLAY_NAME,      MTP_TYPE_STR        },
850ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DATE_ADDED,        MTP_TYPE_STR        },
851ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ARTIST,            MTP_TYPE_STR        },
852ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ALBUM_NAME,        MTP_TYPE_STR        },
853ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ALBUM_ARTIST,      MTP_TYPE_STR        },
854ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_TRACK,             MTP_TYPE_UINT16     },
855ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_TYPE_STR    },
856ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_GENRE,             MTP_TYPE_STR        },
857ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_COMPOSER,          MTP_TYPE_STR        },
858ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DURATION,          MTP_TYPE_UINT32     },
859ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DESCRIPTION,       MTP_TYPE_STR        },
860d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
861d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
86259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic const PropertyTableEntry   kDevicePropertyTable[] = {
863ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    {   MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,    MTP_TYPE_STR },
864ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    {   MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,       MTP_TYPE_STR },
865ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    {   MTP_DEVICE_PROPERTY_IMAGE_SIZE,                 MTP_TYPE_STR },
86659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood};
86759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
86859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodbool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
86959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
87059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    const PropertyTableEntry* entry = kObjectPropertyTable;
87159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    for (int i = 0; i < count; i++, entry++) {
87259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        if (entry->property == property) {
87359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            type = entry->type;
87459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            return true;
87559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        }
87659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
87759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return false;
87859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood}
87959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
88059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodbool MyMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) {
88159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int count = sizeof(kDevicePropertyTable) / sizeof(kDevicePropertyTable[0]);
88259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    const PropertyTableEntry* entry = kDevicePropertyTable;
883d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    for (int i = 0; i < count; i++, entry++) {
884d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        if (entry->property == property) {
885d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            type = entry->type;
886d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            return true;
887d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        }
888d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
889d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return false;
890d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
891d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
8929a2046fb5ceeee4d5334274cbff15f1058bb3244Mike LockwoodMtpObjectHandleList* MyMtpDatabase::getObjectReferences(MtpObjectHandle handle) {
8939a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
8949a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectReferences,
8959a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                (jint)handle);
8969a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (!array)
8979a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return NULL;
8989a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    MtpObjectHandleList* list = new MtpObjectHandleList();
8999a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jint* handles = env->GetIntArrayElements(array, 0);
9009a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jsize length = env->GetArrayLength(array);
9019a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    for (int i = 0; i < length; i++)
9029a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        list->push(handles[i]);
9030a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, handles, 0);
9048839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
9050a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
9060a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
9070a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
9089a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood}
9099a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
9100a7fa0a868ccce920827e141cbbe237594e53364Mike LockwoodMtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle,
9110a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood                                                    MtpObjectHandleList* references) {
9129a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
9139a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    int count = references->size();
9149a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jintArray array = env->NewIntArray(count);
9159a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (!array) {
9169a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        LOGE("out of memory in setObjectReferences");
9179a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return false;
9189a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    }
9199a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jint* handles = env->GetIntArrayElements(array, 0);
9209a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood     for (int i = 0; i < count; i++)
9219a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        handles[i] = (*references)[i];
9229a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    env->ReleaseIntArrayElements(array, handles, 0);
9230a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    MtpResponseCode result = env->CallIntMethod(mDatabase, method_setObjectReferences,
9249a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                (jint)handle, array);
9258839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
9269a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
9270a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
9280a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
929d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
930d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
931828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
932828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectFormat format) {
933828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    MtpProperty* result = NULL;
934828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    switch (property) {
935828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_OBJECT_FORMAT:
9369b5e9c407d35eab4f37c208d81bdf0b8bcdbdf93Mike Lockwood            // use format as default value
9379b5e9c407d35eab4f37c208d81bdf0b8bcdbdf93Mike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT16, false, format);
9389b5e9c407d35eab4f37c208d81bdf0b8bcdbdf93Mike Lockwood            break;
939828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_PROTECTION_STATUS:
940ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_TRACK:
941828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT16);
942828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
943828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_STORAGE_ID:
944828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_PARENT_OBJECT:
945ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_DURATION:
946828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT32);
947828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
948828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_OBJECT_SIZE:
949828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT64);
950828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
951828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_PERSISTENT_UID:
952828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT128);
953828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
954d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood        case MTP_PROPERTY_NAME:
955ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_DISPLAY_NAME:
956ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_ARTIST:
957ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_ALBUM_NAME:
958ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_ALBUM_ARTIST:
959ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_GENRE:
960ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_COMPOSER:
961ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_DESCRIPTION:
962828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR);
963828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
9645b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood        case MTP_PROPERTY_DATE_MODIFIED:
9655b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood        case MTP_PROPERTY_DATE_ADDED:
9665b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood        case MTP_PROPERTY_ORIGINAL_RELEASE_DATE:
9675b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR);
9685b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood            result->setFormDateTime();
9695b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood            break;
9705ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood        case MTP_PROPERTY_OBJECT_FILE_NAME:
9716a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood            // We allow renaming files and folders
9726a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR, true);
9735ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood            break;
974828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    }
975828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
976828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    return result;
977828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
978828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
979828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
980ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
98159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    MtpProperty* result = NULL;
982ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    bool writable = false;
983ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood
98459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    switch (property) {
98559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
98659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
987ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            writable = true;
988ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            // fall through
989ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood        case MTP_DEVICE_PROPERTY_IMAGE_SIZE:
990ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR, writable);
991a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood
992ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            // get current value
993a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            jint ret = env->CallIntMethod(mDatabase, method_getDeviceProperty,
994a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                        (jint)property, mLongBuffer, mStringBuffer);
995a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            if (ret == MTP_RESPONSE_OK) {
996a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
997a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                result->setCurrentValue(str);
998ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood                // for read-only properties it is safe to assume current value is default value
999ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood                if (!writable)
1000ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood                    result->setDefaultValue(str);
1001a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                env->ReleaseCharArrayElements(mStringBuffer, str, 0);
1002a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            } else {
1003a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                LOGE("unable to read device property, response: %04X", ret);
1004a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            }
100559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
100659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
100759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
1008ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
100959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return result;
1010828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
1011828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
10122837eefc5459427138c080d445bb491c75630163Mike Lockwoodvoid MyMtpDatabase::sessionStarted() {
10132837eefc5459427138c080d445bb491c75630163Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
10142837eefc5459427138c080d445bb491c75630163Mike Lockwood    env->CallVoidMethod(mDatabase, method_sessionStarted);
10152837eefc5459427138c080d445bb491c75630163Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
10162837eefc5459427138c080d445bb491c75630163Mike Lockwood}
10172837eefc5459427138c080d445bb491c75630163Mike Lockwood
10182837eefc5459427138c080d445bb491c75630163Mike Lockwoodvoid MyMtpDatabase::sessionEnded() {
10192837eefc5459427138c080d445bb491c75630163Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
10202837eefc5459427138c080d445bb491c75630163Mike Lockwood    env->CallVoidMethod(mDatabase, method_sessionEnded);
10212837eefc5459427138c080d445bb491c75630163Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
10222837eefc5459427138c080d445bb491c75630163Mike Lockwood}
10232837eefc5459427138c080d445bb491c75630163Mike Lockwood
1024ff164a7d6f839c194a52572136cfa320609598e0Mike Lockwood#endif // HAVE_ANDROID_OS
1025ff164a7d6f839c194a52572136cfa320609598e0Mike Lockwood
1026d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
1027d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1028d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic void
1029d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodandroid_media_MtpDatabase_setup(JNIEnv *env, jobject thiz)
1030d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
1031ff164a7d6f839c194a52572136cfa320609598e0Mike Lockwood#ifdef HAVE_ANDROID_OS
1032d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    LOGD("setup\n");
1033d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MyMtpDatabase* database = new MyMtpDatabase(env, thiz);
1034d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->SetIntField(thiz, field_context, (int)database);
1035d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
1036ff164a7d6f839c194a52572136cfa320609598e0Mike Lockwood#endif
1037d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
1038d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1039d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic void
1040d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodandroid_media_MtpDatabase_finalize(JNIEnv *env, jobject thiz)
1041d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
1042ff164a7d6f839c194a52572136cfa320609598e0Mike Lockwood#ifdef HAVE_ANDROID_OS
1043d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    LOGD("finalize\n");
1044d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MyMtpDatabase* database = (MyMtpDatabase *)env->GetIntField(thiz, field_context);
1045d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    database->cleanup(env);
1046d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    delete database;
1047d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->SetIntField(thiz, field_context, 0);
1048d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
1049ff164a7d6f839c194a52572136cfa320609598e0Mike Lockwood#endif
1050d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
1051d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
10523159991e586f9e243f60d65a9554828328b00521Mike Lockwoodstatic jstring
10537d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodandroid_media_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject thiz, jlong seconds)
10543159991e586f9e243f60d65a9554828328b00521Mike Lockwood{
10553159991e586f9e243f60d65a9554828328b00521Mike Lockwood#ifdef HAVE_ANDROID_OS
10563159991e586f9e243f60d65a9554828328b00521Mike Lockwood    char    date[20];
10573159991e586f9e243f60d65a9554828328b00521Mike Lockwood    formatDateTime(seconds, date, sizeof(date));
10583159991e586f9e243f60d65a9554828328b00521Mike Lockwood    return env->NewStringUTF(date);
10593159991e586f9e243f60d65a9554828328b00521Mike Lockwood#else
10603159991e586f9e243f60d65a9554828328b00521Mike Lockwood    return NULL;
10613159991e586f9e243f60d65a9554828328b00521Mike Lockwood#endif
10623159991e586f9e243f60d65a9554828328b00521Mike Lockwood}
10633159991e586f9e243f60d65a9554828328b00521Mike Lockwood
1064d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
1065d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
10667d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodstatic JNINativeMethod gMtpDatabaseMethods[] = {
1067d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    {"native_setup",            "()V",  (void *)android_media_MtpDatabase_setup},
1068d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    {"native_finalize",         "()V",  (void *)android_media_MtpDatabase_finalize},
10697d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood};
10707d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
10717d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodstatic JNINativeMethod gMtpPropertyGroupMethods[] = {
10723159991e586f9e243f60d65a9554828328b00521Mike Lockwood    {"format_date_time",        "(J)Ljava/lang/String;",
10737d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                        (void *)android_media_MtpPropertyGroup_format_date_time},
1074d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
1075d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1076d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic const char* const kClassPathName = "android/media/MtpDatabase";
1077d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1078d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodint register_android_media_MtpDatabase(JNIEnv *env)
1079d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
1080d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jclass clazz;
1081d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1082d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    LOGD("register_android_media_MtpDatabase\n");
1083d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1084d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    clazz = env->FindClass("android/media/MtpDatabase");
1085d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (clazz == NULL) {
1086d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        LOGE("Can't find android/media/MtpDatabase");
1087d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1088d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
1089d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    method_beginSendObject = env->GetMethodID(clazz, "beginSendObject", "(Ljava/lang/String;IIIJJ)I");
1090d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    if (method_beginSendObject == NULL) {
1091d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        LOGE("Can't find beginSendObject");
1092d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        return -1;
1093d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    }
1094413577d8600413bb1dca3730d4ccf20892b929b4Mike Lockwood    method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIJZ)V");
1095d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    if (method_endSendObject == NULL) {
1096d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        LOGE("Can't find endSendObject");
1097d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1098d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
1099d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    method_getObjectList = env->GetMethodID(clazz, "getObjectList", "(III)[I");
1100d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_getObjectList == NULL) {
1101d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        LOGE("Can't find getObjectList");
1102d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1103d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
11047a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    method_getNumObjects = env->GetMethodID(clazz, "getNumObjects", "(III)I");
11057a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    if (method_getNumObjects == NULL) {
11067a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        LOGE("Can't find getNumObjects");
11077a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        return -1;
11087a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    }
11094b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedPlaybackFormats = env->GetMethodID(clazz, "getSupportedPlaybackFormats", "()[I");
11104b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedPlaybackFormats == NULL) {
11114b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        LOGE("Can't find getSupportedPlaybackFormats");
11124b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
11134b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
11144b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedCaptureFormats = env->GetMethodID(clazz, "getSupportedCaptureFormats", "()[I");
11154b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedCaptureFormats == NULL) {
11164b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        LOGE("Can't find getSupportedCaptureFormats");
11174b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
11184b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
11194b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedObjectProperties = env->GetMethodID(clazz, "getSupportedObjectProperties", "(I)[I");
11204b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedObjectProperties == NULL) {
11214b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        LOGE("Can't find getSupportedObjectProperties");
11224b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
11234b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
11244b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedDeviceProperties = env->GetMethodID(clazz, "getSupportedDeviceProperties", "()[I");
11254b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedDeviceProperties == NULL) {
11264b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        LOGE("Can't find getSupportedDeviceProperties");
11274b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
11284b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
112959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    method_setObjectProperty = env->GetMethodID(clazz, "setObjectProperty", "(IIJLjava/lang/String;)I");
113059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (method_setObjectProperty == NULL) {
113159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        LOGE("Can't find setObjectProperty");
113259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return -1;
113359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
113459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    method_getDeviceProperty = env->GetMethodID(clazz, "getDeviceProperty", "(I[J[C)I");
113559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (method_getDeviceProperty == NULL) {
113659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        LOGE("Can't find getDeviceProperty");
113759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return -1;
113859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
113959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    method_setDeviceProperty = env->GetMethodID(clazz, "setDeviceProperty", "(IJLjava/lang/String;)I");
114059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (method_setDeviceProperty == NULL) {
114159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        LOGE("Can't find setDeviceProperty");
114259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return -1;
114359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
1144e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    method_getObjectPropertyList = env->GetMethodID(clazz, "getObjectPropertyList",
11457d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            "(JIJII)Landroid/media/MtpPropertyList;");
1146e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (method_getObjectPropertyList == NULL) {
1147e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        LOGE("Can't find getObjectPropertyList");
1148e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1149e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1150d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z");
1151d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_getObjectInfo == NULL) {
1152d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        LOGE("Can't find getObjectInfo");
1153d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1154d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
115559c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    method_getObjectFilePath = env->GetMethodID(clazz, "getObjectFilePath", "(I[C[J)I");
1156d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_getObjectFilePath == NULL) {
1157d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        LOGE("Can't find getObjectFilePath");
1158d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1159d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
116059c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    method_deleteFile = env->GetMethodID(clazz, "deleteFile", "(I)I");
1161d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_deleteFile == NULL) {
1162d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        LOGE("Can't find deleteFile");
1163d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1164d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
11659a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    method_getObjectReferences = env->GetMethodID(clazz, "getObjectReferences", "(I)[I");
11669a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (method_getObjectReferences == NULL) {
11679a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        LOGE("Can't find getObjectReferences");
11689a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return -1;
11699a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    }
11709a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    method_setObjectReferences = env->GetMethodID(clazz, "setObjectReferences", "(I[I)I");
11719a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (method_setObjectReferences == NULL) {
11729a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        LOGE("Can't find setObjectReferences");
11739a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return -1;
11749a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    }
11752837eefc5459427138c080d445bb491c75630163Mike Lockwood    method_sessionStarted = env->GetMethodID(clazz, "sessionStarted", "()V");
11762837eefc5459427138c080d445bb491c75630163Mike Lockwood    if (method_sessionStarted == NULL) {
11772837eefc5459427138c080d445bb491c75630163Mike Lockwood        LOGE("Can't find sessionStarted");
11782837eefc5459427138c080d445bb491c75630163Mike Lockwood        return -1;
11792837eefc5459427138c080d445bb491c75630163Mike Lockwood    }
11802837eefc5459427138c080d445bb491c75630163Mike Lockwood    method_sessionEnded = env->GetMethodID(clazz, "sessionEnded", "()V");
11812837eefc5459427138c080d445bb491c75630163Mike Lockwood    if (method_sessionEnded == NULL) {
11822837eefc5459427138c080d445bb491c75630163Mike Lockwood        LOGE("Can't find sessionEnded");
11832837eefc5459427138c080d445bb491c75630163Mike Lockwood        return -1;
11842837eefc5459427138c080d445bb491c75630163Mike Lockwood    }
11852837eefc5459427138c080d445bb491c75630163Mike Lockwood
1186d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    field_context = env->GetFieldID(clazz, "mNativeContext", "I");
1187d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (field_context == NULL) {
1188d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        LOGE("Can't find MtpDatabase.mNativeContext");
1189d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1190d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
1191d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1192e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    // now set up fields for MtpPropertyList class
1193e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    clazz = env->FindClass("android/media/MtpPropertyList");
1194e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (clazz == NULL) {
1195e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        LOGE("Can't find android/media/MtpPropertyList");
1196e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1197e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1198e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mCount = env->GetFieldID(clazz, "mCount", "I");
1199e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mCount == NULL) {
1200e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        LOGE("Can't find MtpPropertyList.mCount");
1201e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1202e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1203e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mResult = env->GetFieldID(clazz, "mResult", "I");
1204e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mResult == NULL) {
1205e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        LOGE("Can't find MtpPropertyList.mResult");
1206e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1207e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1208e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mObjectHandles = env->GetFieldID(clazz, "mObjectHandles", "[I");
1209e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mObjectHandles == NULL) {
1210e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        LOGE("Can't find MtpPropertyList.mObjectHandles");
1211e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1212e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1213e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mPropertyCodes = env->GetFieldID(clazz, "mPropertyCodes", "[I");
1214e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mPropertyCodes == NULL) {
1215e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        LOGE("Can't find MtpPropertyList.mPropertyCodes");
1216e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1217e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1218e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mDataTypes = env->GetFieldID(clazz, "mDataTypes", "[I");
1219e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mDataTypes == NULL) {
1220e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        LOGE("Can't find MtpPropertyList.mDataTypes");
1221e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1222e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1223e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mLongValues = env->GetFieldID(clazz, "mLongValues", "[J");
1224e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mLongValues == NULL) {
1225e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        LOGE("Can't find MtpPropertyList.mLongValues");
1226e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1227e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1228e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mStringValues = env->GetFieldID(clazz, "mStringValues", "[Ljava/lang/String;");
1229e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mStringValues == NULL) {
1230e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        LOGE("Can't find MtpPropertyList.mStringValues");
1231e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1232e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1233e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
12347d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    if (AndroidRuntime::registerNativeMethods(env,
12357d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                "android/media/MtpDatabase", gMtpDatabaseMethods, NELEM(gMtpDatabaseMethods)))
12367d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        return -1;
12377d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
1238d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return AndroidRuntime::registerNativeMethods(env,
12397d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                "android/media/MtpPropertyGroup", gMtpPropertyGroupMethods, NELEM(gMtpPropertyGroupMethods));
1240d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
1241