18182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood/*
28182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * Copyright (C) 2010 The Android Open Source Project
38182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood *
48182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
58182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * you may not use this file except in compliance with the License.
68182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * You may obtain a copy of the License at
78182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood *
88182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
98182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood *
108182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * Unless required by applicable law or agreed to in writing, software
118182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
128182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * See the License for the specific language governing permissions and
148182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * limitations under the License.
158182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood */
168182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
178182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood// #define LOG_NDEBUG 0
188182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
198182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#define LOG_TAG "MtpDeviceJNI"
208182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include "utils/Log.h"
218182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
228182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include <stdio.h>
238182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include <assert.h>
248182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include <limits.h>
258182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include <unistd.h>
268182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include <fcntl.h>
278182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
28148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono#include <memory>
29e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono#include <string>
30148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono
318182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include "jni.h"
322279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/JNIHelp.h>
332279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/ScopedPrimitiveArray.h>
341d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono
358182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include "android_runtime/AndroidRuntime.h"
3687eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include "android_runtime/Log.h"
3752da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono#include "nativehelper/ScopedLocalRef.h"
388182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include "private/android_filesystem_config.h"
398182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
408182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include "MtpTypes.h"
418182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include "MtpDevice.h"
428182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include "MtpDeviceInfo.h"
438182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include "MtpStorageInfo.h"
448182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include "MtpObjectInfo.h"
45787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono#include "MtpProperty.h"
468182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
478182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodusing namespace android;
488182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
498182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood// ----------------------------------------------------------------------------
508182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
5152da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirononamespace {
5252da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono
538182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_context;
548182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
558182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodjclass clazz_deviceInfo;
568182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodjclass clazz_storageInfo;
578182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodjclass clazz_objectInfo;
580b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hironojclass clazz_event;
590b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hironojclass clazz_io_exception;
600b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hironojclass clazz_operation_canceled_exception;
618182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
628182e72479a8b0d832df9c392890b25bfa6f97b5Mike LockwoodjmethodID constructor_deviceInfo;
638182e72479a8b0d832df9c392890b25bfa6f97b5Mike LockwoodjmethodID constructor_storageInfo;
648182e72479a8b0d832df9c392890b25bfa6f97b5Mike LockwoodjmethodID constructor_objectInfo;
650b494663a4cb177fc6f05988c9bda2ef6277333dDaichi HironojmethodID constructor_event;
668182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
678182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood// MtpDeviceInfo fields
688182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_deviceInfo_manufacturer;
698182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_deviceInfo_model;
708182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_deviceInfo_version;
718182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_deviceInfo_serialNumber;
721d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hironostatic jfieldID field_deviceInfo_operationsSupported;
73148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hironostatic jfieldID field_deviceInfo_eventsSupported;
748182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
758182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood// MtpStorageInfo fields
768182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_storageInfo_storageId;
778182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_storageInfo_maxCapacity;
788182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_storageInfo_freeSpace;
798182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_storageInfo_description;
808182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_storageInfo_volumeIdentifier;
818182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
828182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood// MtpObjectInfo fields
838182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_handle;
848182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_storageId;
858182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_format;
868182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_protectionStatus;
878182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_compressedSize;
888182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_thumbFormat;
898182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_thumbCompressedSize;
908182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_thumbPixWidth;
918182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_thumbPixHeight;
928182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_imagePixWidth;
938182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_imagePixHeight;
948182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_imagePixDepth;
958182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_parent;
968182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_associationType;
978182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_associationDesc;
988182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_sequenceNumber;
998182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_name;
1008182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_dateCreated;
1018182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_dateModified;
1028182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jfieldID field_objectInfo_keywords;
1038182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
1040b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono// MtpEvent fields
1050b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hironostatic jfieldID field_event_eventCode;
1062a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hironostatic jfieldID field_event_parameter1;
1072a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hironostatic jfieldID field_event_parameter2;
1082a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hironostatic jfieldID field_event_parameter3;
1090b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono
11052da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hironoclass JavaArrayWriter {
11152da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hironopublic:
11252da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    JavaArrayWriter(JNIEnv* env, jbyteArray array) :
11352da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        mEnv(env), mArray(array), mSize(mEnv->GetArrayLength(mArray)) {}
11452da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    bool write(void* data, uint32_t offset, uint32_t length) {
11552da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        if (static_cast<uint32_t>(mSize) < offset + length) {
11652da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono            return false;
11752da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        }
11852da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        mEnv->SetByteArrayRegion(mArray, offset, length, static_cast<jbyte*>(data));
11952da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        return true;
12052da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    }
12152da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    static bool writeTo(void* data, uint32_t offset, uint32_t length, void* clientData) {
12252da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        return static_cast<JavaArrayWriter*>(clientData)->write(data, offset, length);
12352da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    }
1243ad1a8ee94969bb2c4fae56579fe953cbdeeee7eDaichi Hirono
1253ad1a8ee94969bb2c4fae56579fe953cbdeeee7eDaichi Hironoprivate:
1263ad1a8ee94969bb2c4fae56579fe953cbdeeee7eDaichi Hirono    JNIEnv* mEnv;
1273ad1a8ee94969bb2c4fae56579fe953cbdeeee7eDaichi Hirono    jbyteArray mArray;
1283ad1a8ee94969bb2c4fae56579fe953cbdeeee7eDaichi Hirono    jsize mSize;
12952da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono};
13052da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono
13152da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono}
13252da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono
1338182e72479a8b0d832df9c392890b25bfa6f97b5Mike LockwoodMtpDevice* get_device_from_object(JNIEnv* env, jobject javaDevice)
1348182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
135e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    return (MtpDevice*)env->GetLongField(javaDevice, field_context);
1368182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
1378182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
138b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewskivoid fill_jobject_from_object_info(JNIEnv* env, jobject object, MtpObjectInfo* objectInfo) {
139b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mHandle)
140b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_handle, objectInfo->mHandle);
141b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mStorageID)
142b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_storageId, objectInfo->mStorageID);
143b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mFormat)
144b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_format, objectInfo->mFormat);
145b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mProtectionStatus)
146b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_protectionStatus, objectInfo->mProtectionStatus);
147b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mCompressedSize)
148b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_compressedSize, objectInfo->mCompressedSize);
149b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mThumbFormat)
150b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_thumbFormat, objectInfo->mThumbFormat);
151b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mThumbCompressedSize) {
152b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_thumbCompressedSize,
153b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski                objectInfo->mThumbCompressedSize);
154b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    }
155b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mThumbPixWidth)
156b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_thumbPixWidth, objectInfo->mThumbPixWidth);
157b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mThumbPixHeight)
158b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_thumbPixHeight, objectInfo->mThumbPixHeight);
159b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mImagePixWidth)
160b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_imagePixWidth, objectInfo->mImagePixWidth);
161b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mImagePixHeight)
162b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_imagePixHeight, objectInfo->mImagePixHeight);
163b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mImagePixDepth)
164b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_imagePixDepth, objectInfo->mImagePixDepth);
165b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mParent)
166b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_parent, objectInfo->mParent);
167b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mAssociationType)
168b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_associationType, objectInfo->mAssociationType);
169b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mAssociationDesc)
170b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_associationDesc, objectInfo->mAssociationDesc);
171b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mSequenceNumber)
172b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetIntField(object, field_objectInfo_sequenceNumber, objectInfo->mSequenceNumber);
173b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mName)
174b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetObjectField(object, field_objectInfo_name, env->NewStringUTF(objectInfo->mName));
175b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mDateCreated)
176b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetLongField(object, field_objectInfo_dateCreated, objectInfo->mDateCreated * 1000LL);
177b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mDateModified) {
178b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetLongField(object, field_objectInfo_dateModified,
179b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski                objectInfo->mDateModified * 1000LL);
180b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    }
181b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (objectInfo->mKeywords) {
182b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        env->SetObjectField(object, field_objectInfo_keywords,
183b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski            env->NewStringUTF(objectInfo->mKeywords));
184b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    }
185b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski}
186b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
1878182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood// ----------------------------------------------------------------------------
1888182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
1898182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jboolean
1908182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_open(JNIEnv *env, jobject thiz, jstring deviceName, jint fd)
1918182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
1928182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    const char *deviceNameStr = env->GetStringUTFChars(deviceName, NULL);
1933977472d9f3380a8323156dbc7d0090cf2f2d310James Dong    if (deviceNameStr == NULL) {
194e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat        return JNI_FALSE;
1953977472d9f3380a8323156dbc7d0090cf2f2d310James Dong    }
1963977472d9f3380a8323156dbc7d0090cf2f2d310James Dong
197b828b77985416c4d870771a02cd523397726c215Philip P. Moltmann    // The passed in fd is maintained by the UsbDeviceConnection
198b828b77985416c4d870771a02cd523397726c215Philip P. Moltmann    fd = dup(fd);
199b828b77985416c4d870771a02cd523397726c215Philip P. Moltmann
2008182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = MtpDevice::open(deviceNameStr, fd);
2018182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    env->ReleaseStringUTFChars(deviceName, deviceNameStr);
2028182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
2038182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (device)
204e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat        env->SetLongField(thiz, field_context,  (jlong)device);
205e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    return (jboolean)(device != NULL);
2068182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
2078182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
2088182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic void
2098182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_close(JNIEnv *env, jobject thiz)
2108182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
2118182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
2128182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (device) {
2138182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        device->close();
2148182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        delete device;
215e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat        env->SetLongField(thiz, field_context, 0);
2168182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
2178182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
2188182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
2198182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jobject
2208182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_get_device_info(JNIEnv *env, jobject thiz)
2218182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
2228182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
2238182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (!device) {
2245baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("android_mtp_MtpDevice_get_device_info device is null");
2258182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
2268182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
227148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono    std::unique_ptr<MtpDeviceInfo> deviceInfo(device->getDeviceInfo());
2288182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (!deviceInfo) {
2295baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("android_mtp_MtpDevice_get_device_info deviceInfo is null");
2308182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
2318182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
2328182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    jobject info = env->NewObject(clazz_deviceInfo, constructor_deviceInfo);
2338182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (info == NULL) {
2343762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Could not create a MtpDeviceInfo object");
2358182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
2368182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
2378182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
2388182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (deviceInfo->mManufacturer)
2398182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        env->SetObjectField(info, field_deviceInfo_manufacturer,
2408182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood            env->NewStringUTF(deviceInfo->mManufacturer));
2418182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (deviceInfo->mModel)
2428182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        env->SetObjectField(info, field_deviceInfo_model,
2438182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood            env->NewStringUTF(deviceInfo->mModel));
2448182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (deviceInfo->mVersion)
2458182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        env->SetObjectField(info, field_deviceInfo_version,
2468182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood            env->NewStringUTF(deviceInfo->mVersion));
2478182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (deviceInfo->mSerial)
2488182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        env->SetObjectField(info, field_deviceInfo_serialNumber,
2498182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood            env->NewStringUTF(deviceInfo->mSerial));
250399df701a16704b002475300a535683005d7af8bDaichi Hirono    assert(deviceInfo->mOperations);
251399df701a16704b002475300a535683005d7af8bDaichi Hirono    {
2521d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono        const size_t size = deviceInfo->mOperations->size();
253148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono        ScopedLocalRef<jintArray> operations(env, static_cast<jintArray>(env->NewIntArray(size)));
2541d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono        {
255148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono            ScopedIntArrayRW elements(env, operations.get());
256148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono            if (elements.get() == NULL) {
257148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono                ALOGE("Could not create operationsSupported element.");
258148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono                return NULL;
259148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono            }
2601d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono            for (size_t i = 0; i < size; ++i) {
261d9f3005fc3d3e6544e5e94052d9229413b0181d1Jerry Zhang                elements[i] = static_cast<int>(deviceInfo->mOperations->at(i));
2621d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono            }
263148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono            env->SetObjectField(info, field_deviceInfo_operationsSupported, operations.get());
264148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono        }
265148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono    }
266399df701a16704b002475300a535683005d7af8bDaichi Hirono    assert(deviceInfo->mEvents);
267399df701a16704b002475300a535683005d7af8bDaichi Hirono    {
268148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono        const size_t size = deviceInfo->mEvents->size();
269148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono        ScopedLocalRef<jintArray> events(env, static_cast<jintArray>(env->NewIntArray(size)));
270148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono        {
271148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono            ScopedIntArrayRW elements(env, events.get());
272148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono            if (elements.get() == NULL) {
273148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono                ALOGE("Could not create eventsSupported element.");
274148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono                return NULL;
275148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono            }
276148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono            for (size_t i = 0; i < size; ++i) {
277d9f3005fc3d3e6544e5e94052d9229413b0181d1Jerry Zhang                elements[i] = static_cast<int>(deviceInfo->mEvents->at(i));
278148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono            }
279148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono            env->SetObjectField(info, field_deviceInfo_eventsSupported, events.get());
2801d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono        }
2811d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono    }
2828182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
2838182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    return info;
2848182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
2858182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
2868182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jintArray
2878182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_get_storage_ids(JNIEnv *env, jobject thiz)
2888182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
2898182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
2908182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (!device)
2918182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
2928182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpStorageIDList* storageIDs = device->getStorageIDs();
2938182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (!storageIDs)
2948182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
2958182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
2968182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    int length = storageIDs->size();
2978182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    jintArray array = env->NewIntArray(length);
2988182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    // FIXME is this cast safe?
299d9f3005fc3d3e6544e5e94052d9229413b0181d1Jerry Zhang    env->SetIntArrayRegion(array, 0, length, (const jint *)storageIDs->data());
3008182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
3018182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    delete storageIDs;
3028182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    return array;
3038182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
3048182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
3058182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jobject
3068182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_get_storage_info(JNIEnv *env, jobject thiz, jint storageID)
3078182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
3088182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
3098182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (!device)
3108182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
3118182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpStorageInfo* storageInfo = device->getStorageInfo(storageID);
3128182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (!storageInfo)
3138182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
3148182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
3158182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    jobject info = env->NewObject(clazz_storageInfo, constructor_storageInfo);
3168182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (info == NULL) {
3173762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Could not create a MtpStorageInfo object");
3188182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        delete storageInfo;
3198182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
3208182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
3218182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
3228182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (storageInfo->mStorageID)
3238182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        env->SetIntField(info, field_storageInfo_storageId, storageInfo->mStorageID);
3248182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (storageInfo->mMaxCapacity)
3258182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        env->SetLongField(info, field_storageInfo_maxCapacity, storageInfo->mMaxCapacity);
3268182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (storageInfo->mFreeSpaceBytes)
3278182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        env->SetLongField(info, field_storageInfo_freeSpace, storageInfo->mFreeSpaceBytes);
3288182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (storageInfo->mStorageDescription)
3298182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        env->SetObjectField(info, field_storageInfo_description,
3308182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood            env->NewStringUTF(storageInfo->mStorageDescription));
3318182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (storageInfo->mVolumeIdentifier)
3328182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        env->SetObjectField(info, field_storageInfo_volumeIdentifier,
3338182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood            env->NewStringUTF(storageInfo->mVolumeIdentifier));
3348182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
3358182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    delete storageInfo;
3368182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    return info;
3378182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
3388182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
3398182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jintArray
3408182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_get_object_handles(JNIEnv *env, jobject thiz,
3418182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        jint storageID, jint format, jint objectID)
3428182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
3438182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
3448182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (!device)
3458182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
3468182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpObjectHandleList* handles = device->getObjectHandles(storageID, format, objectID);
3478182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (!handles)
3488182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
3498182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
3508182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    int length = handles->size();
3518182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    jintArray array = env->NewIntArray(length);
3528182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    // FIXME is this cast safe?
353d9f3005fc3d3e6544e5e94052d9229413b0181d1Jerry Zhang    env->SetIntArrayRegion(array, 0, length, (const jint *)handles->data());
3548182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
3558182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    delete handles;
3568182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    return array;
3578182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
3588182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
3598182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jobject
3608182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_get_object_info(JNIEnv *env, jobject thiz, jint objectID)
3618182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
3628182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
3638182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (!device)
3648182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
3658182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpObjectInfo* objectInfo = device->getObjectInfo(objectID);
3668182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (!objectInfo)
3678182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
3688182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    jobject info = env->NewObject(clazz_objectInfo, constructor_objectInfo);
3698182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (info == NULL) {
3703762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Could not create a MtpObjectInfo object");
3718182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        delete objectInfo;
3728182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
3738182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
3748182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
375b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    fill_jobject_from_object_info(env, info, objectInfo);
3768182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    delete objectInfo;
3778182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    return info;
3788182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
3798182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
380e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hironobool check_uint32_arg(JNIEnv *env, const char* name, jlong value, uint32_t* out) {
381e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    if (value < 0 || 0xffffffff < value) {
382e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono        jniThrowException(
383e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono                env,
384e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono                "java/lang/IllegalArgumentException",
385e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono                (std::string("argument must be a 32-bit unsigned integer: ") + name).c_str());
386e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono        return false;
387e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    }
388e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    *out = static_cast<uint32_t>(value);
389e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    return true;
390e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono}
391e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono
3928182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jbyteArray
393e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hironoandroid_mtp_MtpDevice_get_object(JNIEnv *env, jobject thiz, jint objectID, jlong objectSizeLong)
3948182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
395e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    uint32_t objectSize;
396e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    if (!check_uint32_arg(env, "objectSize", objectSizeLong, &objectSize)) {
397e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono        return nullptr;
398e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    }
399e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono
4008182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
40152da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    if (!device) {
40252da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        return nullptr;
40352da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    }
4048182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
40552da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    ScopedLocalRef<jbyteArray> array(env, env->NewByteArray(objectSize));
40652da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    if (!array.get()) {
4078182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
40852da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        return nullptr;
4098182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
4108182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
41152da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    JavaArrayWriter writer(env, array.get());
4128182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
41352da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    if (device->readObject(objectID, JavaArrayWriter::writeTo, objectSize, &writer)) {
41452da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        return array.release();
41552da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    }
41652da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    return nullptr;
41752da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono}
41852da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono
4192dd48256e9657b013dd6fa0ca86d1d7c7c730428Daichi Hironostatic jlong
42052da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hironoandroid_mtp_MtpDevice_get_partial_object(JNIEnv *env,
42152da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono                                         jobject thiz,
42252da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono                                         jint objectID,
423e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono                                         jlong offsetLong,
424e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono                                         jlong sizeLong,
42552da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono                                         jbyteArray array)
42652da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono{
4273ad1a8ee94969bb2c4fae56579fe953cbdeeee7eDaichi Hirono    if (!array) {
42852da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        jniThrowException(env, "java/lang/IllegalArgumentException", "Array must not be null.");
42952da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        return -1;
43052da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    }
43152da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono
432e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    uint32_t offset;
433e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    uint32_t size;
434e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    if (!check_uint32_arg(env, "offset", offsetLong, &offset) ||
435e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono            !check_uint32_arg(env, "size", sizeLong, &size)) {
4362dd48256e9657b013dd6fa0ca86d1d7c7c730428Daichi Hirono        return -1;
4372dd48256e9657b013dd6fa0ca86d1d7c7c730428Daichi Hirono    }
4382dd48256e9657b013dd6fa0ca86d1d7c7c730428Daichi Hirono
43952da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    MtpDevice* const device = get_device_from_object(env, thiz);
44052da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    if (!device) {
44152da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        jniThrowException(env, "java/io/IOException", "Failed to obtain MtpDevice.");
44252da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        return -1;
44352da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    }
44452da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono
44552da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    JavaArrayWriter writer(env, array);
4469c180dd38701a10041537389057b4c0f784907f8Andreas Gampe    uint32_t written_size;
4472dd48256e9657b013dd6fa0ca86d1d7c7c730428Daichi Hirono    const bool success = device->readPartialObject(
4489c180dd38701a10041537389057b4c0f784907f8Andreas Gampe            objectID, offset, size, &written_size, JavaArrayWriter::writeTo, &writer);
4499c180dd38701a10041537389057b4c0f784907f8Andreas Gampe    if (!success) {
45052da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        jniThrowException(env, "java/io/IOException", "Failed to read data.");
45152da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono        return -1;
45252da3ad906afbfc5bc57328985543ebc5f7cdb44Daichi Hirono    }
4532dd48256e9657b013dd6fa0ca86d1d7c7c730428Daichi Hirono    return static_cast<jlong>(written_size);
4548182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
4558182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
456038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hironostatic jint
457038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hironoandroid_mtp_MtpDevice_get_partial_object_64(JNIEnv *env,
458038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                                            jobject thiz,
459038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                                            jint objectID,
460038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                                            jlong offset,
461038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                                            jlong size,
462038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                                            jbyteArray array) {
463038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    if (!array) {
464038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono        jniThrowException(env, "java/lang/IllegalArgumentException", "Array must not be null.");
465038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono        return -1;
466038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    }
467038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono
468038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    if (offset < 0) {
469038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono        jniThrowException(
470038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                env,
471038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                "java/lang/IllegalArgumentException",
472038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                "Offset argument must not be a negative value.");
473038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono        return -1;
474038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    }
475038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono
476038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    if (size < 0 || 0xffffffffL < size) {
477038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono        jniThrowException(
478038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                env,
479038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                "java/lang/IllegalArgumentException",
480038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                "Size argument must be a 32-bit unsigned integer.");
481038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono        return -1;
482038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    }
483038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono
484038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    MtpDevice* const device = get_device_from_object(env, thiz);
485038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    if (!device) {
486038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono        jniThrowException(env, "java/io/IOException", "Failed to obtain MtpDevice.");
487038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono        return -1;
488038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    }
489038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono
490038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    const uint32_t native_object_handle = static_cast<uint32_t>(objectID);
491038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    const uint64_t native_offset = static_cast<uint64_t>(offset);
492038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    const uint32_t native_size = static_cast<uint32_t>(size);
493038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono
494038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    JavaArrayWriter writer(env, array);
495038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    uint32_t written_size;
496038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    const bool success = device->readPartialObject64(
497038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono            native_object_handle,
498038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono            native_offset,
499038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono            native_size,
500038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono            &written_size,
501038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono            JavaArrayWriter::writeTo,
502038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono            &writer);
503038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    if (!success) {
504038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono        jniThrowException(env, "java/io/IOException", "Failed to read data.");
505038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono        return -1;
506038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    }
507038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    return static_cast<jint>(written_size);
508038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono}
509038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono
5108182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jbyteArray
5118182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_get_thumbnail(JNIEnv *env, jobject thiz, jint objectID)
5128182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
5138182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
5148182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (!device)
5158182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
5168182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
5178182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    int length;
5188182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    void* thumbnail = device->getThumbnail(objectID, length);
5198182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (! thumbnail)
5208182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return NULL;
5218182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    jbyteArray array = env->NewByteArray(length);
5228182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    env->SetByteArrayRegion(array, 0, length, (const jbyte *)thumbnail);
5238182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
5248182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    free(thumbnail);
5258182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    return array;
5268182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
5278182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
5288182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jboolean
5298182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_delete_object(JNIEnv *env, jobject thiz, jint object_id)
5308182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
5318182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
532e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    if (device && device->deleteObject(object_id)) {
533e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat        return JNI_TRUE;
534e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    } else {
535e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat        return JNI_FALSE;
536e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    }
5378182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
5388182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
539e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hironostatic jint
5408182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_get_parent(JNIEnv *env, jobject thiz, jint object_id)
5418182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
5428182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
5438182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (device)
544e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono        return static_cast<jint>(device->getParent(object_id));
5458182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    else
5468182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
5478182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
5488182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
549e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hironostatic jint
5508182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_get_storage_id(JNIEnv *env, jobject thiz, jint object_id)
5518182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
5528182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
5538182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (device)
554e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono        return static_cast<jint>(device->getStorageID(object_id));
5558182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    else
5568182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
5578182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
5588182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
5598182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstatic jboolean
5608182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodandroid_mtp_MtpDevice_import_file(JNIEnv *env, jobject thiz, jint object_id, jstring dest_path)
5618182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
5628182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    MtpDevice* device = get_device_from_object(env, thiz);
5638182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (device) {
5648182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        const char *destPathStr = env->GetStringUTFChars(dest_path, NULL);
5653977472d9f3380a8323156dbc7d0090cf2f2d310James Dong        if (destPathStr == NULL) {
566e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat            return JNI_FALSE;
5673977472d9f3380a8323156dbc7d0090cf2f2d310James Dong        }
5683977472d9f3380a8323156dbc7d0090cf2f2d310James Dong
569e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat        jboolean result = device->readObject(object_id, destPathStr, AID_SDCARD_RW, 0664);
5708182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        env->ReleaseStringUTFChars(dest_path, destPathStr);
5718182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return result;
5728182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
573c1b9bbb21c8ad5109978a4e9e770cd18b0257434Mike Lockwood
574e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    return JNI_FALSE;
5758182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
5768182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
57774d4ff8ab389a64cc16ef84dfbbfe6b2b2f34aeaTomasz Mikolajewskistatic jboolean
57874d4ff8ab389a64cc16ef84dfbbfe6b2b2f34aeaTomasz Mikolajewskiandroid_mtp_MtpDevice_import_file_to_fd(JNIEnv *env, jobject thiz, jint object_id, jint fd)
57974d4ff8ab389a64cc16ef84dfbbfe6b2b2f34aeaTomasz Mikolajewski{
58074d4ff8ab389a64cc16ef84dfbbfe6b2b2f34aeaTomasz Mikolajewski    MtpDevice* device = get_device_from_object(env, thiz);
58174d4ff8ab389a64cc16ef84dfbbfe6b2b2f34aeaTomasz Mikolajewski    if (device)
58274d4ff8ab389a64cc16ef84dfbbfe6b2b2f34aeaTomasz Mikolajewski        return device->readObject(object_id, fd);
58374d4ff8ab389a64cc16ef84dfbbfe6b2b2f34aeaTomasz Mikolajewski    else
58474d4ff8ab389a64cc16ef84dfbbfe6b2b2f34aeaTomasz Mikolajewski        return JNI_FALSE;
58574d4ff8ab389a64cc16ef84dfbbfe6b2b2f34aeaTomasz Mikolajewski}
58674d4ff8ab389a64cc16ef84dfbbfe6b2b2f34aeaTomasz Mikolajewski
587b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewskistatic jboolean
588e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hironoandroid_mtp_MtpDevice_send_object(
589e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono        JNIEnv *env, jobject thiz, jint object_id, jlong sizeLong, jint fd)
590b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski{
591e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    uint32_t size;
592e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    if (!check_uint32_arg(env, "size", sizeLong, &size))
593e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono        return JNI_FALSE;
594e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono
595b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    MtpDevice* device = get_device_from_object(env, thiz);
596b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (!device)
597b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        return JNI_FALSE;
598b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
599b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    return device->sendObject(object_id, size, fd);
600b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski}
601b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
602b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewskistatic jobject
603b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewskiandroid_mtp_MtpDevice_send_object_info(JNIEnv *env, jobject thiz, jobject info)
604b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski{
605b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    MtpDevice* device = get_device_from_object(env, thiz);
60687763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski    if (!device) {
607452e8fe55946aba95939d4f5a6e709936ea3df0dDaichi Hirono        return NULL;
60887763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski    }
609b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
610b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    // Updating existing objects is not supported.
61187763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski    if (env->GetIntField(info, field_objectInfo_handle) != -1) {
612452e8fe55946aba95939d4f5a6e709936ea3df0dDaichi Hirono        return NULL;
61387763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski    }
614b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
615b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    MtpObjectInfo* object_info = new MtpObjectInfo(-1);
616b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mStorageID = env->GetIntField(info, field_objectInfo_storageId);
617b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mFormat = env->GetIntField(info, field_objectInfo_format);
618b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mProtectionStatus = env->GetIntField(info, field_objectInfo_protectionStatus);
619b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mCompressedSize = env->GetIntField(info, field_objectInfo_compressedSize);
620b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mThumbFormat = env->GetIntField(info, field_objectInfo_thumbFormat);
621b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mThumbCompressedSize =
622b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski            env->GetIntField(info, field_objectInfo_thumbCompressedSize);
623b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mThumbPixWidth = env->GetIntField(info, field_objectInfo_thumbPixWidth);
624b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mThumbPixHeight = env->GetIntField(info, field_objectInfo_thumbPixHeight);
625b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mImagePixWidth = env->GetIntField(info, field_objectInfo_imagePixWidth);
626b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mImagePixHeight = env->GetIntField(info, field_objectInfo_imagePixHeight);
627b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mImagePixDepth = env->GetIntField(info, field_objectInfo_imagePixDepth);
628b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mParent = env->GetIntField(info, field_objectInfo_parent);
629b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mAssociationType = env->GetIntField(info, field_objectInfo_associationType);
630b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mAssociationDesc = env->GetIntField(info, field_objectInfo_associationDesc);
631b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mSequenceNumber = env->GetIntField(info, field_objectInfo_sequenceNumber);
632b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
633b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    jstring name_jstring = (jstring) env->GetObjectField(info, field_objectInfo_name);
63487763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski    if (name_jstring != NULL) {
63587763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski        const char* name_string = env->GetStringUTFChars(name_jstring, NULL);
63687763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski        object_info->mName = strdup(name_string);
63787763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski        env->ReleaseStringUTFChars(name_jstring, name_string);
63887763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski    }
639b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
640b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mDateCreated = env->GetLongField(info, field_objectInfo_dateCreated) / 1000LL;
641b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mDateModified = env->GetLongField(info, field_objectInfo_dateModified) / 1000LL;
642b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
643b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    jstring keywords_jstring = (jstring) env->GetObjectField(info, field_objectInfo_keywords);
64487763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski    if (keywords_jstring != NULL) {
64587763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski        const char* keywords_string = env->GetStringUTFChars(keywords_jstring, NULL);
64687763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski        object_info->mKeywords = strdup(keywords_string);
64787763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski        env->ReleaseStringUTFChars(keywords_jstring, keywords_string);
64887763e6a91a54e7995cfda9b7e80162f02ac4cbcTomasz Mikolajewski    }
649b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
650b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    int object_handle = device->sendObjectInfo(object_info);
651b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (object_handle == -1) {
652b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        delete object_info;
653b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        return NULL;
654b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    }
655b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
656b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    object_info->mHandle = object_handle;
657b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    jobject result = env->NewObject(clazz_objectInfo, constructor_objectInfo);
658b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    if (result == NULL) {
659b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        ALOGE("Could not create a MtpObjectInfo object");
660b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        delete object_info;
661b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski        return NULL;
662b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    }
663b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
664b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    fill_jobject_from_object_info(env, result, object_info);
665b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    delete object_info;
666b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    return result;
667b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski}
668b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski
6690b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hironostatic jint android_mtp_MtpDevice_submit_event_request(JNIEnv *env, jobject thiz)
6700b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono{
6710b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    MtpDevice* const device = get_device_from_object(env, thiz);
6720b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    if (!device) {
6730b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        env->ThrowNew(clazz_io_exception, "");
6740b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        return -1;
6750b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    }
6760b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    return device->submitEventRequest();
6770b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono}
6780b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono
6790b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hironostatic jobject android_mtp_MtpDevice_reap_event_request(JNIEnv *env, jobject thiz, jint seq)
6800b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono{
6810b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    MtpDevice* const device = get_device_from_object(env, thiz);
6820b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    if (!device) {
6830b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        env->ThrowNew(clazz_io_exception, "");
6840b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        return NULL;
6850b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    }
6862a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    uint32_t parameters[3];
6872a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    const int eventCode = device->reapEventRequest(seq, &parameters);
6880b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    if (eventCode <= 0) {
6890b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        env->ThrowNew(clazz_operation_canceled_exception, "");
6900b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        return NULL;
6910b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    }
6920b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    jobject result = env->NewObject(clazz_event, constructor_event);
6930b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    env->SetIntField(result, field_event_eventCode, eventCode);
6942a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    env->SetIntField(result, field_event_parameter1, static_cast<jint>(parameters[0]));
6952a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    env->SetIntField(result, field_event_parameter2, static_cast<jint>(parameters[1]));
6962a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    env->SetIntField(result, field_event_parameter3, static_cast<jint>(parameters[2]));
6970b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    return result;
6980b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono}
6990b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono
7000b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hironostatic void android_mtp_MtpDevice_discard_event_request(JNIEnv *env, jobject thiz, jint seq)
7010b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono{
7020b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    MtpDevice* const device = get_device_from_object(env, thiz);
7030b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    if (!device) {
7040b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        return;
7050b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    }
7060b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    device->discardEventRequest(seq);
7070b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono}
7080b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono
7091337deb6eac47b9eeef0999a928caba0cfca7126Daichi Hirono// Returns object size in 64-bit integer. If the MTP device does not support the property, it
7101337deb6eac47b9eeef0999a928caba0cfca7126Daichi Hirono// throws IOException.
711787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hironostatic jlong android_mtp_MtpDevice_get_object_size_long(
712787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono        JNIEnv *env, jobject thiz, jint handle, jint format) {
713787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    MtpDevice* const device = get_device_from_object(env, thiz);
714787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    if (!device) {
715787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono        env->ThrowNew(clazz_io_exception, "Failed to obtain MtpDevice.");
716787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono        return 0;
717787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    }
718787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono
719787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    std::unique_ptr<MtpProperty> property(
720787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono            device->getObjectPropDesc(MTP_PROPERTY_OBJECT_SIZE, format));
721787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    if (!property) {
722787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono        env->ThrowNew(clazz_io_exception, "Failed to obtain property desc.");
723787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono        return 0;
724787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    }
725787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono
726787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    if (property->getDataType() != MTP_TYPE_UINT64) {
727787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono        env->ThrowNew(clazz_io_exception, "Unexpected property data type.");
728787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono        return 0;
729787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    }
730787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono
731787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    if (!device->getObjectPropValue(handle, property.get())) {
732787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono        env->ThrowNew(clazz_io_exception, "Failed to obtain property value.");
733787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono        return 0;
734787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    }
735787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono
736787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    const jlong object_size = static_cast<jlong>(property->getCurrentValue().u.u64);
737787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    if (object_size < 0) {
738787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono        env->ThrowNew(clazz_io_exception, "Object size is too large to express as jlong.");
739787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono        return 0;
740787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    }
741787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono
742787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    return object_size;
743787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono}
744787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono
7458182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood// ----------------------------------------------------------------------------
7468182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
74776f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = {
7488182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    {"native_open",             "(Ljava/lang/String;I)Z",
7498182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood                                        (void *)android_mtp_MtpDevice_open},
7508182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    {"native_close",            "()V",  (void *)android_mtp_MtpDevice_close},
7518182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    {"native_get_device_info",  "()Landroid/mtp/MtpDeviceInfo;",
7528182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood                                        (void *)android_mtp_MtpDevice_get_device_info},
7538182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    {"native_get_storage_ids",  "()[I", (void *)android_mtp_MtpDevice_get_storage_ids},
7548182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    {"native_get_storage_info", "(I)Landroid/mtp/MtpStorageInfo;",
7558182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood                                        (void *)android_mtp_MtpDevice_get_storage_info},
7568182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    {"native_get_object_handles","(III)[I",
7578182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood                                        (void *)android_mtp_MtpDevice_get_object_handles},
7588182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    {"native_get_object_info",  "(I)Landroid/mtp/MtpObjectInfo;",
7598182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood                                        (void *)android_mtp_MtpDevice_get_object_info},
760e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    {"native_get_object",       "(IJ)[B",(void *)android_mtp_MtpDevice_get_object},
7612dd48256e9657b013dd6fa0ca86d1d7c7c730428Daichi Hirono    {"native_get_partial_object", "(IJJ[B)J", (void *)android_mtp_MtpDevice_get_partial_object},
762038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono    {"native_get_partial_object_64", "(IJJ[B)I",
763038832b9001f66bd2cbebaf1312a7ada2e512114Daichi Hirono                                        (void *)android_mtp_MtpDevice_get_partial_object_64},
7648182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    {"native_get_thumbnail",    "(I)[B",(void *)android_mtp_MtpDevice_get_thumbnail},
7658182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    {"native_delete_object",    "(I)Z", (void *)android_mtp_MtpDevice_delete_object},
766e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    {"native_get_parent",       "(I)I", (void *)android_mtp_MtpDevice_get_parent},
767e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    {"native_get_storage_id",   "(I)I", (void *)android_mtp_MtpDevice_get_storage_id},
76874d4ff8ab389a64cc16ef84dfbbfe6b2b2f34aeaTomasz Mikolajewski    {"native_import_file",      "(ILjava/lang/String;)Z",
7698182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood                                        (void *)android_mtp_MtpDevice_import_file},
770b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    {"native_import_file",      "(II)Z",(void *)android_mtp_MtpDevice_import_file_to_fd},
771e0e6654a31ad01fe4712dec0358ad95f8d3c8c8dDaichi Hirono    {"native_send_object",      "(IJI)Z",(void *)android_mtp_MtpDevice_send_object},
772b04990599a1a05cc922b0fe9dd98128440efb56aTomasz Mikolajewski    {"native_send_object_info", "(Landroid/mtp/MtpObjectInfo;)Landroid/mtp/MtpObjectInfo;",
7730b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono                                        (void *)android_mtp_MtpDevice_send_object_info},
7740b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    {"native_submit_event_request",  "()I", (void *)android_mtp_MtpDevice_submit_event_request},
7750b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    {"native_reap_event_request",   "(I)Landroid/mtp/MtpEvent;",
7760b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono                                            (void *)android_mtp_MtpDevice_reap_event_request},
7770b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    {"native_discard_event_request", "(I)V", (void *)android_mtp_MtpDevice_discard_event_request},
778787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono
779787821bce4a07f9b9434180210bf99e6bd2639c9Daichi Hirono    {"native_get_object_size_long", "(II)J", (void *)android_mtp_MtpDevice_get_object_size_long},
7808182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood};
7818182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
7828182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodint register_android_mtp_MtpDevice(JNIEnv *env)
7838182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood{
7848182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    jclass clazz;
7858182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
7865baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("register_android_mtp_MtpDevice\n");
7878182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
7888182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    clazz = env->FindClass("android/mtp/MtpDeviceInfo");
7898182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (clazz == NULL) {
7903762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpDeviceInfo");
7918182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
7928182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
7938182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    constructor_deviceInfo = env->GetMethodID(clazz, "<init>", "()V");
7948182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (constructor_deviceInfo == NULL) {
7953762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpDeviceInfo constructor");
7968182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
7978182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
7988182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_deviceInfo_manufacturer = env->GetFieldID(clazz, "mManufacturer", "Ljava/lang/String;");
7998182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_deviceInfo_manufacturer == NULL) {
8003762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpDeviceInfo.mManufacturer");
8018182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8028182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8038182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_deviceInfo_model = env->GetFieldID(clazz, "mModel", "Ljava/lang/String;");
8048182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_deviceInfo_model == NULL) {
8053762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpDeviceInfo.mModel");
8068182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8078182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8088182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_deviceInfo_version = env->GetFieldID(clazz, "mVersion", "Ljava/lang/String;");
8098182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_deviceInfo_version == NULL) {
8103762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpDeviceInfo.mVersion");
8118182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8128182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8138182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_deviceInfo_serialNumber = env->GetFieldID(clazz, "mSerialNumber", "Ljava/lang/String;");
8148182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_deviceInfo_serialNumber == NULL) {
8153762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpDeviceInfo.mSerialNumber");
8168182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8178182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8181d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono    field_deviceInfo_operationsSupported = env->GetFieldID(clazz, "mOperationsSupported", "[I");
8191d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono    if (field_deviceInfo_operationsSupported == NULL) {
8201d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono        ALOGE("Can't find MtpDeviceInfo.mOperationsSupported");
8211d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono        return -1;
8221d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono    }
823148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono    field_deviceInfo_eventsSupported = env->GetFieldID(clazz, "mEventsSupported", "[I");
824148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono    if (field_deviceInfo_eventsSupported == NULL) {
825148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono        ALOGE("Can't find MtpDeviceInfo.mEventsSupported");
826148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono        return -1;
827148954a657941ea95ef17da5b3ce40b9145f8755Daichi Hirono    }
82840304e227247c788d1c0e8d41c386cdb10cba91bMike Lockwood    clazz_deviceInfo = (jclass)env->NewGlobalRef(clazz);
8298182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
8308182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    clazz = env->FindClass("android/mtp/MtpStorageInfo");
8318182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (clazz == NULL) {
8323762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpStorageInfo");
8338182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8348182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8358182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    constructor_storageInfo = env->GetMethodID(clazz, "<init>", "()V");
8368182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (constructor_storageInfo == NULL) {
8373762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpStorageInfo constructor");
8388182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8398182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8408182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_storageInfo_storageId = env->GetFieldID(clazz, "mStorageId", "I");
8418182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_storageInfo_storageId == NULL) {
8423762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpStorageInfo.mStorageId");
8438182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8448182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8458182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_storageInfo_maxCapacity = env->GetFieldID(clazz, "mMaxCapacity", "J");
8468182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_storageInfo_maxCapacity == NULL) {
8473762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpStorageInfo.mMaxCapacity");
8488182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8498182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8508182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_storageInfo_freeSpace = env->GetFieldID(clazz, "mFreeSpace", "J");
8518182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_storageInfo_freeSpace == NULL) {
8523762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpStorageInfo.mFreeSpace");
8538182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8548182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8558182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_storageInfo_description = env->GetFieldID(clazz, "mDescription", "Ljava/lang/String;");
8568182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_storageInfo_description == NULL) {
8573762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpStorageInfo.mDescription");
8588182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8598182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8608182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_storageInfo_volumeIdentifier = env->GetFieldID(clazz, "mVolumeIdentifier", "Ljava/lang/String;");
8618182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_storageInfo_volumeIdentifier == NULL) {
8623762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpStorageInfo.mVolumeIdentifier");
8638182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8648182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
86540304e227247c788d1c0e8d41c386cdb10cba91bMike Lockwood    clazz_storageInfo = (jclass)env->NewGlobalRef(clazz);
8668182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
8678182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    clazz = env->FindClass("android/mtp/MtpObjectInfo");
8688182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (clazz == NULL) {
8693762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpObjectInfo");
8708182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8718182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8728182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    constructor_objectInfo = env->GetMethodID(clazz, "<init>", "()V");
8738182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (constructor_objectInfo == NULL) {
8743762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpObjectInfo constructor");
8758182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8768182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8778182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_handle = env->GetFieldID(clazz, "mHandle", "I");
8788182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_handle == NULL) {
8793762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mHandle");
8808182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8818182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8828182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_storageId = env->GetFieldID(clazz, "mStorageId", "I");
8838182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_storageId == NULL) {
8843762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mStorageId");
8858182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8868182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8878182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_format = env->GetFieldID(clazz, "mFormat", "I");
8888182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_format == NULL) {
8893762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mFormat");
8908182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8918182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8928182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_protectionStatus = env->GetFieldID(clazz, "mProtectionStatus", "I");
8938182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_protectionStatus == NULL) {
8943762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mProtectionStatus");
8958182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
8968182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
8978182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_compressedSize = env->GetFieldID(clazz, "mCompressedSize", "I");
8988182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_compressedSize == NULL) {
8993762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mCompressedSize");
9008182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9018182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9028182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_thumbFormat = env->GetFieldID(clazz, "mThumbFormat", "I");
9038182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_thumbFormat == NULL) {
9043762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mThumbFormat");
9058182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9068182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9078182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_thumbCompressedSize = env->GetFieldID(clazz, "mThumbCompressedSize", "I");
9088182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_thumbCompressedSize == NULL) {
9093762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mThumbCompressedSize");
9108182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9118182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9128182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_thumbPixWidth = env->GetFieldID(clazz, "mThumbPixWidth", "I");
9138182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_thumbPixWidth == NULL) {
9143762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mThumbPixWidth");
9158182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9168182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9178182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_thumbPixHeight = env->GetFieldID(clazz, "mThumbPixHeight", "I");
9188182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_thumbPixHeight == NULL) {
9193762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mThumbPixHeight");
9208182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9218182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9228182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_imagePixWidth = env->GetFieldID(clazz, "mImagePixWidth", "I");
9238182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_imagePixWidth == NULL) {
9243762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mImagePixWidth");
9258182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9268182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9278182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_imagePixHeight = env->GetFieldID(clazz, "mImagePixHeight", "I");
9288182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_imagePixHeight == NULL) {
9293762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mImagePixHeight");
9308182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9318182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9328182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_imagePixDepth = env->GetFieldID(clazz, "mImagePixDepth", "I");
9338182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_imagePixDepth == NULL) {
9343762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mImagePixDepth");
9358182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9368182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9378182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_parent = env->GetFieldID(clazz, "mParent", "I");
9388182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_parent == NULL) {
9393762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mParent");
9408182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9418182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9428182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_associationType = env->GetFieldID(clazz, "mAssociationType", "I");
9438182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_associationType == NULL) {
9443762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mAssociationType");
9458182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9468182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9478182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_associationDesc = env->GetFieldID(clazz, "mAssociationDesc", "I");
9488182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_associationDesc == NULL) {
9493762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mAssociationDesc");
9508182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9518182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9528182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_sequenceNumber = env->GetFieldID(clazz, "mSequenceNumber", "I");
9538182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_sequenceNumber == NULL) {
9543762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mSequenceNumber");
9558182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9568182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9578182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_name = env->GetFieldID(clazz, "mName", "Ljava/lang/String;");
9588182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_name == NULL) {
9593762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mName");
9608182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9618182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9628182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_dateCreated = env->GetFieldID(clazz, "mDateCreated", "J");
9638182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_dateCreated == NULL) {
9643762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mDateCreated");
9658182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9668182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9678182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_dateModified = env->GetFieldID(clazz, "mDateModified", "J");
9688182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_dateModified == NULL) {
9693762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mDateModified");
9708182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9718182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
9728182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    field_objectInfo_keywords = env->GetFieldID(clazz, "mKeywords", "Ljava/lang/String;");
9738182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_objectInfo_keywords == NULL) {
9743762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpObjectInfo.mKeywords");
9758182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
9768182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
97740304e227247c788d1c0e8d41c386cdb10cba91bMike Lockwood    clazz_objectInfo = (jclass)env->NewGlobalRef(clazz);
9788182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
9790b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    clazz = env->FindClass("android/mtp/MtpEvent");
9800b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    if (clazz == NULL) {
9810b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        ALOGE("Can't find android/mtp/MtpEvent");
9820b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        return -1;
9830b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    }
9840b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    constructor_event = env->GetMethodID(clazz, "<init>", "()V");
9850b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    if (constructor_event == NULL) {
9860b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        ALOGE("Can't find android/mtp/MtpEvent constructor");
9870b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        return -1;
9880b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    }
9890b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    field_event_eventCode = env->GetFieldID(clazz, "mEventCode", "I");
9900b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    if (field_event_eventCode == NULL) {
9910b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        ALOGE("Can't find MtpObjectInfo.mEventCode");
9920b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        return -1;
9930b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    }
9942a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    field_event_parameter1 = env->GetFieldID(clazz, "mParameter1", "I");
9952a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    if (field_event_parameter1 == NULL) {
9962a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono        ALOGE("Can't find MtpObjectInfo.mParameter1");
9972a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono        return -1;
9982a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    }
9992a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    field_event_parameter2 = env->GetFieldID(clazz, "mParameter2", "I");
10002a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    if (field_event_parameter2 == NULL) {
10012a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono        ALOGE("Can't find MtpObjectInfo.mParameter2");
10022a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono        return -1;
10032a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    }
10042a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    field_event_parameter3 = env->GetFieldID(clazz, "mParameter3", "I");
10052a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    if (field_event_parameter3 == NULL) {
10062a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono        ALOGE("Can't find MtpObjectInfo.mParameter3");
10072a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono        return -1;
10082a9a43369b4717bcf6b372f6798f72e80e938e30Daichi Hirono    }
10090b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    clazz_event = (jclass)env->NewGlobalRef(clazz);
10100b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono
10118182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    clazz = env->FindClass("android/mtp/MtpDevice");
10128182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (clazz == NULL) {
10133762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpDevice");
10148182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
10158182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
1016e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat    field_context = env->GetFieldID(clazz, "mNativeContext", "J");
10178182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    if (field_context == NULL) {
10183762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpDevice.mNativeContext");
10198182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood        return -1;
10208182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    }
10210b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    clazz = env->FindClass("java/io/IOException");
10220b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    if (clazz == NULL) {
10230b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        ALOGE("Can't find java.io.IOException");
10240b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        return -1;
10250b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    }
10260b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    clazz_io_exception = (jclass)env->NewGlobalRef(clazz);
10270b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    clazz = env->FindClass("android/os/OperationCanceledException");
10280b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    if (clazz == NULL) {
10290b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        ALOGE("Can't find android.os.OperationCanceledException");
10300b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono        return -1;
10310b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    }
10320b494663a4cb177fc6f05988c9bda2ef6277333dDaichi Hirono    clazz_operation_canceled_exception = (jclass)env->NewGlobalRef(clazz);
10338182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood
10348182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood    return AndroidRuntime::registerNativeMethods(env,
10358182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood                "android/mtp/MtpDevice", gMethods, NELEM(gMethods));
10368182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}
1037