summaryrefslogtreecommitdiffstats
path: root/media/jni
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2010-07-26 20:40:45 -0400
committerMike Lockwood <lockwood@android.com>2010-07-26 20:40:45 -0400
commitbc4cb0bc79c0d366d6866fe4054a71e00d169ff9 (patch)
tree575e35759dcc1ae6a6e6efab1960d57d73f7a426 /media/jni
parentf78b26a572e3ba5d47009f3a810a15e252b5503c (diff)
downloadframeworks_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.cpp63
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));
}