android_mtp_MtpDatabase.cpp revision 8409c0691fb128fef6244305977342776bddf919
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
208409c0691fb128fef6244305977342776bddf919Jaesung Chung#include "android_media_Utils.h"
218409c0691fb128fef6244305977342776bddf919Jaesung Chung#include "mtp.h"
22d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "MtpDatabase.h"
23d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "MtpDataPacket.h"
249df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood#include "MtpObjectInfo.h"
25828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood#include "MtpProperty.h"
2659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood#include "MtpStringBuffer.h"
27d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood#include "MtpUtils.h"
288409c0691fb128fef6244305977342776bddf919Jaesung Chung
298409c0691fb128fef6244305977342776bddf919Jaesung Chung#include "src/piex_types.h"
308409c0691fb128fef6244305977342776bddf919Jaesung Chung#include "src/piex.h"
31d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
32c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwoodextern "C" {
333cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen#include "libexif/exif-content.h"
343cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen#include "libexif/exif-data.h"
353cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen#include "libexif/exif-tag.h"
363cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen#include "libexif/exif-utils.h"
37c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood}
38c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
398409c0691fb128fef6244305977342776bddf919Jaesung Chung#include <android_runtime/AndroidRuntime.h>
408409c0691fb128fef6244305977342776bddf919Jaesung Chung#include <android_runtime/Log.h>
418409c0691fb128fef6244305977342776bddf919Jaesung Chung#include <jni.h>
428409c0691fb128fef6244305977342776bddf919Jaesung Chung#include <JNIHelp.h>
438409c0691fb128fef6244305977342776bddf919Jaesung Chung#include <nativehelper/ScopedLocalRef.h>
448409c0691fb128fef6244305977342776bddf919Jaesung Chung
458409c0691fb128fef6244305977342776bddf919Jaesung Chung#include <assert.h>
468409c0691fb128fef6244305977342776bddf919Jaesung Chung#include <fcntl.h>
478409c0691fb128fef6244305977342776bddf919Jaesung Chung#include <inttypes.h>
488409c0691fb128fef6244305977342776bddf919Jaesung Chung#include <limits.h>
498409c0691fb128fef6244305977342776bddf919Jaesung Chung#include <stdio.h>
508409c0691fb128fef6244305977342776bddf919Jaesung Chung#include <unistd.h>
518409c0691fb128fef6244305977342776bddf919Jaesung Chung
52d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodusing namespace android;
53d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
54d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
55d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
56d815f79766984fce499e147ecbacc01914683f74Mike Lockwoodstatic jmethodID method_beginSendObject;
57d815f79766984fce499e147ecbacc01914683f74Mike Lockwoodstatic jmethodID method_endSendObject;
58d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_getObjectList;
597a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwoodstatic jmethodID method_getNumObjects;
604b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedPlaybackFormats;
614b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedCaptureFormats;
624b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedObjectProperties;
634b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwoodstatic jmethodID method_getSupportedDeviceProperties;
64828d19dd96b05fa99abdc517701e5366543c324fMike Lockwoodstatic jmethodID method_setObjectProperty;
6559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic jmethodID method_getDeviceProperty;
6659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic jmethodID method_setDeviceProperty;
67e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jmethodID method_getObjectPropertyList;
68d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_getObjectInfo;
69d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_getObjectFilePath;
70d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jmethodID method_deleteFile;
719a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodstatic jmethodID method_getObjectReferences;
729a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodstatic jmethodID method_setObjectReferences;
732837eefc5459427138c080d445bb491c75630163Mike Lockwoodstatic jmethodID method_sessionStarted;
742837eefc5459427138c080d445bb491c75630163Mike Lockwoodstatic jmethodID method_sessionEnded;
752837eefc5459427138c080d445bb491c75630163Mike Lockwood
76d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic jfieldID field_context;
7756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwoodstatic jfieldID field_batteryLevel;
7856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwoodstatic jfieldID field_batteryScale;
79d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
80e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood// MtpPropertyList fields
81e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mCount;
82e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mResult;
83e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mObjectHandles;
84e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mPropertyCodes;
85e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mDataTypes;
86e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mLongValues;
87e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodstatic jfieldID field_mStringValues;
88e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
89e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
90d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) {
91e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    return (MtpDatabase *)env->GetLongField(database, field_context);
92d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
93d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
94d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
95d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
96d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodclass MyMtpDatabase : public MtpDatabase {
97d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodprivate:
98d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jobject         mDatabase;
99d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jintArray       mIntBuffer;
100d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jlongArray      mLongBuffer;
101d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jcharArray      mStringBuffer;
102d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
103d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodpublic:
104d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MyMtpDatabase(JNIEnv *env, jobject client);
105d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    virtual                         ~MyMtpDatabase();
106d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    void                            cleanup(JNIEnv *env);
107d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
108d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    virtual MtpObjectHandle         beginSendObject(const char* path,
109d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectFormat format,
110d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectHandle parent,
111d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpStorageID storage,
112d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            uint64_t size,
113d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            time_t modified);
114d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
115d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    virtual void                    endSendObject(const char* path,
116d815f79766984fce499e147ecbacc01914683f74Mike Lockwood                                            MtpObjectHandle handle,
117d815f79766984fce499e147ecbacc01914683f74Mike Lockwood                                            MtpObjectFormat format,
118d815f79766984fce499e147ecbacc01914683f74Mike Lockwood                                            bool succeeded);
119d815f79766984fce499e147ecbacc01914683f74Mike Lockwood
120d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    virtual MtpObjectHandleList*    getObjectList(MtpStorageID storageID,
121d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectFormat format,
122d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectHandle parent);
123d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1247a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    virtual int                     getNumObjects(MtpStorageID storageID,
1257a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                            MtpObjectFormat format,
1267a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                            MtpObjectHandle parent);
1277a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood
1284b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    // callee should delete[] the results from these
1294b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    // results can be NULL
1304b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpObjectFormatList*    getSupportedPlaybackFormats();
1314b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpObjectFormatList*    getSupportedCaptureFormats();
1324b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpObjectPropertyList*  getSupportedObjectProperties(MtpObjectFormat format);
1334b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    virtual MtpDevicePropertyList*  getSupportedDeviceProperties();
1344b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
135828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         getObjectPropertyValue(MtpObjectHandle handle,
136d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectProperty property,
137d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpDataPacket& packet);
138d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
139828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         setObjectPropertyValue(MtpObjectHandle handle,
140828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectProperty property,
141828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet);
142828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
143828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         getDevicePropertyValue(MtpDeviceProperty property,
144828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet);
145828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
146828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         setDevicePropertyValue(MtpDeviceProperty property,
147828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet);
148828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
149828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpResponseCode         resetDeviceProperty(MtpDeviceProperty property);
150828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
151e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    virtual MtpResponseCode         getObjectPropertyList(MtpObjectHandle handle,
1527d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                            uint32_t format, uint32_t property,
153e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            int groupCode, int depth,
154e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            MtpDataPacket& packet);
155e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
156d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    virtual MtpResponseCode         getObjectInfo(MtpObjectHandle handle,
1579df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood                                            MtpObjectInfo& info);
158d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
159c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    virtual void*                   getThumbnail(MtpObjectHandle handle, size_t& outThumbSize);
160c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
16159c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    virtual MtpResponseCode         getObjectFilePath(MtpObjectHandle handle,
162365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            MtpString& outFilePath,
163365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            int64_t& outFileLength,
164365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            MtpObjectFormat& outFormat);
16559c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    virtual MtpResponseCode         deleteFile(MtpObjectHandle handle);
166d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
16759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    bool                            getObjectPropertyInfo(MtpObjectProperty property, int& type);
16859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    bool                            getDevicePropertyInfo(MtpDeviceProperty property, int& type);
1699a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
1709a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    virtual MtpObjectHandleList*    getObjectReferences(MtpObjectHandle handle);
1719a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
1729a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    virtual MtpResponseCode         setObjectReferences(MtpObjectHandle handle,
1739a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                                            MtpObjectHandleList* references);
174828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
175828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpProperty*            getObjectPropertyDesc(MtpObjectProperty property,
176828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectFormat format);
177828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
178828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    virtual MtpProperty*            getDevicePropertyDesc(MtpDeviceProperty property);
1792837eefc5459427138c080d445bb491c75630163Mike Lockwood
1802837eefc5459427138c080d445bb491c75630163Mike Lockwood    virtual void                    sessionStarted();
1812837eefc5459427138c080d445bb491c75630163Mike Lockwood
1822837eefc5459427138c080d445bb491c75630163Mike Lockwood    virtual void                    sessionEnded();
183d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
184d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1850a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood// ----------------------------------------------------------------------------
1860a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
1870a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwoodstatic void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
1880a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    if (env->ExceptionCheck()) {
1893762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("An exception was thrown by callback '%s'.", methodName);
1900a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood        LOGE_EX(env);
1910a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood        env->ExceptionClear();
1920a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    }
1930a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood}
1940a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
1950a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood// ----------------------------------------------------------------------------
1960a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
197d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMyMtpDatabase::MyMtpDatabase(JNIEnv *env, jobject client)
198d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    :   mDatabase(env->NewGlobalRef(client)),
199d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mIntBuffer(NULL),
200d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mLongBuffer(NULL),
201d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mStringBuffer(NULL)
202d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
203d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    // create buffers for out arguments
204d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    // we don't need to be thread-safe so this is OK
20515dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    jintArray intArray = env->NewIntArray(3);
20615dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    if (!intArray) {
20715dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes        return; // Already threw.
20815dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    }
209d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    mIntBuffer = (jintArray)env->NewGlobalRef(intArray);
21015dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    jlongArray longArray = env->NewLongArray(2);
21115dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    if (!longArray) {
21215dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes        return; // Already threw.
21315dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    }
214d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    mLongBuffer = (jlongArray)env->NewGlobalRef(longArray);
21563ffd78aaab0b0d04012312f0378b0c73b737a2aMike Lockwood    // Needs to be long enough to hold a file path for getObjectFilePath()
21663ffd78aaab0b0d04012312f0378b0c73b737a2aMike Lockwood    jcharArray charArray = env->NewCharArray(PATH_MAX + 1);
21715dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    if (!charArray) {
21815dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes        return; // Already threw.
21915dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes    }
220d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    mStringBuffer = (jcharArray)env->NewGlobalRef(charArray);
221d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
222d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
223d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodvoid MyMtpDatabase::cleanup(JNIEnv *env) {
224d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mDatabase);
225d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mIntBuffer);
226d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mLongBuffer);
227d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->DeleteGlobalRef(mStringBuffer);
228d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
229d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
230d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMyMtpDatabase::~MyMtpDatabase() {
231d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
232d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
233d815f79766984fce499e147ecbacc01914683f74Mike LockwoodMtpObjectHandle MyMtpDatabase::beginSendObject(const char* path,
234d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectFormat format,
235d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectHandle parent,
236d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpStorageID storage,
237d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            uint64_t size,
238d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            time_t modified) {
239d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2408839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    jstring pathStr = env->NewStringUTF(path);
2410a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    MtpObjectHandle result = env->CallIntMethod(mDatabase, method_beginSendObject,
2428839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood            pathStr, (jint)format, (jint)parent, (jint)storage,
2430a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood            (jlong)size, (jlong)modified);
2440a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2458839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (pathStr)
2468839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(pathStr);
2470a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
2480a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
249d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
250d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
251d815f79766984fce499e147ecbacc01914683f74Mike Lockwoodvoid MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
2527a0bd17bceaf3efc3732e30c538fae420d3b742cMike Lockwood                                MtpObjectFormat format, bool succeeded) {
253d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2548839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    jstring pathStr = env->NewStringUTF(path);
2558839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->CallVoidMethod(mDatabase, method_endSendObject, pathStr,
2567a0bd17bceaf3efc3732e30c538fae420d3b742cMike Lockwood                        (jint)handle, (jint)format, (jboolean)succeeded);
2570a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2588839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (pathStr)
2598839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(pathStr);
2600a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
261d815f79766984fce499e147ecbacc01914683f74Mike Lockwood}
262d815f79766984fce499e147ecbacc01914683f74Mike Lockwood
263d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMtpObjectHandleList* MyMtpDatabase::getObjectList(MtpStorageID storageID,
264d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectFormat format,
265d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                    MtpObjectHandle parent) {
266d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
267d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectList,
268d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                (jint)storageID, (jint)format, (jint)parent);
269d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (!array)
270d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return NULL;
271d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MtpObjectHandleList* list = new MtpObjectHandleList();
272d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jint* handles = env->GetIntArrayElements(array, 0);
273d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jsize length = env->GetArrayLength(array);
2747a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    for (int i = 0; i < length; i++)
275d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        list->push(handles[i]);
2760a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, handles, 0);
2778839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
2780a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2790a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
2800a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
281d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
282d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
2837a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwoodint MyMtpDatabase::getNumObjects(MtpStorageID storageID,
2847a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                MtpObjectFormat format,
2857a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                                MtpObjectHandle parent) {
2867a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2870a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    int result = env->CallIntMethod(mDatabase, method_getNumObjects,
2887a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                (jint)storageID, (jint)format, (jint)parent);
2890a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
2900a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
2910a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
2927a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood}
2937a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood
2944b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpObjectFormatList* MyMtpDatabase::getSupportedPlaybackFormats() {
2954b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
2964b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
2974b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedPlaybackFormats);
2984b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
2994b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
3004b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpObjectFormatList* list = new MtpObjectFormatList();
3014b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* formats = env->GetIntArrayElements(array, 0);
3024b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
3034b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
3044b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(formats[i]);
3050a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, formats, 0);
3068839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
3070a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
3080a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
3090a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
3104b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
3114b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
3124b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpObjectFormatList* MyMtpDatabase::getSupportedCaptureFormats() {
3134b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
3144b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
3154b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedCaptureFormats);
3164b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
3174b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
3184b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpObjectFormatList* list = new MtpObjectFormatList();
3194b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* formats = env->GetIntArrayElements(array, 0);
3204b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
3214b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
3224b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(formats[i]);
3230a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, formats, 0);
3248839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
3250a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
3260a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
3270a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
3284b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
3294b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
3304b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpObjectPropertyList* MyMtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) {
3314b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
3324b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
3334b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedObjectProperties, (jint)format);
3344b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
3354b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
3364b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpObjectPropertyList* list = new MtpObjectPropertyList();
3374b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* properties = env->GetIntArrayElements(array, 0);
3384b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
3394b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
3404b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(properties[i]);
3410a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, properties, 0);
3428839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
3430a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
3440a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
3450a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
3464b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
3474b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
3484b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike LockwoodMtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
3494b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
3504b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase,
3514b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood            method_getSupportedDeviceProperties);
3524b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (!array)
3534b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return NULL;
3544b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    MtpDevicePropertyList* list = new MtpDevicePropertyList();
3554b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jint* properties = env->GetIntArrayElements(array, 0);
3564b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    jsize length = env->GetArrayLength(array);
3574b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    for (int i = 0; i < length; i++)
3584b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        list->push(properties[i]);
3590a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, properties, 0);
3608839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
3610a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
3620a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
3630a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
3644b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood}
3654b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood
366828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
367d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpObjectProperty property,
368d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            MtpDataPacket& packet) {
369d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
370e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
3717d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                (jlong)handle, 0, (jlong)property, 0, 0);
372e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    MtpResponseCode result = env->GetIntField(list, field_mResult);
373e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    int count = env->GetIntField(list, field_mCount);
374e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (result == MTP_RESPONSE_OK && count != 1)
375e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        result = MTP_RESPONSE_GENERAL_ERROR;
376e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
377e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (result == MTP_RESPONSE_OK) {
378e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
379e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
380e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
381e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
382e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
383e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
384e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
385e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
386e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
387e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
388e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
389e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        int type = dataTypes[0];
390e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlong longValue = (longValues ? longValues[0] : 0);
391e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
392e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        // special case date properties, which are strings to MTP
393e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        // but stored internally as a uint64
394e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (property == MTP_PROPERTY_DATE_MODIFIED || property == MTP_PROPERTY_DATE_ADDED) {
395e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            char    date[20];
396e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            formatDateTime(longValue, date, sizeof(date));
397e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putString(date);
398e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            goto out;
399e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
400e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        // release date is stored internally as just the year
401e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) {
402e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            char    date[20];
403aeb75fc5a3dc51bf9d5220647a68c48644c66ea8Mark Salyzyn            snprintf(date, sizeof(date), "%04" PRId64 "0101T000000", longValue);
404e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putString(date);
405e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            goto out;
406e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
407828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
408e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        switch (type) {
409e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT8:
410e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt8(longValue);
411e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
412e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT8:
413e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt8(longValue);
414e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
415e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT16:
416e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt16(longValue);
417e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
418e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT16:
419e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt16(longValue);
420e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
421e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT32:
422e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt32(longValue);
423e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
424e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT32:
425e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt32(longValue);
426e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
427e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT64:
428e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt64(longValue);
429e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
430e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT64:
431e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putUInt64(longValue);
432e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
433e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_INT128:
434e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt128(longValue);
435e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
436e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_UINT128:
437e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                packet.putInt128(longValue);
438e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
439e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            case MTP_TYPE_STR:
440e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            {
441e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                jstring stringValue = (jstring)env->GetObjectArrayElement(stringValuesArray, 0);
44217a24c58bb2e86719f003c80f682beb66803f24dMartin Blumenstingl                const char* str = (stringValue ? env->GetStringUTFChars(stringValue, NULL) : NULL);
443e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                if (stringValue) {
444e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putString(str);
445e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    env->ReleaseStringUTFChars(stringValue, str);
446e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                } else {
447e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putEmptyString();
448e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                }
44917a24c58bb2e86719f003c80f682beb66803f24dMartin Blumenstingl                env->DeleteLocalRef(stringValue);
450e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                break;
451e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood             }
452e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            default:
4533762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("unsupported type in getObjectPropertyValue\n");
454e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
455e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
456e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwoodout:
457e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
458e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
459e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
460e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValues)
461e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
462e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
463e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(objectHandlesArray);
464e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(propertyCodesArray);
465e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(dataTypesArray);
466e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValuesArray)
467e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(longValuesArray);
468e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (stringValuesArray)
469e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(stringValuesArray);
470d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
4710a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
472e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    env->DeleteLocalRef(list);
4730a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
474e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    return result;
475d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
476d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
4779c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwoodstatic bool readLongValue(int type, MtpDataPacket& packet, jlong& longValue) {
4789c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood    switch (type) {
4799c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        case MTP_TYPE_INT8: {
4809c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            int8_t temp;
4819c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            if (!packet.getInt8(temp)) return false;
4829c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            longValue = temp;
4839c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            break;
4849c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        }
4859c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        case MTP_TYPE_UINT8: {
4869c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            uint8_t temp;
4879c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            if (!packet.getUInt8(temp)) return false;
4889c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            longValue = temp;
4899c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            break;
4909c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        }
4919c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        case MTP_TYPE_INT16: {
4929c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            int16_t temp;
4939c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            if (!packet.getInt16(temp)) return false;
4949c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            longValue = temp;
4959c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            break;
4969c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        }
4979c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        case MTP_TYPE_UINT16: {
4989c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            uint16_t temp;
4999c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            if (!packet.getUInt16(temp)) return false;
5009c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            longValue = temp;
5019c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            break;
5029c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        }
5039c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        case MTP_TYPE_INT32: {
5049c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            int32_t temp;
5059c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            if (!packet.getInt32(temp)) return false;
5069c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            longValue = temp;
5079c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            break;
5089c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        }
5099c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        case MTP_TYPE_UINT32: {
5109c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            uint32_t temp;
5119c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            if (!packet.getUInt32(temp)) return false;
5129c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            longValue = temp;
5139c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            break;
5149c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        }
5159c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        case MTP_TYPE_INT64: {
5169c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            int64_t temp;
5179c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            if (!packet.getInt64(temp)) return false;
5189c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            longValue = temp;
5199c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            break;
5209c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        }
5219c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        case MTP_TYPE_UINT64: {
5229c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            uint64_t temp;
5239c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            if (!packet.getUInt64(temp)) return false;
5249c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            longValue = temp;
5259c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            break;
5269c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        }
5279c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        default:
5289c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            ALOGE("unsupported type in readLongValue");
5299c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood            return false;
5309c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood    }
5319c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood    return true;
5329c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood}
5339c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood
534828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
535828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectProperty property,
536828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet) {
53759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int         type;
53859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
53959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (!getObjectPropertyInfo(property, type))
54059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
54159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
54259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
54359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jlong longValue = 0;
54459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jstring stringValue = NULL;
5459c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood    MtpResponseCode result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
54659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
5479c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood    if (type == MTP_TYPE_STR) {
5489c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        MtpStringBuffer buffer;
5499c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        if (!packet.getString(buffer)) goto fail;
5509c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        stringValue = env->NewStringUTF((const char *)buffer);
5519c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood    } else {
5529c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        if (!readLongValue(type, packet, longValue)) goto fail;
55359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
55459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
5559c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood    result = env->CallIntMethod(mDatabase, method_setObjectProperty,
55659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood                (jint)handle, (jint)property, longValue, stringValue);
5578839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (stringValue)
5588839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(stringValue);
55959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
5609c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwoodfail:
56159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
56259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return result;
563828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
564828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
565828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
566828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet) {
56756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
56859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
56956c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood    if (property == MTP_DEVICE_PROPERTY_BATTERY_LEVEL) {
57056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        // special case - implemented here instead of Java
57156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        packet.putUInt8((uint8_t)env->GetIntField(mDatabase, field_batteryLevel));
57256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        return MTP_RESPONSE_OK;
57356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood    } else {
57456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        int type;
57556c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood
57656c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        if (!getDevicePropertyInfo(property, type))
57756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
57856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood
57956c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
58056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                    (jint)property, mLongBuffer, mStringBuffer);
58156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        if (result != MTP_RESPONSE_OK) {
58256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            checkAndClearExceptionFromCallback(env, __FUNCTION__);
58356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            return result;
58456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        }
58559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
58656c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
58756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        jlong longValue = longValues[0];
58856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
58959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
59056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        switch (type) {
59156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            case MTP_TYPE_INT8:
59256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                packet.putInt8(longValue);
59356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                break;
59456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            case MTP_TYPE_UINT8:
59556c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                packet.putUInt8(longValue);
59656c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                break;
59756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            case MTP_TYPE_INT16:
59856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                packet.putInt16(longValue);
59956c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                break;
60056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            case MTP_TYPE_UINT16:
60156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                packet.putUInt16(longValue);
60256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                break;
60356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            case MTP_TYPE_INT32:
60456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                packet.putInt32(longValue);
60556c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                break;
60656c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            case MTP_TYPE_UINT32:
60756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                packet.putUInt32(longValue);
60856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                break;
60956c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            case MTP_TYPE_INT64:
61056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                packet.putInt64(longValue);
61156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                break;
61256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            case MTP_TYPE_UINT64:
61356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                packet.putUInt64(longValue);
61456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                break;
61556c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            case MTP_TYPE_INT128:
61656c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                packet.putInt128(longValue);
61756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                break;
61856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            case MTP_TYPE_UINT128:
61956c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                packet.putInt128(longValue);
62056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                break;
62156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            case MTP_TYPE_STR:
62256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            {
62356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
62456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                packet.putString(str);
62556c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                env->ReleaseCharArrayElements(mStringBuffer, str, 0);
62656c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                break;
62756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood             }
62856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            default:
62956c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                ALOGE("unsupported type in getDevicePropertyValue\n");
63056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood                return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
63156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        }
63259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
63356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        checkAndClearExceptionFromCallback(env, __FUNCTION__);
63456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        return MTP_RESPONSE_OK;
63559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
636828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
637828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
638828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
639828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpDataPacket& packet) {
64059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int         type;
64159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
64259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (!getDevicePropertyInfo(property, type))
64359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
64459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
64559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
64659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jlong longValue = 0;
64759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    jstring stringValue = NULL;
6489c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood    MtpResponseCode result = MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
64959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
6509c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood    if (type == MTP_TYPE_STR) {
6519c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        MtpStringBuffer buffer;
6529c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        if (!packet.getString(buffer)) goto fail;
6539c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        stringValue = env->NewStringUTF((const char *)buffer);
6549c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood    } else {
6559c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood        if (!readLongValue(type, packet, longValue)) goto fail;
65659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
65759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
6589c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwood    result = env->CallIntMethod(mDatabase, method_setDeviceProperty,
65959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood                (jint)property, longValue, stringValue);
6608839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    if (stringValue)
6618839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood        env->DeleteLocalRef(stringValue);
66259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
6639c803fa52606aeb27d4d098161722fb111dd1b23Mike Lockwoodfail:
66459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
66559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return result;
666828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
667828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
668aeb75fc5a3dc51bf9d5220647a68c48644c66ea8Mark SalyzynMtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty /*property*/) {
669828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    return -1;
670828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
671828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
672e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike LockwoodMtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
6737d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                            uint32_t format, uint32_t property,
674e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            int groupCode, int depth,
675e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                                            MtpDataPacket& packet) {
676e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
677e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
6787d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                (jlong)handle, (jint)format, (jlong)property, (jint)groupCode, (jint)depth);
6797d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
6807d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    if (!list)
6817d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        return MTP_RESPONSE_GENERAL_ERROR;
682e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    int count = env->GetIntField(list, field_mCount);
683e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    MtpResponseCode result = env->GetIntField(list, field_mResult);
684e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
685e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    packet.putUInt32(count);
686e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (count > 0) {
687e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
688e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
689e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
690e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
691e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);
692e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
693e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
694e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
695e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
696e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);
697e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
698e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        for (int i = 0; i < count; i++) {
699e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putUInt32(objectHandles[i]);
700e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putUInt16(propertyCodes[i]);
701e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            int type = dataTypes[i];
702e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            packet.putUInt16(type);
703e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
704e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            switch (type) {
705e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT8:
706e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt8(longValues[i]);
707e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
708e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT8:
709e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt8(longValues[i]);
710e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
711e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT16:
712e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt16(longValues[i]);
713e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
714e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT16:
715e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt16(longValues[i]);
716e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
717e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT32:
718e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt32(longValues[i]);
719e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
720e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT32:
721e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt32(longValues[i]);
722e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
723e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT64:
724e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt64(longValues[i]);
725e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
726e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT64:
727e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt64(longValues[i]);
728e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
729e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_INT128:
730e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putInt128(longValues[i]);
731e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
732e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_UINT128:
733e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    packet.putUInt128(longValues[i]);
734e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
735e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                case MTP_TYPE_STR: {
736e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    jstring value = (jstring)env->GetObjectArrayElement(stringValuesArray, i);
7372711e494caf9ec665c46258feb36c9654290f6e0Mike Lockwood                    const char *valueStr = (value ? env->GetStringUTFChars(value, NULL) : NULL);
738e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    if (valueStr) {
739e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                        packet.putString(valueStr);
740e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                        env->ReleaseStringUTFChars(value, valueStr);
741e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    } else {
742e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                        packet.putEmptyString();
743e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    }
744e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    env->DeleteLocalRef(value);
745e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
746e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                }
747e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                default:
7483762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                    ALOGE("bad or unsupported data type in MyMtpDatabase::getObjectPropertyList");
749e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood                    break;
750e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            }
751e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        }
752e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
753e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
754e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
755e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
756e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValues)
757e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->ReleaseLongArrayElements(longValuesArray, longValues, 0);
758e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
759e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(objectHandlesArray);
760e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(propertyCodesArray);
761e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        env->DeleteLocalRef(dataTypesArray);
762e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (longValuesArray)
763e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(longValuesArray);
764e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        if (stringValuesArray)
765e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood            env->DeleteLocalRef(stringValuesArray);
766e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
767e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
768e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    env->DeleteLocalRef(list);
769e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
770e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    return result;
771e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood}
772e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
7735a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampestatic void foreachentry(ExifEntry *entry, void* /* user */) {
7743cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen    char buf[1024];
7753cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen    ALOGI("entry %x, format %d, size %d: %s",
7763cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen            entry->tag, entry->format, entry->size, exif_entry_get_value(entry, buf, sizeof(buf)));
7773cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen}
7783cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen
7793cd393c5051ce26c8030736f5524962d98abe849Marco Nelissenstatic void foreachcontent(ExifContent *content, void *user) {
7803cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen    ALOGI("content %d", exif_content_get_ifd(content));
7813cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen    exif_content_foreach_entry(content, foreachentry, user);
7823cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen}
7833cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen
7843cd393c5051ce26c8030736f5524962d98abe849Marco Nelissenstatic long getLongFromExifEntry(ExifEntry *e) {
7853cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen    ExifByteOrder o = exif_data_get_byte_order(e->parent->parent);
7863cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen    return exif_get_long(e->data, o);
7873cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen}
7883cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen
789d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike LockwoodMtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
7909df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood                                            MtpObjectInfo& info) {
791f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    MtpString       path;
792f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    int64_t         length;
793f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    MtpObjectFormat format;
794f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood
795f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    MtpResponseCode result = getObjectFilePath(handle, path, length, format);
796f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    if (result != MTP_RESPONSE_OK) {
797f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood        return result;
798f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    }
799f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    info.mCompressedSize = (length > 0xFFFFFFFFLL ? 0xFFFFFFFF : (uint32_t)length);
800d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
801d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
802f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    if (!env->CallBooleanMethod(mDatabase, method_getObjectInfo,
803f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood                (jint)handle, mIntBuffer, mStringBuffer, mLongBuffer)) {
804d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
805f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood    }
806d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
807d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jint* intValues = env->GetIntArrayElements(mIntBuffer, 0);
8089df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood    info.mStorageID = intValues[0];
8099df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood    info.mFormat = intValues[1];
8109df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood    info.mParent = intValues[2];
811d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseIntArrayElements(mIntBuffer, intValues, 0);
812d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
813d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
8141341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood    info.mDateCreated = longValues[0];
8151341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood    info.mDateModified = longValues[1];
816d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
817d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
8185a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe    if ((false)) {
8195a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe        info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ?
8205a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe                                MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
8215a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe                                MTP_ASSOCIATION_TYPE_UNDEFINED);
8225a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe    }
8239df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood    info.mAssociationType = MTP_ASSOCIATION_TYPE_UNDEFINED;
824d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
825d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
8266698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert    MtpString temp(reinterpret_cast<char16_t*>(str));
8279df53fae3afd1c6b5278216be2fd33a255602aefMike Lockwood    info.mName = strdup((const char *)temp);
828d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseCharArrayElements(mStringBuffer, str, 0);
829d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
830c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    // read EXIF data for thumbnail information
8318409c0691fb128fef6244305977342776bddf919Jaesung Chung    switch (info.mFormat) {
8328409c0691fb128fef6244305977342776bddf919Jaesung Chung        case MTP_FORMAT_EXIF_JPEG:
8338409c0691fb128fef6244305977342776bddf919Jaesung Chung        case MTP_FORMAT_JFIF: {
8348409c0691fb128fef6244305977342776bddf919Jaesung Chung            ExifData *exifdata = exif_data_new_from_file(path);
8358409c0691fb128fef6244305977342776bddf919Jaesung Chung            if (exifdata) {
8368409c0691fb128fef6244305977342776bddf919Jaesung Chung                if ((false)) {
8378409c0691fb128fef6244305977342776bddf919Jaesung Chung                    exif_data_foreach_content(exifdata, foreachcontent, NULL);
8388409c0691fb128fef6244305977342776bddf919Jaesung Chung                }
8393cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen
8408409c0691fb128fef6244305977342776bddf919Jaesung Chung                ExifEntry *w = exif_content_get_entry(
8418409c0691fb128fef6244305977342776bddf919Jaesung Chung                        exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_X_DIMENSION);
8428409c0691fb128fef6244305977342776bddf919Jaesung Chung                ExifEntry *h = exif_content_get_entry(
8438409c0691fb128fef6244305977342776bddf919Jaesung Chung                        exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_Y_DIMENSION);
8448409c0691fb128fef6244305977342776bddf919Jaesung Chung                info.mThumbCompressedSize = exifdata->data ? exifdata->size : 0;
8458409c0691fb128fef6244305977342776bddf919Jaesung Chung                info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
8468409c0691fb128fef6244305977342776bddf919Jaesung Chung                info.mImagePixWidth = w ? getLongFromExifEntry(w) : 0;
8478409c0691fb128fef6244305977342776bddf919Jaesung Chung                info.mImagePixHeight = h ? getLongFromExifEntry(h) : 0;
8488409c0691fb128fef6244305977342776bddf919Jaesung Chung                exif_data_unref(exifdata);
8498409c0691fb128fef6244305977342776bddf919Jaesung Chung            }
8508409c0691fb128fef6244305977342776bddf919Jaesung Chung            break;
8518409c0691fb128fef6244305977342776bddf919Jaesung Chung        }
8528409c0691fb128fef6244305977342776bddf919Jaesung Chung
8538409c0691fb128fef6244305977342776bddf919Jaesung Chung        // Except DNG, all supported RAW image formats are not defined in PTP 1.2 specification.
8548409c0691fb128fef6244305977342776bddf919Jaesung Chung        // Most of RAW image formats are based on TIFF or TIFF/EP. To render Fuji's RAF format,
8558409c0691fb128fef6244305977342776bddf919Jaesung Chung        // it checks MTP_FORMAT_DEFINED case since it's designed as a custom format.
8568409c0691fb128fef6244305977342776bddf919Jaesung Chung        case MTP_FORMAT_DNG:
8578409c0691fb128fef6244305977342776bddf919Jaesung Chung        case MTP_FORMAT_TIFF:
8588409c0691fb128fef6244305977342776bddf919Jaesung Chung        case MTP_FORMAT_TIFF_EP:
8598409c0691fb128fef6244305977342776bddf919Jaesung Chung        case MTP_FORMAT_DEFINED: {
8608409c0691fb128fef6244305977342776bddf919Jaesung Chung            std::unique_ptr<FileStream> stream(new FileStream(path));
8618409c0691fb128fef6244305977342776bddf919Jaesung Chung            piex::PreviewImageData image_data;
8628409c0691fb128fef6244305977342776bddf919Jaesung Chung            if (!GetExifFromRawImage(stream.get(), path, image_data)) {
8638409c0691fb128fef6244305977342776bddf919Jaesung Chung                // Couldn't parse EXIF data from a image file via piex.
8648409c0691fb128fef6244305977342776bddf919Jaesung Chung                break;
8655a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe            }
8663cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen
8678409c0691fb128fef6244305977342776bddf919Jaesung Chung            info.mThumbCompressedSize = image_data.thumbnail_length;
8683cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen            info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
8698409c0691fb128fef6244305977342776bddf919Jaesung Chung            info.mImagePixWidth = image_data.full_width;
8708409c0691fb128fef6244305977342776bddf919Jaesung Chung            info.mImagePixHeight = image_data.full_height;
8718409c0691fb128fef6244305977342776bddf919Jaesung Chung
8728409c0691fb128fef6244305977342776bddf919Jaesung Chung            break;
873c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood        }
874c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    }
875c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
8760a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
877d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return MTP_RESPONSE_OK;
878d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
879d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
880c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwoodvoid* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) {
881c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    MtpString path;
882c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    int64_t length;
883c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    MtpObjectFormat format;
884c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    void* result = NULL;
885c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    outThumbSize = 0;
886c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
8878409c0691fb128fef6244305977342776bddf919Jaesung Chung    if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK) {
8888409c0691fb128fef6244305977342776bddf919Jaesung Chung        switch (format) {
8898409c0691fb128fef6244305977342776bddf919Jaesung Chung            case MTP_FORMAT_EXIF_JPEG:
8908409c0691fb128fef6244305977342776bddf919Jaesung Chung            case MTP_FORMAT_JFIF: {
8918409c0691fb128fef6244305977342776bddf919Jaesung Chung                ExifData *exifdata = exif_data_new_from_file(path);
8928409c0691fb128fef6244305977342776bddf919Jaesung Chung                if (exifdata) {
8938409c0691fb128fef6244305977342776bddf919Jaesung Chung                    if (exifdata->data) {
8948409c0691fb128fef6244305977342776bddf919Jaesung Chung                        result = malloc(exifdata->size);
8958409c0691fb128fef6244305977342776bddf919Jaesung Chung                        if (result) {
8968409c0691fb128fef6244305977342776bddf919Jaesung Chung                            memcpy(result, exifdata->data, exifdata->size);
8978409c0691fb128fef6244305977342776bddf919Jaesung Chung                            outThumbSize = exifdata->size;
8988409c0691fb128fef6244305977342776bddf919Jaesung Chung                        }
8998409c0691fb128fef6244305977342776bddf919Jaesung Chung                    }
9008409c0691fb128fef6244305977342776bddf919Jaesung Chung                    exif_data_unref(exifdata);
9018409c0691fb128fef6244305977342776bddf919Jaesung Chung                }
9028409c0691fb128fef6244305977342776bddf919Jaesung Chung                break;
9038409c0691fb128fef6244305977342776bddf919Jaesung Chung            }
9048409c0691fb128fef6244305977342776bddf919Jaesung Chung
9058409c0691fb128fef6244305977342776bddf919Jaesung Chung            // See the above comment on getObjectInfo() method.
9068409c0691fb128fef6244305977342776bddf919Jaesung Chung            case MTP_FORMAT_DNG:
9078409c0691fb128fef6244305977342776bddf919Jaesung Chung            case MTP_FORMAT_TIFF:
9088409c0691fb128fef6244305977342776bddf919Jaesung Chung            case MTP_FORMAT_TIFF_EP:
9098409c0691fb128fef6244305977342776bddf919Jaesung Chung            case MTP_FORMAT_DEFINED: {
9108409c0691fb128fef6244305977342776bddf919Jaesung Chung                std::unique_ptr<FileStream> stream(new FileStream(path));
9118409c0691fb128fef6244305977342776bddf919Jaesung Chung                piex::PreviewImageData image_data;
9128409c0691fb128fef6244305977342776bddf919Jaesung Chung                if (!GetExifFromRawImage(stream.get(), path, image_data)) {
9138409c0691fb128fef6244305977342776bddf919Jaesung Chung                    // Couldn't parse EXIF data from a image file via piex.
9148409c0691fb128fef6244305977342776bddf919Jaesung Chung                    break;
9158409c0691fb128fef6244305977342776bddf919Jaesung Chung                }
9168409c0691fb128fef6244305977342776bddf919Jaesung Chung
9178409c0691fb128fef6244305977342776bddf919Jaesung Chung                if (image_data.thumbnail_length == 0) {
9188409c0691fb128fef6244305977342776bddf919Jaesung Chung                    // No thumbnail.
9198409c0691fb128fef6244305977342776bddf919Jaesung Chung                    break;
9208409c0691fb128fef6244305977342776bddf919Jaesung Chung                }
9213cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen
9228409c0691fb128fef6244305977342776bddf919Jaesung Chung                result = malloc(image_data.thumbnail_length);
9233cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen                if (result) {
9248409c0691fb128fef6244305977342776bddf919Jaesung Chung                    piex::Error err = stream.get()->GetData(
9258409c0691fb128fef6244305977342776bddf919Jaesung Chung                            image_data.thumbnail_offset,
9268409c0691fb128fef6244305977342776bddf919Jaesung Chung                            image_data.thumbnail_length,
9278409c0691fb128fef6244305977342776bddf919Jaesung Chung                            (std::uint8_t *)result);
9288409c0691fb128fef6244305977342776bddf919Jaesung Chung                    if (err == piex::Error::kOk) {
9298409c0691fb128fef6244305977342776bddf919Jaesung Chung                        outThumbSize = image_data.thumbnail_length;
9308409c0691fb128fef6244305977342776bddf919Jaesung Chung                    } else {
9318409c0691fb128fef6244305977342776bddf919Jaesung Chung                        free(result);
9328409c0691fb128fef6244305977342776bddf919Jaesung Chung                    }
9333cd393c5051ce26c8030736f5524962d98abe849Marco Nelissen                }
9348409c0691fb128fef6244305977342776bddf919Jaesung Chung                break;
935c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood            }
936c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood        }
937c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    }
938c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
939c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood    return result;
940c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood}
941c89f22242b955ae748765b3465b819b40f70ee5fMike Lockwood
94259c777a24a2c639dfd84b7bf17e430e6d3424866Mike LockwoodMtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle,
943365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            MtpString& outFilePath,
944365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            int64_t& outFileLength,
945365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood                                            MtpObjectFormat& outFormat) {
946d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
94759c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath,
948d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                (jint)handle, mStringBuffer, mLongBuffer);
94959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (result != MTP_RESPONSE_OK) {
95059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        checkAndClearExceptionFromCallback(env, __FUNCTION__);
95159c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood        return result;
95259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
953d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
954d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
9556698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert    outFilePath.setTo(reinterpret_cast<char16_t*>(str),
9566698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert                      strlen16(reinterpret_cast<char16_t*>(str)));
957d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseCharArrayElements(mStringBuffer, str, 0);
958d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
959d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
960365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood    outFileLength = longValues[0];
961365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood    outFormat = longValues[1];
962d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
96315dd15fd572df6b6f785dff75f66e9b99f40322aElliott Hughes
9640a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
96559c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    return result;
966d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
967d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
96859c777a24a2c639dfd84b7bf17e430e6d3424866Mike LockwoodMtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) {
969d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
9700a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    MtpResponseCode result = env->CallIntMethod(mDatabase, method_deleteFile, (jint)handle);
9710a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
9720a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
9730a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
974d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
975d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
976d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstruct PropertyTableEntry {
977d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MtpObjectProperty   property;
978d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    int                 type;
979d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
980d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
98159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic const PropertyTableEntry   kObjectPropertyTable[] = {
982d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_STORAGE_ID,        MTP_TYPE_UINT32     },
983d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_OBJECT_FORMAT,     MTP_TYPE_UINT16     },
984d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16     },
985d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_OBJECT_SIZE,       MTP_TYPE_UINT64     },
986d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_OBJECT_FILE_NAME,  MTP_TYPE_STR        },
987d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_DATE_MODIFIED,     MTP_TYPE_STR        },
988d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_PARENT_OBJECT,     MTP_TYPE_UINT32     },
989d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_PERSISTENT_UID,    MTP_TYPE_UINT128    },
990d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood    {   MTP_PROPERTY_NAME,              MTP_TYPE_STR        },
991ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DISPLAY_NAME,      MTP_TYPE_STR        },
992ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DATE_ADDED,        MTP_TYPE_STR        },
993ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ARTIST,            MTP_TYPE_STR        },
994ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ALBUM_NAME,        MTP_TYPE_STR        },
995ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ALBUM_ARTIST,      MTP_TYPE_STR        },
996ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_TRACK,             MTP_TYPE_UINT16     },
997ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_TYPE_STR    },
998ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_GENRE,             MTP_TYPE_STR        },
999ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_COMPOSER,          MTP_TYPE_STR        },
1000ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DURATION,          MTP_TYPE_UINT32     },
1001ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood    {   MTP_PROPERTY_DESCRIPTION,       MTP_TYPE_STR        },
100271827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood    {   MTP_PROPERTY_AUDIO_WAVE_CODEC,  MTP_TYPE_UINT32     },
100371827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood    {   MTP_PROPERTY_BITRATE_TYPE,      MTP_TYPE_UINT16     },
100471827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood    {   MTP_PROPERTY_AUDIO_BITRATE,     MTP_TYPE_UINT32     },
100571827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood    {   MTP_PROPERTY_NUMBER_OF_CHANNELS,MTP_TYPE_UINT16     },
100671827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood    {   MTP_PROPERTY_SAMPLE_RATE,       MTP_TYPE_UINT32     },
1007d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
1008d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
100959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodstatic const PropertyTableEntry   kDevicePropertyTable[] = {
1010ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    {   MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,    MTP_TYPE_STR },
1011ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    {   MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,       MTP_TYPE_STR },
1012ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    {   MTP_DEVICE_PROPERTY_IMAGE_SIZE,                 MTP_TYPE_STR },
101356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood    {   MTP_DEVICE_PROPERTY_BATTERY_LEVEL,              MTP_TYPE_UINT8 },
101459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood};
101559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
101659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodbool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
101759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
101859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    const PropertyTableEntry* entry = kObjectPropertyTable;
101959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    for (int i = 0; i < count; i++, entry++) {
102059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        if (entry->property == property) {
102159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            type = entry->type;
102259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            return true;
102359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        }
102459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
102559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return false;
102659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood}
102759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
102859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodbool MyMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) {
102959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    int count = sizeof(kDevicePropertyTable) / sizeof(kDevicePropertyTable[0]);
103059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    const PropertyTableEntry* entry = kDevicePropertyTable;
1031d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    for (int i = 0; i < count; i++, entry++) {
1032d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        if (entry->property == property) {
1033d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            type = entry->type;
1034d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            return true;
1035d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        }
1036d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
1037d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return false;
1038d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
1039d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
10409a2046fb5ceeee4d5334274cbff15f1058bb3244Mike LockwoodMtpObjectHandleList* MyMtpDatabase::getObjectReferences(MtpObjectHandle handle) {
10419a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
10429a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jintArray array = (jintArray)env->CallObjectMethod(mDatabase, method_getObjectReferences,
10439a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                (jint)handle);
10449a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (!array)
10459a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return NULL;
10469a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    MtpObjectHandleList* list = new MtpObjectHandleList();
10479a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jint* handles = env->GetIntArrayElements(array, 0);
10489a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jsize length = env->GetArrayLength(array);
10499a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    for (int i = 0; i < length; i++)
10509a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        list->push(handles[i]);
10510a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    env->ReleaseIntArrayElements(array, handles, 0);
10528839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
10530a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood
10540a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
10550a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return list;
10569a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood}
10579a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
10580a7fa0a868ccce920827e141cbbe237594e53364Mike LockwoodMtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle,
10590a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood                                                    MtpObjectHandleList* references) {
10609a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
10619a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    int count = references->size();
10629a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jintArray array = env->NewIntArray(count);
10639a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (!array) {
10643762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("out of memory in setObjectReferences");
10659a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return false;
10669a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    }
10679a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    jint* handles = env->GetIntArrayElements(array, 0);
10689a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood     for (int i = 0; i < count; i++)
10699a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        handles[i] = (*references)[i];
10709a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    env->ReleaseIntArrayElements(array, handles, 0);
10710a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    MtpResponseCode result = env->CallIntMethod(mDatabase, method_setObjectReferences,
10729a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                (jint)handle, array);
10738839471f4d83238f9c017142dcbe3f915f3213fbMike Lockwood    env->DeleteLocalRef(array);
10749a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
10750a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
10760a7fa0a868ccce920827e141cbbe237594e53364Mike Lockwood    return result;
1077d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
1078d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1079828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
1080828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood                                            MtpObjectFormat format) {
108192b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood    static const int channelEnum[] = {
108292b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                        1,  // mono
108392b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                        2,  // stereo
108492b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                        3,  // 2.1
108592b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                        4,  // 3
108692b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                        5,  // 3.1
108792b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                        6,  // 4
108892b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                        7,  // 4.1
108992b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                        8,  // 5
109092b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                        9,  // 5.1
109192b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                    };
109292b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood    static const int bitrateEnum[] = {
109392b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                        1,  // fixed rate
109492b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                        2,  // variable rate
109592b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood                                     };
109692b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood
1097828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    MtpProperty* result = NULL;
1098828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    switch (property) {
1099828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_OBJECT_FORMAT:
11009b5e9c407d35eab4f37c208d81bdf0b8bcdbdf93Mike Lockwood            // use format as default value
11019b5e9c407d35eab4f37c208d81bdf0b8bcdbdf93Mike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT16, false, format);
11029b5e9c407d35eab4f37c208d81bdf0b8bcdbdf93Mike Lockwood            break;
1103828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_PROTECTION_STATUS:
1104ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_TRACK:
1105828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT16);
1106828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
1107828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_STORAGE_ID:
1108828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_PARENT_OBJECT:
1109ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_DURATION:
111092b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood        case MTP_PROPERTY_AUDIO_WAVE_CODEC:
1111828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT32);
1112828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
1113828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_OBJECT_SIZE:
1114828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT64);
1115828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
1116828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood        case MTP_PROPERTY_PERSISTENT_UID:
1117828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT128);
1118828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
1119d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood        case MTP_PROPERTY_NAME:
1120ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_DISPLAY_NAME:
1121ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_ARTIST:
1122ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_ALBUM_NAME:
1123ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_ALBUM_ARTIST:
1124ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_GENRE:
1125ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_COMPOSER:
1126ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood        case MTP_PROPERTY_DESCRIPTION:
1127828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR);
1128828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood            break;
11295b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood        case MTP_PROPERTY_DATE_MODIFIED:
11305b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood        case MTP_PROPERTY_DATE_ADDED:
11315b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood        case MTP_PROPERTY_ORIGINAL_RELEASE_DATE:
11325b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR);
11335b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood            result->setFormDateTime();
11345b19af05f2c6ad71171f95bdad2484a38b61121fMike Lockwood            break;
11355ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood        case MTP_PROPERTY_OBJECT_FILE_NAME:
11366a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood            // We allow renaming files and folders
11376a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR, true);
11385ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood            break;
113992b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood        case MTP_PROPERTY_BITRATE_TYPE:
114092b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood             result = new MtpProperty(property, MTP_TYPE_UINT16);
114192b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood            result->setFormEnum(bitrateEnum, sizeof(bitrateEnum)/sizeof(bitrateEnum[0]));
114292b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood            break;
114392b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood        case MTP_PROPERTY_AUDIO_BITRATE:
114492b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT32);
114592b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood            result->setFormRange(1, 1536000, 1);
114692b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood            break;
114792b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood        case MTP_PROPERTY_NUMBER_OF_CHANNELS:
114892b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT16);
114992b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood            result->setFormEnum(channelEnum, sizeof(channelEnum)/sizeof(channelEnum[0]));
115092b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood            break;
115192b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood        case MTP_PROPERTY_SAMPLE_RATE:
115292b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT32);
115392b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood            result->setFormRange(8000, 48000, 1);
115492b53bc2dd42a3c1d2d7708145099da2a5fe541eMike Lockwood            break;
1155828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    }
1156828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
1157828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood    return result;
1158828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
1159828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
1160828d19dd96b05fa99abdc517701e5366543c324fMike LockwoodMtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
1161ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
116259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    MtpProperty* result = NULL;
1163ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    bool writable = false;
1164ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood
116559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    switch (property) {
116659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
116759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
1168ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            writable = true;
1169ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            // fall through
117056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        case MTP_DEVICE_PROPERTY_IMAGE_SIZE: {
1171ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            result = new MtpProperty(property, MTP_TYPE_STR, writable);
1172a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood
1173ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood            // get current value
1174a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            jint ret = env->CallIntMethod(mDatabase, method_getDeviceProperty,
1175a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                        (jint)property, mLongBuffer, mStringBuffer);
1176a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            if (ret == MTP_RESPONSE_OK) {
1177a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
1178a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                result->setCurrentValue(str);
1179ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood                // for read-only properties it is safe to assume current value is default value
1180ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood                if (!writable)
1181ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood                    result->setDefaultValue(str);
1182a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood                env->ReleaseCharArrayElements(mStringBuffer, str, 0);
1183a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            } else {
11843762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("unable to read device property, response: %04X", ret);
1185a2a2128423309641a6b508a15404f3a7e8f3077bMike Lockwood            }
118659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood            break;
118756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        }
118856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        case MTP_DEVICE_PROPERTY_BATTERY_LEVEL:
118956c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            result = new MtpProperty(property, MTP_TYPE_UINT8);
119056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            result->setFormRange(0, env->GetIntField(mDatabase, field_batteryScale), 1);
119156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            result->mCurrentValue.u.u8 = (uint8_t)env->GetIntField(mDatabase, field_batteryLevel);
119256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood            break;
119359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
119459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood
1195ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
119659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    return result;
1197828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood}
1198828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood
11992837eefc5459427138c080d445bb491c75630163Mike Lockwoodvoid MyMtpDatabase::sessionStarted() {
12002837eefc5459427138c080d445bb491c75630163Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
12012837eefc5459427138c080d445bb491c75630163Mike Lockwood    env->CallVoidMethod(mDatabase, method_sessionStarted);
12022837eefc5459427138c080d445bb491c75630163Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
12032837eefc5459427138c080d445bb491c75630163Mike Lockwood}
12042837eefc5459427138c080d445bb491c75630163Mike Lockwood
12052837eefc5459427138c080d445bb491c75630163Mike Lockwoodvoid MyMtpDatabase::sessionEnded() {
12062837eefc5459427138c080d445bb491c75630163Mike Lockwood    JNIEnv* env = AndroidRuntime::getJNIEnv();
12072837eefc5459427138c080d445bb491c75630163Mike Lockwood    env->CallVoidMethod(mDatabase, method_sessionEnded);
12082837eefc5459427138c080d445bb491c75630163Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
12092837eefc5459427138c080d445bb491c75630163Mike Lockwood}
12102837eefc5459427138c080d445bb491c75630163Mike Lockwood
1211d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
1212d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1213d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic void
12140cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodandroid_mtp_MtpDatabase_setup(JNIEnv *env, jobject thiz)
1215d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
1216d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    MyMtpDatabase* database = new MyMtpDatabase(env, thiz);
1217e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    env->SetLongField(thiz, field_context, (jlong)database);
1218d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
1219d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
1220d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1221d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodstatic void
12220cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodandroid_mtp_MtpDatabase_finalize(JNIEnv *env, jobject thiz)
1223d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
1224e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    MyMtpDatabase* database = (MyMtpDatabase *)env->GetLongField(thiz, field_context);
1225d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    database->cleanup(env);
1226d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    delete database;
1227e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    env->SetLongField(thiz, field_context, 0);
1228d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    checkAndClearExceptionFromCallback(env, __FUNCTION__);
1229d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
1230d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
12313159991e586f9e243f60d65a9554828328b00521Mike Lockwoodstatic jstring
1232aeb75fc5a3dc51bf9d5220647a68c48644c66ea8Mark Salyzynandroid_mtp_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject /*thiz*/, jlong seconds)
12333159991e586f9e243f60d65a9554828328b00521Mike Lockwood{
12343159991e586f9e243f60d65a9554828328b00521Mike Lockwood    char    date[20];
12353159991e586f9e243f60d65a9554828328b00521Mike Lockwood    formatDateTime(seconds, date, sizeof(date));
12363159991e586f9e243f60d65a9554828328b00521Mike Lockwood    return env->NewStringUTF(date);
12373159991e586f9e243f60d65a9554828328b00521Mike Lockwood}
12383159991e586f9e243f60d65a9554828328b00521Mike Lockwood
1239d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood// ----------------------------------------------------------------------------
1240d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
124176f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMtpDatabaseMethods[] = {
12420cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood    {"native_setup",            "()V",  (void *)android_mtp_MtpDatabase_setup},
12430cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood    {"native_finalize",         "()V",  (void *)android_mtp_MtpDatabase_finalize},
12447d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood};
12457d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
124676f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMtpPropertyGroupMethods[] = {
12473159991e586f9e243f60d65a9554828328b00521Mike Lockwood    {"format_date_time",        "(J)Ljava/lang/String;",
12480cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood                                        (void *)android_mtp_MtpPropertyGroup_format_date_time},
1249d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood};
1250d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
12510cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodint register_android_mtp_MtpDatabase(JNIEnv *env)
1252d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood{
1253d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    jclass clazz;
1254d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
12550cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood    clazz = env->FindClass("android/mtp/MtpDatabase");
1256d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (clazz == NULL) {
12573762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpDatabase");
1258d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1259d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
1260d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    method_beginSendObject = env->GetMethodID(clazz, "beginSendObject", "(Ljava/lang/String;IIIJJ)I");
1261d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    if (method_beginSendObject == NULL) {
12623762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find beginSendObject");
1263d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        return -1;
1264d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    }
12657a0bd17bceaf3efc3732e30c538fae420d3b742cMike Lockwood    method_endSendObject = env->GetMethodID(clazz, "endSendObject", "(Ljava/lang/String;IIZ)V");
1266d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    if (method_endSendObject == NULL) {
12673762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find endSendObject");
1268d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1269d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
1270d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    method_getObjectList = env->GetMethodID(clazz, "getObjectList", "(III)[I");
1271d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_getObjectList == NULL) {
12723762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getObjectList");
1273d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1274d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
12757a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    method_getNumObjects = env->GetMethodID(clazz, "getNumObjects", "(III)I");
12767a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    if (method_getNumObjects == NULL) {
12773762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getNumObjects");
12787a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        return -1;
12797a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    }
12804b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedPlaybackFormats = env->GetMethodID(clazz, "getSupportedPlaybackFormats", "()[I");
12814b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedPlaybackFormats == NULL) {
12823762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getSupportedPlaybackFormats");
12834b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
12844b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
12854b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedCaptureFormats = env->GetMethodID(clazz, "getSupportedCaptureFormats", "()[I");
12864b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedCaptureFormats == NULL) {
12873762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getSupportedCaptureFormats");
12884b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
12894b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
12904b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedObjectProperties = env->GetMethodID(clazz, "getSupportedObjectProperties", "(I)[I");
12914b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedObjectProperties == NULL) {
12923762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getSupportedObjectProperties");
12934b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
12944b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
12954b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    method_getSupportedDeviceProperties = env->GetMethodID(clazz, "getSupportedDeviceProperties", "()[I");
12964b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    if (method_getSupportedDeviceProperties == NULL) {
12973762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getSupportedDeviceProperties");
12984b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood        return -1;
12994b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood    }
130059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    method_setObjectProperty = env->GetMethodID(clazz, "setObjectProperty", "(IIJLjava/lang/String;)I");
130159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (method_setObjectProperty == NULL) {
13023762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find setObjectProperty");
130359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return -1;
130459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
130559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    method_getDeviceProperty = env->GetMethodID(clazz, "getDeviceProperty", "(I[J[C)I");
130659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (method_getDeviceProperty == NULL) {
13073762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getDeviceProperty");
130859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return -1;
130959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
131059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    method_setDeviceProperty = env->GetMethodID(clazz, "setDeviceProperty", "(IJLjava/lang/String;)I");
131159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    if (method_setDeviceProperty == NULL) {
13123762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find setDeviceProperty");
131359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood        return -1;
131459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood    }
1315e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    method_getObjectPropertyList = env->GetMethodID(clazz, "getObjectPropertyList",
13160cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood            "(JIJII)Landroid/mtp/MtpPropertyList;");
1317e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (method_getObjectPropertyList == NULL) {
13183762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getObjectPropertyList");
1319e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1320e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1321d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z");
1322d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_getObjectInfo == NULL) {
13233762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getObjectInfo");
1324d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1325d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
132659c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    method_getObjectFilePath = env->GetMethodID(clazz, "getObjectFilePath", "(I[C[J)I");
1327d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_getObjectFilePath == NULL) {
13283762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getObjectFilePath");
1329d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1330d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
133159c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    method_deleteFile = env->GetMethodID(clazz, "deleteFile", "(I)I");
1332d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (method_deleteFile == NULL) {
13333762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find deleteFile");
1334d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1335d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
13369a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    method_getObjectReferences = env->GetMethodID(clazz, "getObjectReferences", "(I)[I");
13379a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (method_getObjectReferences == NULL) {
13383762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find getObjectReferences");
13399a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return -1;
13409a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    }
13419a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    method_setObjectReferences = env->GetMethodID(clazz, "setObjectReferences", "(I[I)I");
13429a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    if (method_setObjectReferences == NULL) {
13433762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find setObjectReferences");
13449a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return -1;
13459a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    }
13462837eefc5459427138c080d445bb491c75630163Mike Lockwood    method_sessionStarted = env->GetMethodID(clazz, "sessionStarted", "()V");
13472837eefc5459427138c080d445bb491c75630163Mike Lockwood    if (method_sessionStarted == NULL) {
13483762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find sessionStarted");
13492837eefc5459427138c080d445bb491c75630163Mike Lockwood        return -1;
13502837eefc5459427138c080d445bb491c75630163Mike Lockwood    }
13512837eefc5459427138c080d445bb491c75630163Mike Lockwood    method_sessionEnded = env->GetMethodID(clazz, "sessionEnded", "()V");
13522837eefc5459427138c080d445bb491c75630163Mike Lockwood    if (method_sessionEnded == NULL) {
13533762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find sessionEnded");
13542837eefc5459427138c080d445bb491c75630163Mike Lockwood        return -1;
13552837eefc5459427138c080d445bb491c75630163Mike Lockwood    }
13562837eefc5459427138c080d445bb491c75630163Mike Lockwood
1357e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    field_context = env->GetFieldID(clazz, "mNativeContext", "J");
1358d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    if (field_context == NULL) {
13593762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpDatabase.mNativeContext");
1360d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return -1;
1361d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
136256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood    field_batteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
136356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood    if (field_batteryLevel == NULL) {
136456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        ALOGE("Can't find MtpDatabase.mBatteryLevel");
136556c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        return -1;
136656c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood    }
136756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood    field_batteryScale = env->GetFieldID(clazz, "mBatteryScale", "I");
136856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood    if (field_batteryScale == NULL) {
136956c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        ALOGE("Can't find MtpDatabase.mBatteryScale");
137056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood        return -1;
137156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood    }
1372d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1373e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    // now set up fields for MtpPropertyList class
13740cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood    clazz = env->FindClass("android/mtp/MtpPropertyList");
1375e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (clazz == NULL) {
13763762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpPropertyList");
1377e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1378e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1379e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mCount = env->GetFieldID(clazz, "mCount", "I");
1380e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mCount == NULL) {
13813762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mCount");
1382e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1383e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1384e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mResult = env->GetFieldID(clazz, "mResult", "I");
1385e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mResult == NULL) {
13863762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mResult");
1387e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1388e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1389e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mObjectHandles = env->GetFieldID(clazz, "mObjectHandles", "[I");
1390e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mObjectHandles == NULL) {
13913762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mObjectHandles");
1392e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1393e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1394e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mPropertyCodes = env->GetFieldID(clazz, "mPropertyCodes", "[I");
1395e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mPropertyCodes == NULL) {
13963762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mPropertyCodes");
1397e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1398e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1399e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mDataTypes = env->GetFieldID(clazz, "mDataTypes", "[I");
1400e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mDataTypes == NULL) {
14013762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mDataTypes");
1402e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1403e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1404e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mLongValues = env->GetFieldID(clazz, "mLongValues", "[J");
1405e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mLongValues == NULL) {
14063762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mLongValues");
1407e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1408e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1409e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    field_mStringValues = env->GetFieldID(clazz, "mStringValues", "[Ljava/lang/String;");
1410e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    if (field_mStringValues == NULL) {
14113762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpPropertyList.mStringValues");
1412e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood        return -1;
1413e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood    }
1414e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood
14157d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    if (AndroidRuntime::registerNativeMethods(env,
14160cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood                "android/mtp/MtpDatabase", gMtpDatabaseMethods, NELEM(gMtpDatabaseMethods)))
14177d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        return -1;
14187d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
1419d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    return AndroidRuntime::registerNativeMethods(env,
14200cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood                "android/mtp/MtpPropertyGroup", gMtpPropertyGroupMethods, NELEM(gMtpPropertyGroupMethods));
1421d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
1422