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