diff options
author | Mike Lockwood <lockwood@android.com> | 2010-07-26 20:40:45 -0400 |
---|---|---|
committer | Mike Lockwood <lockwood@android.com> | 2010-07-26 20:40:45 -0400 |
commit | bc4cb0bc79c0d366d6866fe4054a71e00d169ff9 (patch) | |
tree | 575e35759dcc1ae6a6e6efab1960d57d73f7a426 /media/jni | |
parent | f78b26a572e3ba5d47009f3a810a15e252b5503c (diff) | |
download | frameworks_base-bc4cb0bc79c0d366d6866fe4054a71e00d169ff9.zip frameworks_base-bc4cb0bc79c0d366d6866fe4054a71e00d169ff9.tar.gz frameworks_base-bc4cb0bc79c0d366d6866fe4054a71e00d169ff9.tar.bz2 |
MTP host: Add support for reading files from an MTP device via ParcelFileDescriptor
Also added some support for sending files to the device that hasn't been debugged yet.
Add locking to MtpDevice to prevent it from attempting multiple transactions simultaneously.
Change-Id: I2b995ba0af086cc6920bd6b8c869f540ad78560a
Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'media/jni')
-rw-r--r-- | media/jni/android_media_MtpClient.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/media/jni/android_media_MtpClient.cpp b/media/jni/android_media_MtpClient.cpp index f69053c..67740bc 100644 --- a/media/jni/android_media_MtpClient.cpp +++ b/media/jni/android_media_MtpClient.cpp @@ -29,6 +29,7 @@ #include "MtpClient.h" #include "MtpDevice.h" +#include "MtpObjectInfo.h" using namespace android; @@ -38,6 +39,19 @@ static jmethodID method_deviceAdded; static jmethodID method_deviceRemoved; static jfieldID field_context; +static struct file_descriptor_offsets_t +{ + jclass mClass; + jmethodID mConstructor; + jfieldID mDescriptor; +} gFileDescriptorOffsets; + +static struct parcel_file_descriptor_offsets_t +{ + jclass mClass; + jmethodID mConstructor; +} gParcelFileDescriptorOffsets; + #ifdef HAVE_ANDROID_OS static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { @@ -187,6 +201,38 @@ android_media_MtpClient_get_storage_id(JNIEnv *env, jobject thiz, return -1; } +static jobject +android_media_MtpClient_open_file(JNIEnv *env, jobject thiz, + jint device_id, jint object_id) +{ +#ifdef HAVE_ANDROID_OS + MyClient *client = (MyClient *)env->GetIntField(thiz, field_context); + MtpDevice* device = client->getDevice(device_id); + if (!device) + return NULL; + + MtpObjectInfo* info = device->getObjectInfo(object_id); + if (!info) + return NULL; + int object_size = info->mCompressedSize; + delete info; + int fd = device->readObject(object_id, object_size); + if (fd < 0) + return NULL; + + jobject fileDescriptor = env->NewObject(gFileDescriptorOffsets.mClass, + gFileDescriptorOffsets.mConstructor); + if (fileDescriptor != NULL) { + env->SetIntField(fileDescriptor, gFileDescriptorOffsets.mDescriptor, fd); + } else { + return NULL; + } + return env->NewObject(gParcelFileDescriptorOffsets.mClass, + gParcelFileDescriptorOffsets.mConstructor, fileDescriptor); +#endif + return NULL; +} + // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { @@ -197,6 +243,8 @@ static JNINativeMethod gMethods[] = { {"native_delete_object", "(II)Z", (void *)android_media_MtpClient_delete_object}, {"native_get_parent", "(II)I", (void *)android_media_MtpClient_get_parent}, {"native_get_storage_id", "(II)I", (void *)android_media_MtpClient_get_storage_id}, + {"native_open_file", "(II)Landroid/os/ParcelFileDescriptor;", + (void *)android_media_MtpClient_open_file}, }; static const char* const kClassPathName = "android/media/MtpClient"; @@ -228,6 +276,21 @@ int register_android_media_MtpClient(JNIEnv *env) return -1; } + clazz = env->FindClass("java/io/FileDescriptor"); + LOG_FATAL_IF(clazz == NULL, "Unable to find class java.io.FileDescriptor"); + gFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); + gFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "()V"); + gFileDescriptorOffsets.mDescriptor = env->GetFieldID(clazz, "descriptor", "I"); + LOG_FATAL_IF(gFileDescriptorOffsets.mDescriptor == NULL, + "Unable to find descriptor field in java.io.FileDescriptor"); + + clazz = env->FindClass("android/os/ParcelFileDescriptor"); + LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor"); + gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); + gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V"); + LOG_FATAL_IF(gParcelFileDescriptorOffsets.mConstructor == NULL, + "Unable to find constructor for android.os.ParcelFileDescriptor"); + return AndroidRuntime::registerNativeMethods(env, "android/media/MtpClient", gMethods, NELEM(gMethods)); } |