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"
2987eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include "android_runtime/Log.h"
30d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
31d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "MtpDatabase.h"
32d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "MtpDataPacket.h"
339df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood#include "MtpObjectInfo.h"
34828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood#include "MtpProperty.h"
3559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood#include "MtpStringBuffer.h"
36d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "MtpUtils.h"
37d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "mtp.h"
38d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
39c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwoodextern "C" {
40c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood#include "jhead.h"
41c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood}
42c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
43d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodusing namespace android;
44d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
45d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
46d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
47d815f79766984fce499e147ecbacc01914683f74Mike Lockwoodstatic jmethodID method_beginSendObject;
48d815f79766984fce499e147ecbacc01914683f74Mike Lockwoodstatic jmethodID method_endSendObject;
49d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_getObjectList;
507a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwoodstatic jmethodID method_getNumObjects;
514b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedPlaybackFormats;
524b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedCaptureFormats;
534b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedObjectProperties;
544b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedDeviceProperties;
55828d19dd96b05fa99abdc517701e5366543c324fMike Lockwoodstatic jmethodID method_setObjectProperty;
5659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic jmethodID method_getDeviceProperty;
5759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic jmethodID method_setDeviceProperty;
58e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jmethodID method_getObjectPropertyList;
59d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_getObjectInfo;
60d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_getObjectFilePath;
61d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_deleteFile;
629a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodstatic jmethodID method_getObjectReferences;
639a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodstatic jmethodID method_setObjectReferences;
642837eefc5459427138c080d445bb491c75630163Mike Lockwoodstatic jmethodID method_sessionStarted;
652837eefc5459427138c080d445bb491c75630163Mike Lockwoodstatic jmethodID method_sessionEnded;
662837eefc5459427138c080d445bb491c75630163Mike Lockwood
67d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jfieldID field_context;
68d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
69e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood// MtpPropertyList fields
70e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mCount;
71e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mResult;
72e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mObjectHandles;
73e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mPropertyCodes;
74e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mDataTypes;
75e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mLongValues;
76e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mStringValues;
77e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
78e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
79d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) {
80d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return (MtpDatabase *)env->GetIntField(database, field_context);
81d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
82d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
83d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
84d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
85d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodclass MyMtpDatabase : public MtpDatabase {
86d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodprivate:
87d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jobject         mDatabase;
88d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jintArray       mIntBuffer;
89d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jlongArray      mLongBuffer;
90d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jcharArray      mStringBuffer;
91d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
92d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodpublic:
93d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MyMtpDatabase(JNIEnv *env, jobject client);
94d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    virtual                         ~MyMtpDatabase();
95d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    void                            cleanup(JNIEnv *env);
96d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
97d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    virtual MtpObjectHandle         beginSendObject(const char* path,
98d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectFormat format,
99d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectHandle parent,
100d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpStorageID storage,
101d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            uint64_t size,
102d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            time_t modified);
103d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
104d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    virtual void                    endSendObject(const char* path,
105d815f79766984fce499e147ecbacc01914683f74Mike Lockwood                                            MtpObjectHandle handle,
106d815f79766984fce499e147ecbacc01914683f74Mike Lockwood                                            MtpObjectFormat format,
107d815f79766984fce499e147ecbacc01914683f74Mike Lockwood                                            bool succeeded);
108d815f79766984fce499e147ecbacc01914683f74Mike Lockwood
109d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    virtual MtpObjectHandleList*    getObjectList(MtpStorageID storageID,
110d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectFormat format,
111d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectHandle parent);
112d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1137a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    virtual int                     getNumObjects(MtpStorageID storageID,
1147a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                            MtpObjectFormat format,
1157a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                            MtpObjectHandle parent);
1167a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood
1174b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    // callee should delete[] the results from these
1184b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    // results can be NULL
1194b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpObjectFormatList*    getSupportedPlaybackFormats();
1204b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpObjectFormatList*    getSupportedCaptureFormats();
1214b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpObjectPropertyList*  getSupportedObjectProperties(MtpObjectFormat format);
1224b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpDevicePropertyList*  getSupportedDeviceProperties();
1234b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
124828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         getObjectPropertyValue(MtpObjectHandle handle,
125d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectProperty property,
126d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpDataPacket& packet);
127d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
128828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         setObjectPropertyValue(MtpObjectHandle handle,
129828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectProperty property,
130828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet);
131828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
132828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         getDevicePropertyValue(MtpDeviceProperty property,
133828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet);
134828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
135828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         setDevicePropertyValue(MtpDeviceProperty property,
136828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet);
137828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
138828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         resetDeviceProperty(MtpDeviceProperty property);
139828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
140e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    virtual MtpResponseCode         getObjectPropertyList(MtpObjectHandle handle,
1417d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                            uint32_t format, uint32_t property,
142e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            int groupCode, int depth,
143e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            MtpDataPacket& packet);
144e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
145d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    virtual MtpResponseCode         getObjectInfo(MtpObjectHandle handle,
1469df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood                                            MtpObjectInfo& info);
147d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
148c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    virtual void*                   getThumbnail(MtpObjectHandle handle, size_t& outThumbSize);
149c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
15059c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    virtual MtpResponseCode         getObjectFilePath(MtpObjectHandle handle,
151365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            MtpString& outFilePath,
152365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            int64_t& outFileLength,
153365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            MtpObjectFormat& outFormat);
15459c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    virtual MtpResponseCode         deleteFile(MtpObjectHandle handle);
155d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
15659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    bool                            getObjectPropertyInfo(MtpObjectProperty property, int& type);
15759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    bool                            getDevicePropertyInfo(MtpDeviceProperty property, int& type);
1589a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
1599a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    virtual MtpObjectHandleList*    getObjectReferences(MtpObjectHandle handle);
1609a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
1619a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    virtual MtpResponseCode         setObjectReferences(MtpObjectHandle handle,
1629a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                                            MtpObjectHandleList* references);
163828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
164828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpProperty*            getObjectPropertyDesc(MtpObjectProperty property,
165828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectFormat format);
166828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
167828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpProperty*            getDevicePropertyDesc(MtpDeviceProperty property);
1682837eefc5459427138c080d445bb491c75630163Mike Lockwood
1692837eefc5459427138c080d445bb491c75630163Mike Lockwood    virtual void                    sessionStarted();
1702837eefc5459427138c080d445bb491c75630163Mike Lockwood
1712837eefc5459427138c080d445bb491c75630163Mike Lockwood    virtual void                    sessionEnded();
172d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
173d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1740a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood// ----------------------------------------------------------------------------
1750a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
1760a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwoodstatic void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
1770a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    if (env->ExceptionCheck()) {
1783762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("An exception was thrown by callback '%s'.", methodName);
1790a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood        LOGE_EX(env);
1800a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood        env->ExceptionClear();
1810a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    }
1820a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood}
1830a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
1840a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood// ----------------------------------------------------------------------------
1850a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
186d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMyMtpDatabase::MyMtpDatabase(JNIEnv *env, jobject client)
187d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    :   mDatabase(env->NewGlobalRef(client)),
188d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mIntBuffer(NULL),
189d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mLongBuffer(NULL),
190d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mStringBuffer(NULL)
191d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
192d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    // create buffers for out arguments
193d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    // we don't need to be thread-safe so this is OK
19415dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    jintArray intArray = env->NewIntArray(3);
19515dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    if (!intArray) {
19615dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes        return; // Already threw.
19715dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    }
198d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    mIntBuffer = (jintArray)env->NewGlobalRef(intArray);
19915dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    jlongArray longArray = env->NewLongArray(2);
20015dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    if (!longArray) {
20115dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes        return; // Already threw.
20215dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    }
203d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    mLongBuffer = (jlongArray)env->NewGlobalRef(longArray);
20415dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    jcharArray charArray = env->NewCharArray(256);
20515dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    if (!charArray) {
20615dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes        return; // Already threw.
20715dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    }
208d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    mStringBuffer = (jcharArray)env->NewGlobalRef(charArray);
209d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
210d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
211d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodvoid MyMtpDatabase::cleanup(JNIEnv *env) {
212d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mDatabase);
213d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mIntBuffer);
214d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mLongBuffer);
215d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mStringBuffer);
216d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
217d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
218d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMyMtpDatabase::~MyMtpDatabase() {
219d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
220d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
221d815f79766984fce499e147ecbacc01914683f74Mike LockwoodMtpObjectHandle MyMtpDatabase::beginSendObject(const char* path,
222d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectFormat format,
223d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectHandle parent,
224d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpStorageID storage,
225d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            uint64_t size,
226d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            time_t modified) {
227d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2288839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    jstring pathStr = env->NewStringUTF(path);
2290a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    MtpObjectHandle result = env->CallIntMethod(mDatabase, method_beginSendObject,
2308839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood            pathStr, (jint)format, (jint)parent, (jint)storage,
2310a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood            (jlong)size, (jlong)modified);
2320a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2338839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (pathStr)
2348839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(pathStr);
2350a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
2360a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
237d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
238d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
239d815f79766984fce499e147ecbacc01914683f74Mike Lockwoodvoid MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
2407a0bd17bceaf3efc3732e30c538fae420d3b742cMike Lockwood                                MtpObjectFormat format, bool succeeded) {
241d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2428839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    jstring pathStr = env->NewStringUTF(path);
2438839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->CallVoidMethod(mDatabase, method_endSendObject, pathStr,
2447a0bd17bceaf3efc3732e30c538fae420d3b742cMike Lockwood                        (jint)handle, (jint)format, (jboolean)succeeded);
2450a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2468839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (pathStr)
2478839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(pathStr);
2480a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
249d815f79766984fce499e147ecbacc01914683f74Mike Lockwood}
250d815f79766984fce499e147ecbacc01914683f74Mike Lockwood
251d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMtpObjectHandleList* MyMtpDatabase::getObjectList(MtpStorageID storageID,
252d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectFormat format,
253d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectHandle parent) {
254d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
255d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectList,
256d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                (jint)storageID, (jint)format, (jint)parent);
257d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (!array)
258d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return NULL;
259d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MtpObjectHandleList* list = new MtpObjectHandleList();
260d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jint* handles = env->GetIntArrayElements(array, 0);
261d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jsize length = env->GetArrayLength(array);
2627a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    for (int i = 0; i < length; i++)
263d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        list->push(handles[i]);
2640a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, handles, 0);
2658839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
2660a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2670a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
2680a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
269d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
270d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
2717a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwoodint MyMtpDatabase::getNumObjects(MtpStorageID storageID,
2727a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                MtpObjectFormat format,
2737a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                MtpObjectHandle parent) {
2747a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2750a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    int result = env->CallIntMethod(mDatabase, method_getNumObjects,
2767a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                (jint)storageID, (jint)format, (jint)parent);
2770a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2780a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
2790a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
2807a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood}
2817a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood
2824b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpObjectFormatList* MyMtpDatabase::getSupportedPlaybackFormats() {
2834b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2844b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
2854b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedPlaybackFormats);
2864b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
2874b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
2884b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpObjectFormatList* list = new MtpObjectFormatList();
2894b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* formats = env->GetIntArrayElements(array, 0);
2904b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
2914b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
2924b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(formats[i]);
2930a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, formats, 0);
2948839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
2950a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2960a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
2970a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
2984b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
2994b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
3004b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpObjectFormatList* MyMtpDatabase::getSupportedCaptureFormats() {
3014b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
3024b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
3034b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedCaptureFormats);
3044b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
3054b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
3064b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpObjectFormatList* list = new MtpObjectFormatList();
3074b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* formats = env->GetIntArrayElements(array, 0);
3084b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
3094b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
3104b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(formats[i]);
3110a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, formats, 0);
3128839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
3130a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
3140a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
3150a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
3164b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
3174b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
3184b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpObjectPropertyList* MyMtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) {
3194b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
3204b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
3214b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedObjectProperties, (jint)format);
3224b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
3234b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
3244b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpObjectPropertyList* list = new MtpObjectPropertyList();
3254b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* properties = env->GetIntArrayElements(array, 0);
3264b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
3274b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
3284b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(properties[i]);
3290a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, properties, 0);
3308839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
3310a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
3320a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
3330a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
3344b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
3354b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
3364b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
3374b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
3384b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
3394b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedDeviceProperties);
3404b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
3414b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
3424b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpDevicePropertyList* list = new MtpDevicePropertyList();
3434b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* properties = env->GetIntArrayElements(array, 0);
3444b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
3454b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
3464b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(properties[i]);
3470a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, properties, 0);
3488839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
3490a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
3500a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
3510a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
3524b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
3534b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
354828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
355d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectProperty property,
356d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpDataPacket& packet) {
357d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
358e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
3597d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                (jlong)handle, 0, (jlong)property, 0, 0);
360e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    MtpResponseCode result = env->GetIntField(list, field_mResult);
361e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    int count = env->GetIntField(list, field_mCount);
362e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (result == MTP_RESPONSE_OK && count != 1)
363e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        result = MTP_RESPONSE_GENERAL_ERROR;
364e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
365e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (result == MTP_RESPONSE_OK) {
366e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
367e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
368e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
369e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
370e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
371e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
372e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
373e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
374e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
375e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
376e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
377e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        int type = dataTypes[0];
378e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlong longValue = (longValues ? longValues[0] : 0);
379e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
380e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        // special case date properties, which are strings to MTP
381e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        // but stored internally as a uint64
382e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (property == MTP_PROPERTY_DATE_MODIFIED || property == MTP_PROPERTY_DATE_ADDED) {
383e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            char    date[20];
384e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            formatDateTime(longValue, date, sizeof(date));
385e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putString(date);
386e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            goto out;
387e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
388e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        // release date is stored internally as just the year
389e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) {
390e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            char    date[20];
391e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            snprintf(date, sizeof(date), "%04lld0101T000000", longValue);
392e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putString(date);
393e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            goto out;
394e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
395828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
396e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        switch (type) {
397e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT8:
398e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt8(longValue);
399e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
400e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT8:
401e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt8(longValue);
402e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
403e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT16:
404e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt16(longValue);
405e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
406e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT16:
407e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt16(longValue);
408e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
409e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT32:
410e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt32(longValue);
411e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
412e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT32:
413e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt32(longValue);
414e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
415e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT64:
416e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt64(longValue);
417e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
418e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT64:
419e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt64(longValue);
420e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
421e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT128:
422e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt128(longValue);
423e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
424e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT128:
425e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt128(longValue);
426e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
427e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_STR:
428e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            {
429e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                jstring stringValue = (jstring)env->GetObjectArrayElement(stringValuesArray, 0);
430e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                if (stringValue) {
431e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    const char* str = env->GetStringUTFChars(stringValue, NULL);
4323977472d9f3380a8323156dbc7d0090cf2f2d310James Dong                    if (str == NULL) {
4333977472d9f3380a8323156dbc7d0090cf2f2d310James Dong                        return MTP_RESPONSE_GENERAL_ERROR;
4343977472d9f3380a8323156dbc7d0090cf2f2d310James Dong                    }
435e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putString(str);
436e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    env->ReleaseStringUTFChars(stringValue, str);
437e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                } else {
438e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putEmptyString();
439e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                }
440e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
441e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood             }
442e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            default:
4433762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("unsupported type in getObjectPropertyValue\n");
444e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
445e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
446e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodout:
447e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
448e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
449e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
450e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValues)
451e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
452e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
453e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(objectHandlesArray);
454e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(propertyCodesArray);
455e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(dataTypesArray);
456e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValuesArray)
457e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(longValuesArray);
458e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (stringValuesArray)
459e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(stringValuesArray);
460d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
4610a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
462e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    env->DeleteLocalRef(list);
4630a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
464e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    return result;
465d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
466d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
467828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
468828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectProperty property,
469828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet) {
47059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int         type;
47159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
47259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (!getObjectPropertyInfo(property, type))
47359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
47459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
47559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
47659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jlong longValue = 0;
47759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jstring stringValue = NULL;
47859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
47959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    switch (type) {
48059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT8:
48159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt8();
48259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
48359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT8:
48459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt8();
48559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
48659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT16:
48759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt16();
48859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
48959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT16:
49059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt16();
49159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
49259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT32:
49359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt32();
49459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
49559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT32:
49659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt32();
49759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
49859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT64:
49959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt64();
50059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
50159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT64:
50259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt64();
50359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
50459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_STR:
50559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        {
50659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            MtpStringBuffer buffer;
50759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.getString(buffer);
50859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            stringValue = env->NewStringUTF((const char *)buffer);
50959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
51059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood         }
51159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        default:
5123762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("unsupported type in getObjectPropertyValue\n");
51359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
51459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
51559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
51659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jint result = env->CallIntMethod(mDatabase, method_setObjectProperty,
51759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood                (jint)handle, (jint)property, longValue, stringValue);
5188839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (stringValue)
5198839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(stringValue);
52059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
52159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
52259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return result;
523828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
524828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
525828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
526828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet) {
52759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int         type;
52859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
52959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (!getDevicePropertyInfo(property, type))
53059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
53159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
53259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
53359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
53459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood                (jint)property, mLongBuffer, mStringBuffer);
53559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (result != MTP_RESPONSE_OK) {
53659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        checkAndClearExceptionFromCallback(env, __FUNCTION__);
53759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return result;
53859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
53959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
54059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
54159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jlong longValue = longValues[0];
54259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
54359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
54459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    switch (type) {
54559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT8:
54659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt8(longValue);
54759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
54859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT8:
54959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putUInt8(longValue);
55059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
55159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT16:
55259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt16(longValue);
55359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
55459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT16:
55559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putUInt16(longValue);
55659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
55759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT32:
55859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt32(longValue);
55959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
56059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT32:
56159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putUInt32(longValue);
56259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
56359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT64:
56459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt64(longValue);
56559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
56659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT64:
56759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putUInt64(longValue);
56859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
56959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT128:
57059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt128(longValue);
57159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
57259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT128:
57359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putInt128(longValue);
57459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
57559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_STR:
57659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        {
57759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
57859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.putString(str);
57959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            env->ReleaseCharArrayElements(mStringBuffer, str, 0);
58059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
58159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood         }
58259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        default:
5833762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("unsupported type in getDevicePropertyValue\n");
58459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
58559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
58659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
58759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
58859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return MTP_RESPONSE_OK;
589828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
590828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
591828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
592828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet) {
59359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int         type;
59459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
59559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (!getDevicePropertyInfo(property, type))
59659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
59759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
59859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
59959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jlong longValue = 0;
60059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jstring stringValue = NULL;
60159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
60259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    switch (type) {
60359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT8:
60459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt8();
60559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
60659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT8:
60759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt8();
60859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
60959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT16:
61059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt16();
61159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
61259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT16:
61359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt16();
61459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
61559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT32:
61659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt32();
61759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
61859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT32:
61959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt32();
62059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
62159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_INT64:
62259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getInt64();
62359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
62459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_UINT64:
62559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            longValue = packet.getUInt64();
62659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
62759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_TYPE_STR:
62859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        {
62959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            MtpStringBuffer buffer;
63059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            packet.getString(buffer);
63159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            stringValue = env->NewStringUTF((const char *)buffer);
63259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
63359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood         }
63459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        default:
6353762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("unsupported type in setDevicePropertyValue\n");
63659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
63759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
63859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
63959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jint result = env->CallIntMethod(mDatabase, method_setDeviceProperty,
64059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood                (jint)property, longValue, stringValue);
6418839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (stringValue)
6428839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(stringValue);
64359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
64459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
64559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return result;
646828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
647828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
648828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty property) {
649828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    return -1;
650828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
651828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
652e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike LockwoodMtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
6537d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                            uint32_t format, uint32_t property,
654e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            int groupCode, int depth,
655e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            MtpDataPacket& packet) {
656e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
657e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
6587d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                (jlong)handle, (jint)format, (jlong)property, (jint)groupCode, (jint)depth);
6597d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
6607d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    if (!list)
6617d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        return MTP_RESPONSE_GENERAL_ERROR;
662e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    int count = env->GetIntField(list, field_mCount);
663e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    MtpResponseCode result = env->GetIntField(list, field_mResult);
664e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
665e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    packet.putUInt32(count);
666e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (count > 0) {
667e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
668e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
669e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
670e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
671e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
672e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
673e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
674e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
675e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
676e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
677e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
678e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        for (int i = 0; i < count; i++) {
679e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putUInt32(objectHandles[i]);
680e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putUInt16(propertyCodes[i]);
681e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            int type = dataTypes[i];
682e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putUInt16(type);
683e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
684e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            switch (type) {
685e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT8:
686e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt8(longValues[i]);
687e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
688e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT8:
689e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt8(longValues[i]);
690e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
691e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT16:
692e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt16(longValues[i]);
693e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
694e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT16:
695e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt16(longValues[i]);
696e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
697e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT32:
698e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt32(longValues[i]);
699e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
700e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT32:
701e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt32(longValues[i]);
702e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
703e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT64:
704e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt64(longValues[i]);
705e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
706e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT64:
707e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt64(longValues[i]);
708e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
709e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT128:
710e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt128(longValues[i]);
711e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
712e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT128:
713e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt128(longValues[i]);
714e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
715e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_STR: {
716e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    jstring value = (jstring)env->GetObjectArrayElement(stringValuesArray, i);
7172711e494caf9ec665c46258feb36c9654290f6e0Mike Lockwood                    const char *valueStr = (value ? env->GetStringUTFChars(value, NULL) : NULL);
718e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    if (valueStr) {
719e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                        packet.putString(valueStr);
720e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                        env->ReleaseStringUTFChars(value, valueStr);
721e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    } else {
722e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                        packet.putEmptyString();
723e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    }
724e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    env->DeleteLocalRef(value);
725e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
726e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                }
727e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                default:
7283762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                    ALOGE("bad or unsupported data type in MyMtpDatabase::getObjectPropertyList");
729e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
730e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            }
731e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
732e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
733e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
734e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
735e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
736e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValues)
737e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
738e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
739e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(objectHandlesArray);
740e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(propertyCodesArray);
741e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(dataTypesArray);
742e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValuesArray)
743e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(longValuesArray);
744e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (stringValuesArray)
745e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(stringValuesArray);
746e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
747e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
748e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    env->DeleteLocalRef(list);
749e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
750e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    return result;
751e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood}
752e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
753d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
7549df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood                                            MtpObjectInfo& info) {
755f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    char            date[20];
756f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    MtpString       path;
757f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    int64_t         length;
758f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    MtpObjectFormat format;
759f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood
760f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    MtpResponseCode result = getObjectFilePath(handle, path, length, format);
761f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    if (result != MTP_RESPONSE_OK) {
762f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood        return result;
763f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    }
764f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    info.mCompressedSize = (length > 0xFFFFFFFFLL ? 0xFFFFFFFF : (uint32_t)length);
765d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
766d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
767f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    if (!env->CallBooleanMethod(mDatabase, method_getObjectInfo,
768f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood                (jint)handle, mIntBuffer, mStringBuffer, mLongBuffer)) {
769d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
770f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    }
771d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
772d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jint* intValues = env->GetIntArrayElements(mIntBuffer, 0);
7739df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood    info.mStorageID = intValues[0];
7749df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood    info.mFormat = intValues[1];
7759df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood    info.mParent = intValues[2];
776d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseIntArrayElements(mIntBuffer, intValues, 0);
777d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
778d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
7791341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood    info.mDateCreated = longValues[0];
7801341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood    info.mDateModified = longValues[1];
781d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
782d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
7839df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood//    info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ?
784828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood//                            MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
785828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood//                            MTP_ASSOCIATION_TYPE_UNDEFINED);
7869df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood    info.mAssociationType = MTP_ASSOCIATION_TYPE_UNDEFINED;
787d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
788d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
7899df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood    MtpString temp(str);
7909df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood    info.mName = strdup((const char *)temp);
791d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseCharArrayElements(mStringBuffer, str, 0);
792d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
793c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    // read EXIF data for thumbnail information
794c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    if (info.mFormat == MTP_FORMAT_EXIF_JPEG || info.mFormat == MTP_FORMAT_JFIF) {
795f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood        ResetJpgfile();
796f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood         // Start with an empty image information structure.
797f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood        memset(&ImageInfo, 0, sizeof(ImageInfo));
798f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood        ImageInfo.FlashUsed = -1;
799f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood        ImageInfo.MeteringMode = -1;
800f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood        ImageInfo.Whitebalance = -1;
801f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood        strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
802f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood        if (ReadJpegFile((const char*)path, READ_METADATA)) {
803f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood            Section_t* section = FindSection(M_EXIF);
804f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood            if (section) {
805f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood                info.mThumbCompressedSize = ImageInfo.ThumbnailSize;
806f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood                info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
807f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood                info.mImagePixWidth = ImageInfo.Width;
808f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood                info.mImagePixHeight = ImageInfo.Height;
809c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood            }
810c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood        }
811f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood        DiscardData();
812c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    }
813c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
8140a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
815d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return MTP_RESPONSE_OK;
816d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
817d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
818c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwoodvoid* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) {
819c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    MtpString path;
820c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    int64_t length;
821c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    MtpObjectFormat format;
822c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    void* result = NULL;
823c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    outThumbSize = 0;
824c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
825c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK
826c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood            && (format == MTP_FORMAT_EXIF_JPEG || format == MTP_FORMAT_JFIF)) {
827c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood        ResetJpgfile();
828c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood         // Start with an empty image information structure.
829c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood        memset(&ImageInfo, 0, sizeof(ImageInfo));
830c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood        ImageInfo.FlashUsed = -1;
831c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood        ImageInfo.MeteringMode = -1;
832c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood        ImageInfo.Whitebalance = -1;
833c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood        strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
834c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood        if (ReadJpegFile((const char*)path, READ_METADATA)) {
835c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood            Section_t* section = FindSection(M_EXIF);
836c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood            if (section) {
837c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood                outThumbSize = ImageInfo.ThumbnailSize;
838c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood                result = malloc(outThumbSize);
839c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood                if (result)
840c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood                    memcpy(result, section->Data + ImageInfo.ThumbnailOffset + 8, outThumbSize);
841c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood            }
842c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood            DiscardData();
843c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood        }
844c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    }
845c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
846c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    return result;
847c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood}
848c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
84959c777a24a2c639dfd84b7bf17e430e6d3424866Mike LockwoodMtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle,
850365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            MtpString& outFilePath,
851365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            int64_t& outFileLength,
852365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            MtpObjectFormat& outFormat) {
853d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
85459c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath,
855d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                (jint)handle, mStringBuffer, mLongBuffer);
85659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (result != MTP_RESPONSE_OK) {
85759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        checkAndClearExceptionFromCallback(env, __FUNCTION__);
85859c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood        return result;
85959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
860d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
861d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
862365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood    outFilePath.setTo(str, strlen16(str));
863d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseCharArrayElements(mStringBuffer, str, 0);
864d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
865d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
866365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood    outFileLength = longValues[0];
867365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood    outFormat = longValues[1];
868d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
86915dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes
8700a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
87159c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    return result;
872d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
873d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
87459c777a24a2c639dfd84b7bf17e430e6d3424866Mike LockwoodMtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) {
875d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
8760a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    MtpResponseCode result = env->CallIntMethod(mDatabase, method_deleteFile, (jint)handle);
8770a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
8780a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
8790a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
880d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
881d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
882d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstruct PropertyTableEntry {
883d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MtpObjectProperty   property;
884d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    int                 type;
885d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
886d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
88759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic const PropertyTableEntry   kObjectPropertyTable[] = {
888d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_STORAGE_ID,        MTP_TYPE_UINT32     },
889d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_OBJECT_FORMAT,     MTP_TYPE_UINT16     },
890d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16     },
891d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_OBJECT_SIZE,       MTP_TYPE_UINT64     },
892d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_OBJECT_FILE_NAME,  MTP_TYPE_STR        },
893d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_DATE_MODIFIED,     MTP_TYPE_STR        },
894d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_PARENT_OBJECT,     MTP_TYPE_UINT32     },
895d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_PERSISTENT_UID,    MTP_TYPE_UINT128    },
896d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_NAME,              MTP_TYPE_STR        },
897ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DISPLAY_NAME,      MTP_TYPE_STR        },
898ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DATE_ADDED,        MTP_TYPE_STR        },
899ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ARTIST,            MTP_TYPE_STR        },
900ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ALBUM_NAME,        MTP_TYPE_STR        },
901ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ALBUM_ARTIST,      MTP_TYPE_STR        },
902ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_TRACK,             MTP_TYPE_UINT16     },
903ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_TYPE_STR    },
904ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_GENRE,             MTP_TYPE_STR        },
905ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_COMPOSER,          MTP_TYPE_STR        },
906ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DURATION,          MTP_TYPE_UINT32     },
907ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DESCRIPTION,       MTP_TYPE_STR        },
908d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
909d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
91059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic const PropertyTableEntry   kDevicePropertyTable[] = {
911ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    {   MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,    MTP_TYPE_STR },
912ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    {   MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,       MTP_TYPE_STR },
913ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    {   MTP_DEVICE_PROPERTY_IMAGE_SIZE,                 MTP_TYPE_STR },
91459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood};
91559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
91659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodbool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
91759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
91859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    const PropertyTableEntry* entry = kObjectPropertyTable;
91959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    for (int i = 0; i < count; i++, entry++) {
92059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        if (entry->property == property) {
92159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            type = entry->type;
92259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            return true;
92359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        }
92459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
92559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return false;
92659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood}
92759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
92859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodbool MyMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) {
92959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int count = sizeof(kDevicePropertyTable) / sizeof(kDevicePropertyTable[0]);
93059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    const PropertyTableEntry* entry = kDevicePropertyTable;
931d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    for (int i = 0; i < count; i++, entry++) {
932d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        if (entry->property == property) {
933d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            type = entry->type;
934d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            return true;
935d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        }
936d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
937d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return false;
938d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
939d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
9409a2046fb5ceeee4d5334274cbff15f1058bb3244Mike LockwoodMtpObjectHandleList* MyMtpDatabase::getObjectReferences(MtpObjectHandle handle) {
9419a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
9429a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectReferences,
9439a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                (jint)handle);
9449a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (!array)
9459a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return NULL;
9469a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    MtpObjectHandleList* list = new MtpObjectHandleList();
9479a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jint* handles = env->GetIntArrayElements(array, 0);
9489a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jsize length = env->GetArrayLength(array);
9499a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    for (int i = 0; i < length; i++)
9509a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        list->push(handles[i]);
9510a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, handles, 0);
9528839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
9530a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
9540a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
9550a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
9569a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood}
9579a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
9580a7fa0a868ccce920827e141cbbe237594e53364Mike LockwoodMtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle,
9590a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood                                                    MtpObjectHandleList* references) {
9609a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
9619a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    int count = references->size();
9629a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jintArray array = env->NewIntArray(count);
9639a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (!array) {
9643762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("out of memory in setObjectReferences");
9659a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return false;
9669a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    }
9679a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jint* handles = env->GetIntArrayElements(array, 0);
9689a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood     for (int i = 0; i < count; i++)
9699a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        handles[i] = (*references)[i];
9709a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    env->ReleaseIntArrayElements(array, handles, 0);
9710a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    MtpResponseCode result = env->CallIntMethod(mDatabase, method_setObjectReferences,
9729a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                (jint)handle, array);
9738839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
9749a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
9750a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
9760a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
977d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
978d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
979828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
980828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectFormat format) {
981828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    MtpProperty* result = NULL;
982828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    switch (property) {
983828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_OBJECT_FORMAT:
9849b5e9c407d35eab4f37c208d81bdf0b8bcdbdf93Mike Lockwood            // use format as default value
9859b5e9c407d35eab4f37c208d81bdf0b8bcdbdf93Mike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT16, false, format);
9869b5e9c407d35eab4f37c208d81bdf0b8bcdbdf93Mike Lockwood            break;
987828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_PROTECTION_STATUS:
988ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_TRACK:
989828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT16);
990828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
991828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_STORAGE_ID:
992828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_PARENT_OBJECT:
993ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_DURATION:
994828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT32);
995828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
996828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_OBJECT_SIZE:
997828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT64);
998828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
999828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_PERSISTENT_UID:
1000828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT128);
1001828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
1002d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood        case MTP_PROPERTY_NAME:
1003ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_DISPLAY_NAME:
1004ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_ARTIST:
1005ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_ALBUM_NAME:
1006ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_ALBUM_ARTIST:
1007ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_GENRE:
1008ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_COMPOSER:
1009ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_DESCRIPTION:
1010828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR);
1011828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
10125b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood        case MTP_PROPERTY_DATE_MODIFIED:
10135b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood        case MTP_PROPERTY_DATE_ADDED:
10145b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood        case MTP_PROPERTY_ORIGINAL_RELEASE_DATE:
10155b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR);
10165b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood            result->setFormDateTime();
10175b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood            break;
10185ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood        case MTP_PROPERTY_OBJECT_FILE_NAME:
10196a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood            // We allow renaming files and folders
10206a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR, true);
10215ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood            break;
1022828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    }
1023828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
1024828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    return result;
1025828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
1026828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
1027828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
1028ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
102959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    MtpProperty* result = NULL;
1030ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    bool writable = false;
1031ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood
103259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    switch (property) {
103359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
103459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
1035ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            writable = true;
1036ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            // fall through
1037ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood        case MTP_DEVICE_PROPERTY_IMAGE_SIZE:
1038ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR, writable);
1039a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood
1040ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            // get current value
1041a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            jint ret = env->CallIntMethod(mDatabase, method_getDeviceProperty,
1042a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                        (jint)property, mLongBuffer, mStringBuffer);
1043a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            if (ret == MTP_RESPONSE_OK) {
1044a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
1045a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                result->setCurrentValue(str);
1046ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood                // for read-only properties it is safe to assume current value is default value
1047ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood                if (!writable)
1048ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood                    result->setDefaultValue(str);
1049a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                env->ReleaseCharArrayElements(mStringBuffer, str, 0);
1050a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            } else {
10513762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("unable to read device property, response: %04X", ret);
1052a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            }
105359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
105459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
105559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
1056ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
105759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return result;
1058828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
1059828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
10602837eefc5459427138c080d445bb491c75630163Mike Lockwoodvoid MyMtpDatabase::sessionStarted() {
10612837eefc5459427138c080d445bb491c75630163Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
10622837eefc5459427138c080d445bb491c75630163Mike Lockwood    env->CallVoidMethod(mDatabase, method_sessionStarted);
10632837eefc5459427138c080d445bb491c75630163Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
10642837eefc5459427138c080d445bb491c75630163Mike Lockwood}
10652837eefc5459427138c080d445bb491c75630163Mike Lockwood
10662837eefc5459427138c080d445bb491c75630163Mike Lockwoodvoid MyMtpDatabase::sessionEnded() {
10672837eefc5459427138c080d445bb491c75630163Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
10682837eefc5459427138c080d445bb491c75630163Mike Lockwood    env->CallVoidMethod(mDatabase, method_sessionEnded);
10692837eefc5459427138c080d445bb491c75630163Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
10702837eefc5459427138c080d445bb491c75630163Mike Lockwood}
10712837eefc5459427138c080d445bb491c75630163Mike Lockwood
1072d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
1073d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1074d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic void
10750cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodandroid_mtp_MtpDatabase_setup(JNIEnv *env, jobject thiz)
1076d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
1077d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MyMtpDatabase* database = new MyMtpDatabase(env, thiz);
1078d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->SetIntField(thiz, field_context, (int)database);
1079d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
1080d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
1081d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1082d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic void
10830cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodandroid_mtp_MtpDatabase_finalize(JNIEnv *env, jobject thiz)
1084d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
1085d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MyMtpDatabase* database = (MyMtpDatabase *)env->GetIntField(thiz, field_context);
1086d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    database->cleanup(env);
1087d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    delete database;
1088d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->SetIntField(thiz, field_context, 0);
1089d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
1090d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
1091d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
10923159991e586f9e243f60d65a9554828328b00521Mike Lockwoodstatic jstring
10930cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodandroid_mtp_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject thiz, jlong seconds)
10943159991e586f9e243f60d65a9554828328b00521Mike Lockwood{
10953159991e586f9e243f60d65a9554828328b00521Mike Lockwood    char    date[20];
10963159991e586f9e243f60d65a9554828328b00521Mike Lockwood    formatDateTime(seconds, date, sizeof(date));
10973159991e586f9e243f60d65a9554828328b00521Mike Lockwood    return env->NewStringUTF(date);
10983159991e586f9e243f60d65a9554828328b00521Mike Lockwood}
10993159991e586f9e243f60d65a9554828328b00521Mike Lockwood
1100d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
1101d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
11027d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodstatic JNINativeMethod gMtpDatabaseMethods[] = {
11030cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood    {"native_setup",            "()V",  (void *)android_mtp_MtpDatabase_setup},
11040cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood    {"native_finalize",         "()V",  (void *)android_mtp_MtpDatabase_finalize},
11057d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood};
11067d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
11077d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodstatic JNINativeMethod gMtpPropertyGroupMethods[] = {
11083159991e586f9e243f60d65a9554828328b00521Mike Lockwood    {"format_date_time",        "(J)Ljava/lang/String;",
11090cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood                                        (void *)android_mtp_MtpPropertyGroup_format_date_time},
1110d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
1111d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
11120cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodstatic const char* const kClassPathName = "android/mtp/MtpDatabase";
1113d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
11140cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodint register_android_mtp_MtpDatabase(JNIEnv *env)
1115d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
1116d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jclass clazz;
1117d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
11180cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood    clazz = env->FindClass("android/mtp/MtpDatabase");
1119d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (clazz == NULL) {
11203762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpDatabase");
1121d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1122d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
1123d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    method_beginSendObject = env->GetMethodID(clazz, "beginSendObject", "(Ljava/lang/String;IIIJJ)I");
1124d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    if (method_beginSendObject == NULL) {
11253762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find beginSendObject");
1126d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        return -1;
1127d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    }
11287a0bd17bceaf3efc3732e30c538fae420d3b742cMike Lockwood    method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIZ)V");
1129d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    if (method_endSendObject == NULL) {
11303762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find endSendObject");
1131d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1132d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
1133d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    method_getObjectList = env->GetMethodID(clazz, "getObjectList", "(III)[I");
1134d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_getObjectList == NULL) {
11353762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getObjectList");
1136d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1137d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
11387a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    method_getNumObjects = env->GetMethodID(clazz, "getNumObjects", "(III)I");
11397a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    if (method_getNumObjects == NULL) {
11403762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getNumObjects");
11417a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        return -1;
11427a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    }
11434b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedPlaybackFormats = env->GetMethodID(clazz, "getSupportedPlaybackFormats", "()[I");
11444b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedPlaybackFormats == NULL) {
11453762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getSupportedPlaybackFormats");
11464b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
11474b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
11484b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedCaptureFormats = env->GetMethodID(clazz, "getSupportedCaptureFormats", "()[I");
11494b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedCaptureFormats == NULL) {
11503762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getSupportedCaptureFormats");
11514b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
11524b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
11534b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedObjectProperties = env->GetMethodID(clazz, "getSupportedObjectProperties", "(I)[I");
11544b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedObjectProperties == NULL) {
11553762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getSupportedObjectProperties");
11564b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
11574b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
11584b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedDeviceProperties = env->GetMethodID(clazz, "getSupportedDeviceProperties", "()[I");
11594b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedDeviceProperties == NULL) {
11603762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getSupportedDeviceProperties");
11614b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
11624b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
116359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    method_setObjectProperty = env->GetMethodID(clazz, "setObjectProperty", "(IIJLjava/lang/String;)I");
116459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (method_setObjectProperty == NULL) {
11653762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find setObjectProperty");
116659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return -1;
116759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
116859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    method_getDeviceProperty = env->GetMethodID(clazz, "getDeviceProperty", "(I[J[C)I");
116959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (method_getDeviceProperty == NULL) {
11703762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getDeviceProperty");
117159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return -1;
117259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
117359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    method_setDeviceProperty = env->GetMethodID(clazz, "setDeviceProperty", "(IJLjava/lang/String;)I");
117459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (method_setDeviceProperty == NULL) {
11753762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find setDeviceProperty");
117659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return -1;
117759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
1178e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    method_getObjectPropertyList = env->GetMethodID(clazz, "getObjectPropertyList",
11790cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood            "(JIJII)Landroid/mtp/MtpPropertyList;");
1180e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (method_getObjectPropertyList == NULL) {
11813762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getObjectPropertyList");
1182e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1183e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1184d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z");
1185d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_getObjectInfo == NULL) {
11863762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getObjectInfo");
1187d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1188d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
118959c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    method_getObjectFilePath = env->GetMethodID(clazz, "getObjectFilePath", "(I[C[J)I");
1190d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_getObjectFilePath == NULL) {
11913762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getObjectFilePath");
1192d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1193d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
119459c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    method_deleteFile = env->GetMethodID(clazz, "deleteFile", "(I)I");
1195d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_deleteFile == NULL) {
11963762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find deleteFile");
1197d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1198d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
11999a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    method_getObjectReferences = env->GetMethodID(clazz, "getObjectReferences", "(I)[I");
12009a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (method_getObjectReferences == NULL) {
12013762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getObjectReferences");
12029a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return -1;
12039a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    }
12049a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    method_setObjectReferences = env->GetMethodID(clazz, "setObjectReferences", "(I[I)I");
12059a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (method_setObjectReferences == NULL) {
12063762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find setObjectReferences");
12079a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return -1;
12089a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    }
12092837eefc5459427138c080d445bb491c75630163Mike Lockwood    method_sessionStarted = env->GetMethodID(clazz, "sessionStarted", "()V");
12102837eefc5459427138c080d445bb491c75630163Mike Lockwood    if (method_sessionStarted == NULL) {
12113762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find sessionStarted");
12122837eefc5459427138c080d445bb491c75630163Mike Lockwood        return -1;
12132837eefc5459427138c080d445bb491c75630163Mike Lockwood    }
12142837eefc5459427138c080d445bb491c75630163Mike Lockwood    method_sessionEnded = env->GetMethodID(clazz, "sessionEnded", "()V");
12152837eefc5459427138c080d445bb491c75630163Mike Lockwood    if (method_sessionEnded == NULL) {
12163762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find sessionEnded");
12172837eefc5459427138c080d445bb491c75630163Mike Lockwood        return -1;
12182837eefc5459427138c080d445bb491c75630163Mike Lockwood    }
12192837eefc5459427138c080d445bb491c75630163Mike Lockwood
1220d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    field_context = env->GetFieldID(clazz, "mNativeContext", "I");
1221d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (field_context == NULL) {
12223762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpDatabase.mNativeContext");
1223d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1224d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
1225d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1226e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    // now set up fields for MtpPropertyList class
12270cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood    clazz = env->FindClass("android/mtp/MtpPropertyList");
1228e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (clazz == NULL) {
12293762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpPropertyList");
1230e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1231e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1232e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mCount = env->GetFieldID(clazz, "mCount", "I");
1233e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mCount == NULL) {
12343762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mCount");
1235e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1236e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1237e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mResult = env->GetFieldID(clazz, "mResult", "I");
1238e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mResult == NULL) {
12393762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mResult");
1240e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1241e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1242e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mObjectHandles = env->GetFieldID(clazz, "mObjectHandles", "[I");
1243e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mObjectHandles == NULL) {
12443762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mObjectHandles");
1245e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1246e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1247e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mPropertyCodes = env->GetFieldID(clazz, "mPropertyCodes", "[I");
1248e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mPropertyCodes == NULL) {
12493762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mPropertyCodes");
1250e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1251e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1252e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mDataTypes = env->GetFieldID(clazz, "mDataTypes", "[I");
1253e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mDataTypes == NULL) {
12543762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mDataTypes");
1255e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1256e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1257e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mLongValues = env->GetFieldID(clazz, "mLongValues", "[J");
1258e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mLongValues == NULL) {
12593762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mLongValues");
1260e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1261e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1262e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mStringValues = env->GetFieldID(clazz, "mStringValues", "[Ljava/lang/String;");
1263e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mStringValues == NULL) {
12643762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mStringValues");
1265e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1266e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1267e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
12687d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    if (AndroidRuntime::registerNativeMethods(env,
12690cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood                "android/mtp/MtpDatabase", gMtpDatabaseMethods, NELEM(gMtpDatabaseMethods)))
12707d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        return -1;
12717d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
1272d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return AndroidRuntime::registerNativeMethods(env,
12730cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood                "android/mtp/MtpPropertyGroup", gMtpPropertyGroupMethods, NELEM(gMtpPropertyGroupMethods));
1274d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
1275