android_mtp_MtpDevice.cpp revision 3977472d9f3380a8323156dbc7d0090cf2f2d310
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// #define LOG_NDEBUG 0 18 19#define LOG_TAG "MtpDeviceJNI" 20#include "utils/Log.h" 21 22#include <stdio.h> 23#include <assert.h> 24#include <limits.h> 25#include <unistd.h> 26#include <fcntl.h> 27 28#include "jni.h" 29#include "JNIHelp.h" 30#include "android_runtime/AndroidRuntime.h" 31#include "private/android_filesystem_config.h" 32 33#include "MtpTypes.h" 34#include "MtpDevice.h" 35#include "MtpDeviceInfo.h" 36#include "MtpStorageInfo.h" 37#include "MtpObjectInfo.h" 38 39using namespace android; 40 41// ---------------------------------------------------------------------------- 42 43static jfieldID field_context; 44 45jclass clazz_deviceInfo; 46jclass clazz_storageInfo; 47jclass clazz_objectInfo; 48 49jmethodID constructor_deviceInfo; 50jmethodID constructor_storageInfo; 51jmethodID constructor_objectInfo; 52 53// MtpDeviceInfo fields 54static jfieldID field_deviceInfo_manufacturer; 55static jfieldID field_deviceInfo_model; 56static jfieldID field_deviceInfo_version; 57static jfieldID field_deviceInfo_serialNumber; 58 59// MtpStorageInfo fields 60static jfieldID field_storageInfo_storageId; 61static jfieldID field_storageInfo_maxCapacity; 62static jfieldID field_storageInfo_freeSpace; 63static jfieldID field_storageInfo_description; 64static jfieldID field_storageInfo_volumeIdentifier; 65 66// MtpObjectInfo fields 67static jfieldID field_objectInfo_handle; 68static jfieldID field_objectInfo_storageId; 69static jfieldID field_objectInfo_format; 70static jfieldID field_objectInfo_protectionStatus; 71static jfieldID field_objectInfo_compressedSize; 72static jfieldID field_objectInfo_thumbFormat; 73static jfieldID field_objectInfo_thumbCompressedSize; 74static jfieldID field_objectInfo_thumbPixWidth; 75static jfieldID field_objectInfo_thumbPixHeight; 76static jfieldID field_objectInfo_imagePixWidth; 77static jfieldID field_objectInfo_imagePixHeight; 78static jfieldID field_objectInfo_imagePixDepth; 79static jfieldID field_objectInfo_parent; 80static jfieldID field_objectInfo_associationType; 81static jfieldID field_objectInfo_associationDesc; 82static jfieldID field_objectInfo_sequenceNumber; 83static jfieldID field_objectInfo_name; 84static jfieldID field_objectInfo_dateCreated; 85static jfieldID field_objectInfo_dateModified; 86static jfieldID field_objectInfo_keywords; 87 88#ifdef HAVE_ANDROID_OS 89 90MtpDevice* get_device_from_object(JNIEnv* env, jobject javaDevice) 91{ 92 return (MtpDevice*)env->GetIntField(javaDevice, field_context); 93} 94 95static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { 96 if (env->ExceptionCheck()) { 97 LOGE("An exception was thrown by callback '%s'.", methodName); 98 LOGE_EX(env); 99 env->ExceptionClear(); 100 } 101} 102 103#endif // HAVE_ANDROID_OS 104 105// ---------------------------------------------------------------------------- 106 107static jboolean 108android_mtp_MtpDevice_open(JNIEnv *env, jobject thiz, jstring deviceName, jint fd) 109{ 110#ifdef HAVE_ANDROID_OS 111 LOGD("open\n"); 112 const char *deviceNameStr = env->GetStringUTFChars(deviceName, NULL); 113 if (deviceNameStr == NULL) { 114 return false; 115 } 116 117 MtpDevice* device = MtpDevice::open(deviceNameStr, fd); 118 env->ReleaseStringUTFChars(deviceName, deviceNameStr); 119 120 if (device) 121 env->SetIntField(thiz, field_context, (int)device); 122 return (device != NULL); 123#endif 124} 125 126static void 127android_mtp_MtpDevice_close(JNIEnv *env, jobject thiz) 128{ 129#ifdef HAVE_ANDROID_OS 130 LOGD("close\n"); 131 MtpDevice* device = get_device_from_object(env, thiz); 132 if (device) { 133 device->close(); 134 delete device; 135 env->SetIntField(thiz, field_context, 0); 136 } 137#endif 138} 139 140static jobject 141android_mtp_MtpDevice_get_device_info(JNIEnv *env, jobject thiz) 142{ 143#ifdef HAVE_ANDROID_OS 144 MtpDevice* device = get_device_from_object(env, thiz); 145 if (!device) { 146 LOGD("android_mtp_MtpDevice_get_device_info device is null"); 147 return NULL; 148 } 149 MtpDeviceInfo* deviceInfo = device->getDeviceInfo(); 150 if (!deviceInfo) { 151 LOGD("android_mtp_MtpDevice_get_device_info deviceInfo is null"); 152 return NULL; 153 } 154 jobject info = env->NewObject(clazz_deviceInfo, constructor_deviceInfo); 155 if (info == NULL) { 156 LOGE("Could not create a MtpDeviceInfo object"); 157 delete deviceInfo; 158 return NULL; 159 } 160 161 if (deviceInfo->mManufacturer) 162 env->SetObjectField(info, field_deviceInfo_manufacturer, 163 env->NewStringUTF(deviceInfo->mManufacturer)); 164 if (deviceInfo->mModel) 165 env->SetObjectField(info, field_deviceInfo_model, 166 env->NewStringUTF(deviceInfo->mModel)); 167 if (deviceInfo->mVersion) 168 env->SetObjectField(info, field_deviceInfo_version, 169 env->NewStringUTF(deviceInfo->mVersion)); 170 if (deviceInfo->mSerial) 171 env->SetObjectField(info, field_deviceInfo_serialNumber, 172 env->NewStringUTF(deviceInfo->mSerial)); 173 174 delete deviceInfo; 175 return info; 176#else 177 return NULL; 178#endif 179} 180 181static jintArray 182android_mtp_MtpDevice_get_storage_ids(JNIEnv *env, jobject thiz) 183{ 184#ifdef HAVE_ANDROID_OS 185 MtpDevice* device = get_device_from_object(env, thiz); 186 if (!device) 187 return NULL; 188 MtpStorageIDList* storageIDs = device->getStorageIDs(); 189 if (!storageIDs) 190 return NULL; 191 192 int length = storageIDs->size(); 193 jintArray array = env->NewIntArray(length); 194 // FIXME is this cast safe? 195 env->SetIntArrayRegion(array, 0, length, (const jint *)storageIDs->array()); 196 197 delete storageIDs; 198 return array; 199#else 200 return NULL; 201#endif 202} 203 204static jobject 205android_mtp_MtpDevice_get_storage_info(JNIEnv *env, jobject thiz, jint storageID) 206{ 207#ifdef HAVE_ANDROID_OS 208 MtpDevice* device = get_device_from_object(env, thiz); 209 if (!device) 210 return NULL; 211 MtpStorageInfo* storageInfo = device->getStorageInfo(storageID); 212 if (!storageInfo) 213 return NULL; 214 215 jobject info = env->NewObject(clazz_storageInfo, constructor_storageInfo); 216 if (info == NULL) { 217 LOGE("Could not create a MtpStorageInfo object"); 218 delete storageInfo; 219 return NULL; 220 } 221 222 if (storageInfo->mStorageID) 223 env->SetIntField(info, field_storageInfo_storageId, storageInfo->mStorageID); 224 if (storageInfo->mMaxCapacity) 225 env->SetLongField(info, field_storageInfo_maxCapacity, storageInfo->mMaxCapacity); 226 if (storageInfo->mFreeSpaceBytes) 227 env->SetLongField(info, field_storageInfo_freeSpace, storageInfo->mFreeSpaceBytes); 228 if (storageInfo->mStorageDescription) 229 env->SetObjectField(info, field_storageInfo_description, 230 env->NewStringUTF(storageInfo->mStorageDescription)); 231 if (storageInfo->mVolumeIdentifier) 232 env->SetObjectField(info, field_storageInfo_volumeIdentifier, 233 env->NewStringUTF(storageInfo->mVolumeIdentifier)); 234 235 delete storageInfo; 236 return info; 237#else 238 return NULL; 239#endif 240} 241 242static jintArray 243android_mtp_MtpDevice_get_object_handles(JNIEnv *env, jobject thiz, 244 jint storageID, jint format, jint objectID) 245{ 246#ifdef HAVE_ANDROID_OS 247 MtpDevice* device = get_device_from_object(env, thiz); 248 if (!device) 249 return NULL; 250 MtpObjectHandleList* handles = device->getObjectHandles(storageID, format, objectID); 251 if (!handles) 252 return NULL; 253 254 int length = handles->size(); 255 jintArray array = env->NewIntArray(length); 256 // FIXME is this cast safe? 257 env->SetIntArrayRegion(array, 0, length, (const jint *)handles->array()); 258 259 delete handles; 260 return array; 261#else 262 return NULL; 263#endif 264} 265 266static jobject 267android_mtp_MtpDevice_get_object_info(JNIEnv *env, jobject thiz, jint objectID) 268{ 269#ifdef HAVE_ANDROID_OS 270 MtpDevice* device = get_device_from_object(env, thiz); 271 if (!device) 272 return NULL; 273 MtpObjectInfo* objectInfo = device->getObjectInfo(objectID); 274 if (!objectInfo) 275 return NULL; 276 jobject info = env->NewObject(clazz_objectInfo, constructor_objectInfo); 277 if (info == NULL) { 278 LOGE("Could not create a MtpObjectInfo object"); 279 delete objectInfo; 280 return NULL; 281 } 282 283 if (objectInfo->mHandle) 284 env->SetIntField(info, field_objectInfo_handle, objectInfo->mHandle); 285 if (objectInfo->mStorageID) 286 env->SetIntField(info, field_objectInfo_storageId, objectInfo->mStorageID); 287 if (objectInfo->mFormat) 288 env->SetIntField(info, field_objectInfo_format, objectInfo->mFormat); 289 if (objectInfo->mProtectionStatus) 290 env->SetIntField(info, field_objectInfo_protectionStatus, objectInfo->mProtectionStatus); 291 if (objectInfo->mCompressedSize) 292 env->SetIntField(info, field_objectInfo_compressedSize, objectInfo->mCompressedSize); 293 if (objectInfo->mThumbFormat) 294 env->SetIntField(info, field_objectInfo_thumbFormat, objectInfo->mThumbFormat); 295 if (objectInfo->mThumbCompressedSize) 296 env->SetIntField(info, field_objectInfo_thumbCompressedSize, objectInfo->mThumbCompressedSize); 297 if (objectInfo->mThumbPixWidth) 298 env->SetIntField(info, field_objectInfo_thumbPixWidth, objectInfo->mThumbPixWidth); 299 if (objectInfo->mThumbPixHeight) 300 env->SetIntField(info, field_objectInfo_thumbPixHeight, objectInfo->mThumbPixHeight); 301 if (objectInfo->mImagePixWidth) 302 env->SetIntField(info, field_objectInfo_imagePixWidth, objectInfo->mImagePixWidth); 303 if (objectInfo->mImagePixHeight) 304 env->SetIntField(info, field_objectInfo_imagePixHeight, objectInfo->mImagePixHeight); 305 if (objectInfo->mImagePixDepth) 306 env->SetIntField(info, field_objectInfo_imagePixDepth, objectInfo->mImagePixDepth); 307 if (objectInfo->mParent) 308 env->SetIntField(info, field_objectInfo_parent, objectInfo->mParent); 309 if (objectInfo->mAssociationType) 310 env->SetIntField(info, field_objectInfo_associationType, objectInfo->mAssociationType); 311 if (objectInfo->mAssociationDesc) 312 env->SetIntField(info, field_objectInfo_associationDesc, objectInfo->mAssociationDesc); 313 if (objectInfo->mSequenceNumber) 314 env->SetIntField(info, field_objectInfo_sequenceNumber, objectInfo->mSequenceNumber); 315 if (objectInfo->mName) 316 env->SetObjectField(info, field_objectInfo_name, env->NewStringUTF(objectInfo->mName)); 317 if (objectInfo->mDateCreated) 318 env->SetLongField(info, field_objectInfo_dateCreated, objectInfo->mDateCreated * 1000LL); 319 if (objectInfo->mDateModified) 320 env->SetLongField(info, field_objectInfo_dateModified, objectInfo->mDateModified * 1000LL); 321 if (objectInfo->mKeywords) 322 env->SetObjectField(info, field_objectInfo_keywords, 323 env->NewStringUTF(objectInfo->mKeywords)); 324 325 delete objectInfo; 326 return info; 327#else 328 return NULL; 329#endif 330} 331 332struct get_object_callback_data { 333 JNIEnv *env; 334 jbyteArray array; 335}; 336 337static bool get_object_callback(void* data, int offset, int length, void* clientData) 338{ 339 get_object_callback_data* cbData = (get_object_callback_data *)clientData; 340 cbData->env->SetByteArrayRegion(cbData->array, offset, length, (jbyte *)data); 341 return true; 342} 343 344static jbyteArray 345android_mtp_MtpDevice_get_object(JNIEnv *env, jobject thiz, jint objectID, jint objectSize) 346{ 347#ifdef HAVE_ANDROID_OS 348 MtpDevice* device = get_device_from_object(env, thiz); 349 if (!device) 350 return NULL; 351 352 jbyteArray array = env->NewByteArray(objectSize); 353 if (!array) { 354 jniThrowException(env, "java/lang/OutOfMemoryError", NULL); 355 return NULL; 356 } 357 358 get_object_callback_data data; 359 data.env = env; 360 data.array = array; 361 362 if (device->readObject(objectID, get_object_callback, objectSize, &data)) 363 return array; 364#endif 365 return NULL; 366} 367 368static jbyteArray 369android_mtp_MtpDevice_get_thumbnail(JNIEnv *env, jobject thiz, jint objectID) 370{ 371#ifdef HAVE_ANDROID_OS 372 MtpDevice* device = get_device_from_object(env, thiz); 373 if (!device) 374 return NULL; 375 376 int length; 377 void* thumbnail = device->getThumbnail(objectID, length); 378 if (! thumbnail) 379 return NULL; 380 jbyteArray array = env->NewByteArray(length); 381 env->SetByteArrayRegion(array, 0, length, (const jbyte *)thumbnail); 382 383 free(thumbnail); 384 return array; 385#else 386 return NULL; 387#endif 388} 389 390static jboolean 391android_mtp_MtpDevice_delete_object(JNIEnv *env, jobject thiz, jint object_id) 392{ 393#ifdef HAVE_ANDROID_OS 394 MtpDevice* device = get_device_from_object(env, thiz); 395 if (device) 396 return device->deleteObject(object_id); 397 else 398 #endif 399 return NULL; 400} 401 402static jlong 403android_mtp_MtpDevice_get_parent(JNIEnv *env, jobject thiz, jint object_id) 404{ 405#ifdef HAVE_ANDROID_OS 406 MtpDevice* device = get_device_from_object(env, thiz); 407 if (device) 408 return device->getParent(object_id); 409 else 410#endif 411 return -1; 412} 413 414static jlong 415android_mtp_MtpDevice_get_storage_id(JNIEnv *env, jobject thiz, jint object_id) 416{ 417 #ifdef HAVE_ANDROID_OS 418 MtpDevice* device = get_device_from_object(env, thiz); 419 if (device) 420 return device->getStorageID(object_id); 421 else 422#endif 423 return -1; 424} 425 426static jboolean 427android_mtp_MtpDevice_import_file(JNIEnv *env, jobject thiz, jint object_id, jstring dest_path) 428{ 429#ifdef HAVE_ANDROID_OS 430 MtpDevice* device = get_device_from_object(env, thiz); 431 if (device) { 432 const char *destPathStr = env->GetStringUTFChars(dest_path, NULL); 433 if (destPathStr == NULL) { 434 return false; 435 } 436 437 bool result = device->readObject(object_id, destPathStr, AID_SDCARD_RW, 0664); 438 env->ReleaseStringUTFChars(dest_path, destPathStr); 439 return result; 440 } 441#endif 442 return false; 443} 444 445// ---------------------------------------------------------------------------- 446 447static JNINativeMethod gMethods[] = { 448 {"native_open", "(Ljava/lang/String;I)Z", 449 (void *)android_mtp_MtpDevice_open}, 450 {"native_close", "()V", (void *)android_mtp_MtpDevice_close}, 451 {"native_get_device_info", "()Landroid/mtp/MtpDeviceInfo;", 452 (void *)android_mtp_MtpDevice_get_device_info}, 453 {"native_get_storage_ids", "()[I", (void *)android_mtp_MtpDevice_get_storage_ids}, 454 {"native_get_storage_info", "(I)Landroid/mtp/MtpStorageInfo;", 455 (void *)android_mtp_MtpDevice_get_storage_info}, 456 {"native_get_object_handles","(III)[I", 457 (void *)android_mtp_MtpDevice_get_object_handles}, 458 {"native_get_object_info", "(I)Landroid/mtp/MtpObjectInfo;", 459 (void *)android_mtp_MtpDevice_get_object_info}, 460 {"native_get_object", "(II)[B",(void *)android_mtp_MtpDevice_get_object}, 461 {"native_get_thumbnail", "(I)[B",(void *)android_mtp_MtpDevice_get_thumbnail}, 462 {"native_delete_object", "(I)Z", (void *)android_mtp_MtpDevice_delete_object}, 463 {"native_get_parent", "(I)J", (void *)android_mtp_MtpDevice_get_parent}, 464 {"native_get_storage_id", "(I)J", (void *)android_mtp_MtpDevice_get_storage_id}, 465 {"native_import_file", "(ILjava/lang/String;)Z", 466 (void *)android_mtp_MtpDevice_import_file}, 467}; 468 469static const char* const kClassPathName = "android/mtp/MtpDevice"; 470 471int register_android_mtp_MtpDevice(JNIEnv *env) 472{ 473 jclass clazz; 474 475 LOGD("register_android_mtp_MtpDevice\n"); 476 477 clazz = env->FindClass("android/mtp/MtpDeviceInfo"); 478 if (clazz == NULL) { 479 LOGE("Can't find android/mtp/MtpDeviceInfo"); 480 return -1; 481 } 482 constructor_deviceInfo = env->GetMethodID(clazz, "<init>", "()V"); 483 if (constructor_deviceInfo == NULL) { 484 LOGE("Can't find android/mtp/MtpDeviceInfo constructor"); 485 return -1; 486 } 487 field_deviceInfo_manufacturer = env->GetFieldID(clazz, "mManufacturer", "Ljava/lang/String;"); 488 if (field_deviceInfo_manufacturer == NULL) { 489 LOGE("Can't find MtpDeviceInfo.mManufacturer"); 490 return -1; 491 } 492 field_deviceInfo_model = env->GetFieldID(clazz, "mModel", "Ljava/lang/String;"); 493 if (field_deviceInfo_model == NULL) { 494 LOGE("Can't find MtpDeviceInfo.mModel"); 495 return -1; 496 } 497 field_deviceInfo_version = env->GetFieldID(clazz, "mVersion", "Ljava/lang/String;"); 498 if (field_deviceInfo_version == NULL) { 499 LOGE("Can't find MtpDeviceInfo.mVersion"); 500 return -1; 501 } 502 field_deviceInfo_serialNumber = env->GetFieldID(clazz, "mSerialNumber", "Ljava/lang/String;"); 503 if (field_deviceInfo_serialNumber == NULL) { 504 LOGE("Can't find MtpDeviceInfo.mSerialNumber"); 505 return -1; 506 } 507 clazz_deviceInfo = (jclass)env->NewGlobalRef(clazz); 508 509 clazz = env->FindClass("android/mtp/MtpStorageInfo"); 510 if (clazz == NULL) { 511 LOGE("Can't find android/mtp/MtpStorageInfo"); 512 return -1; 513 } 514 constructor_storageInfo = env->GetMethodID(clazz, "<init>", "()V"); 515 if (constructor_storageInfo == NULL) { 516 LOGE("Can't find android/mtp/MtpStorageInfo constructor"); 517 return -1; 518 } 519 field_storageInfo_storageId = env->GetFieldID(clazz, "mStorageId", "I"); 520 if (field_storageInfo_storageId == NULL) { 521 LOGE("Can't find MtpStorageInfo.mStorageId"); 522 return -1; 523 } 524 field_storageInfo_maxCapacity = env->GetFieldID(clazz, "mMaxCapacity", "J"); 525 if (field_storageInfo_maxCapacity == NULL) { 526 LOGE("Can't find MtpStorageInfo.mMaxCapacity"); 527 return -1; 528 } 529 field_storageInfo_freeSpace = env->GetFieldID(clazz, "mFreeSpace", "J"); 530 if (field_storageInfo_freeSpace == NULL) { 531 LOGE("Can't find MtpStorageInfo.mFreeSpace"); 532 return -1; 533 } 534 field_storageInfo_description = env->GetFieldID(clazz, "mDescription", "Ljava/lang/String;"); 535 if (field_storageInfo_description == NULL) { 536 LOGE("Can't find MtpStorageInfo.mDescription"); 537 return -1; 538 } 539 field_storageInfo_volumeIdentifier = env->GetFieldID(clazz, "mVolumeIdentifier", "Ljava/lang/String;"); 540 if (field_storageInfo_volumeIdentifier == NULL) { 541 LOGE("Can't find MtpStorageInfo.mVolumeIdentifier"); 542 return -1; 543 } 544 clazz_storageInfo = (jclass)env->NewGlobalRef(clazz); 545 546 clazz = env->FindClass("android/mtp/MtpObjectInfo"); 547 if (clazz == NULL) { 548 LOGE("Can't find android/mtp/MtpObjectInfo"); 549 return -1; 550 } 551 constructor_objectInfo = env->GetMethodID(clazz, "<init>", "()V"); 552 if (constructor_objectInfo == NULL) { 553 LOGE("Can't find android/mtp/MtpObjectInfo constructor"); 554 return -1; 555 } 556 field_objectInfo_handle = env->GetFieldID(clazz, "mHandle", "I"); 557 if (field_objectInfo_handle == NULL) { 558 LOGE("Can't find MtpObjectInfo.mHandle"); 559 return -1; 560 } 561 field_objectInfo_storageId = env->GetFieldID(clazz, "mStorageId", "I"); 562 if (field_objectInfo_storageId == NULL) { 563 LOGE("Can't find MtpObjectInfo.mStorageId"); 564 return -1; 565 } 566 field_objectInfo_format = env->GetFieldID(clazz, "mFormat", "I"); 567 if (field_objectInfo_format == NULL) { 568 LOGE("Can't find MtpObjectInfo.mFormat"); 569 return -1; 570 } 571 field_objectInfo_protectionStatus = env->GetFieldID(clazz, "mProtectionStatus", "I"); 572 if (field_objectInfo_protectionStatus == NULL) { 573 LOGE("Can't find MtpObjectInfo.mProtectionStatus"); 574 return -1; 575 } 576 field_objectInfo_compressedSize = env->GetFieldID(clazz, "mCompressedSize", "I"); 577 if (field_objectInfo_compressedSize == NULL) { 578 LOGE("Can't find MtpObjectInfo.mCompressedSize"); 579 return -1; 580 } 581 field_objectInfo_thumbFormat = env->GetFieldID(clazz, "mThumbFormat", "I"); 582 if (field_objectInfo_thumbFormat == NULL) { 583 LOGE("Can't find MtpObjectInfo.mThumbFormat"); 584 return -1; 585 } 586 field_objectInfo_thumbCompressedSize = env->GetFieldID(clazz, "mThumbCompressedSize", "I"); 587 if (field_objectInfo_thumbCompressedSize == NULL) { 588 LOGE("Can't find MtpObjectInfo.mThumbCompressedSize"); 589 return -1; 590 } 591 field_objectInfo_thumbPixWidth = env->GetFieldID(clazz, "mThumbPixWidth", "I"); 592 if (field_objectInfo_thumbPixWidth == NULL) { 593 LOGE("Can't find MtpObjectInfo.mThumbPixWidth"); 594 return -1; 595 } 596 field_objectInfo_thumbPixHeight = env->GetFieldID(clazz, "mThumbPixHeight", "I"); 597 if (field_objectInfo_thumbPixHeight == NULL) { 598 LOGE("Can't find MtpObjectInfo.mThumbPixHeight"); 599 return -1; 600 } 601 field_objectInfo_imagePixWidth = env->GetFieldID(clazz, "mImagePixWidth", "I"); 602 if (field_objectInfo_imagePixWidth == NULL) { 603 LOGE("Can't find MtpObjectInfo.mImagePixWidth"); 604 return -1; 605 } 606 field_objectInfo_imagePixHeight = env->GetFieldID(clazz, "mImagePixHeight", "I"); 607 if (field_objectInfo_imagePixHeight == NULL) { 608 LOGE("Can't find MtpObjectInfo.mImagePixHeight"); 609 return -1; 610 } 611 field_objectInfo_imagePixDepth = env->GetFieldID(clazz, "mImagePixDepth", "I"); 612 if (field_objectInfo_imagePixDepth == NULL) { 613 LOGE("Can't find MtpObjectInfo.mImagePixDepth"); 614 return -1; 615 } 616 field_objectInfo_parent = env->GetFieldID(clazz, "mParent", "I"); 617 if (field_objectInfo_parent == NULL) { 618 LOGE("Can't find MtpObjectInfo.mParent"); 619 return -1; 620 } 621 field_objectInfo_associationType = env->GetFieldID(clazz, "mAssociationType", "I"); 622 if (field_objectInfo_associationType == NULL) { 623 LOGE("Can't find MtpObjectInfo.mAssociationType"); 624 return -1; 625 } 626 field_objectInfo_associationDesc = env->GetFieldID(clazz, "mAssociationDesc", "I"); 627 if (field_objectInfo_associationDesc == NULL) { 628 LOGE("Can't find MtpObjectInfo.mAssociationDesc"); 629 return -1; 630 } 631 field_objectInfo_sequenceNumber = env->GetFieldID(clazz, "mSequenceNumber", "I"); 632 if (field_objectInfo_sequenceNumber == NULL) { 633 LOGE("Can't find MtpObjectInfo.mSequenceNumber"); 634 return -1; 635 } 636 field_objectInfo_name = env->GetFieldID(clazz, "mName", "Ljava/lang/String;"); 637 if (field_objectInfo_name == NULL) { 638 LOGE("Can't find MtpObjectInfo.mName"); 639 return -1; 640 } 641 field_objectInfo_dateCreated = env->GetFieldID(clazz, "mDateCreated", "J"); 642 if (field_objectInfo_dateCreated == NULL) { 643 LOGE("Can't find MtpObjectInfo.mDateCreated"); 644 return -1; 645 } 646 field_objectInfo_dateModified = env->GetFieldID(clazz, "mDateModified", "J"); 647 if (field_objectInfo_dateModified == NULL) { 648 LOGE("Can't find MtpObjectInfo.mDateModified"); 649 return -1; 650 } 651 field_objectInfo_keywords = env->GetFieldID(clazz, "mKeywords", "Ljava/lang/String;"); 652 if (field_objectInfo_keywords == NULL) { 653 LOGE("Can't find MtpObjectInfo.mKeywords"); 654 return -1; 655 } 656 clazz_objectInfo = (jclass)env->NewGlobalRef(clazz); 657 658 clazz = env->FindClass("android/mtp/MtpDevice"); 659 if (clazz == NULL) { 660 LOGE("Can't find android/mtp/MtpDevice"); 661 return -1; 662 } 663 field_context = env->GetFieldID(clazz, "mNativeContext", "I"); 664 if (field_context == NULL) { 665 LOGE("Can't find MtpDevice.mNativeContext"); 666 return -1; 667 } 668 669 return AndroidRuntime::registerNativeMethods(env, 670 "android/mtp/MtpDevice", gMethods, NELEM(gMethods)); 671} 672