Loading core/java/android/provider/Mtp.java +19 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,25 @@ public final class Mtp + "/storage/" + storageID + "/child"); } /** * Used for copying files from device to host. * Constructs a Uri based on the ID of the device and object for the source file, * and the path for the destination file. * When passed to the ContentProvider.insert() method, the file will be transferred * to the specified destination directory and insert() will return a content Uri * for the new file in the MediaProvider. * ContentProvider.insert() will throw IllegalArgumentException if the destination * path is not in the external storage or internal media directory. */ public static Uri getContentUriForImport(int deviceID, long objectID, String destPath) { if (destPath.length() == 0 || destPath.charAt(0) != '/') { throw new IllegalArgumentException( "destPath must be a full path in getContentUriForImport"); } return Uri.parse(CONTENT_AUTHORITY_DEVICE_SLASH + deviceID + "/import/" + objectID + "?" + destPath); } /** * The following columns correspond to the fields in the ObjectInfo dataset * as described in the MTP specification. Loading media/java/android/media/MtpClient.java +5 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package android.media; import android.os.ParcelFileDescriptor; import android.util.Log; /** Loading Loading @@ -69,9 +68,10 @@ public class MtpClient { return native_get_storage_id(deviceID, objectID); } // create a file descriptor for reading the contents of an object over MTP public ParcelFileDescriptor openFile(int deviceID, long objectID) { return native_open_file(deviceID, objectID); // Reads a file from device to host to the specified destination. // Returns true if the transfer succeeds. public boolean importFile(int deviceID, long objectID, String destPath) { return native_import_file(deviceID, objectID, destPath); } public interface Listener { Loading Loading @@ -104,5 +104,5 @@ public class MtpClient { private native boolean native_delete_object(int deviceID, long objectID); private native long native_get_parent(int deviceID, long objectID); private native long native_get_storage_id(int deviceID, long objectID); private native ParcelFileDescriptor native_open_file(int deviceID, long objectID); private native boolean native_import_file(int deviceID, long objectID, String destPath); } media/java/android/media/MtpCursor.java +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ public final class MtpCursor extends AbstractWindowedCursor { public static final int OBJECT_ID = 6; public static final int STORAGE_CHILDREN = 7; public static final int OBJECT_CHILDREN = 8; public static final int OBJECT_IMPORT = 9; /** The names of the columns in the projection */ private String[] mColumns; Loading media/jni/android_media_MtpClient.cpp +10 −53 Original line number Diff line number Diff line Loading @@ -39,19 +39,6 @@ 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) { Loading Loading @@ -201,34 +188,19 @@ 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, jlong object_id) static jboolean android_media_MtpClient_import_file(JNIEnv *env, jobject thiz, jint device_id, jlong object_id, jstring dest_path) { #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; if (device) { const char *destPathStr = env->GetStringUTFChars(dest_path, NULL); bool result = device->readObject(object_id, destPathStr); env->ReleaseStringUTFChars(dest_path, destPathStr); return result; } return env->NewObject(gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDescriptor); #endif return NULL; } Loading @@ -243,8 +215,8 @@ static JNINativeMethod gMethods[] = { {"native_delete_object", "(IJ)Z", (void *)android_media_MtpClient_delete_object}, {"native_get_parent", "(IJ)J", (void *)android_media_MtpClient_get_parent}, {"native_get_storage_id", "(IJ)J", (void *)android_media_MtpClient_get_storage_id}, {"native_open_file", "(IJ)Landroid/os/ParcelFileDescriptor;", (void *)android_media_MtpClient_open_file}, {"native_import_file", "(IJLjava/lang/String;)Z", (void *)android_media_MtpClient_import_file}, }; static const char* const kClassPathName = "android/media/MtpClient"; Loading Loading @@ -276,21 +248,6 @@ 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)); } media/mtp/MtpDataPacket.cpp +17 −13 Original line number Diff line number Diff line Loading @@ -413,20 +413,32 @@ int MtpDataPacket::read(struct usb_endpoint *ep) { } int MtpDataPacket::readData(struct usb_endpoint *ep, void* buffer, int length) { int packetSize = usb_endpoint_max_packet(ep); int read = 0; while (read < length) { int ret = transfer(ep, (char *)buffer + read, packetSize); int ret = transfer(ep, (char *)buffer + read, length - read); if (ret < 0) { printf("MtpDataPacket::readData returning %d\n", ret); return ret; } read += ret; } printf("MtpDataPacket::readData returning %d\n", read); return read; } // Queue a read request. Call readDataWait to wait for result int MtpDataPacket::readDataAsync(struct usb_endpoint *ep, void* buffer, int length) { if (usb_endpoint_queue(ep, buffer, length)) { LOGE("usb_endpoint_queue failed, errno: %d", errno); return -1; } return 0; } // Wait for result of readDataAsync int MtpDataPacket::readDataWait(struct usb_endpoint *ep) { int ep_num; return usb_endpoint_wait(usb_endpoint_get_device(ep), &ep_num); } int MtpDataPacket::readDataHeader(struct usb_endpoint *ep) { int length = transfer(ep, mBuffer, usb_endpoint_max_packet(ep)); if (length >= 0) Loading Loading @@ -454,15 +466,7 @@ int MtpDataPacket::write(struct usb_endpoint *ep) { } int MtpDataPacket::write(struct usb_endpoint *ep, void* buffer, uint32_t length) { int ret = 0; int packetSize = usb_endpoint_max_packet(ep); while (length > 0) { int write = (length > packetSize ? packetSize : length); int ret = transfer(ep, buffer, write); if (ret < 0) break; length -= ret; } int ret = transfer(ep, buffer, length); return (ret < 0 ? ret : 0); } Loading Loading
core/java/android/provider/Mtp.java +19 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,25 @@ public final class Mtp + "/storage/" + storageID + "/child"); } /** * Used for copying files from device to host. * Constructs a Uri based on the ID of the device and object for the source file, * and the path for the destination file. * When passed to the ContentProvider.insert() method, the file will be transferred * to the specified destination directory and insert() will return a content Uri * for the new file in the MediaProvider. * ContentProvider.insert() will throw IllegalArgumentException if the destination * path is not in the external storage or internal media directory. */ public static Uri getContentUriForImport(int deviceID, long objectID, String destPath) { if (destPath.length() == 0 || destPath.charAt(0) != '/') { throw new IllegalArgumentException( "destPath must be a full path in getContentUriForImport"); } return Uri.parse(CONTENT_AUTHORITY_DEVICE_SLASH + deviceID + "/import/" + objectID + "?" + destPath); } /** * The following columns correspond to the fields in the ObjectInfo dataset * as described in the MTP specification. Loading
media/java/android/media/MtpClient.java +5 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package android.media; import android.os.ParcelFileDescriptor; import android.util.Log; /** Loading Loading @@ -69,9 +68,10 @@ public class MtpClient { return native_get_storage_id(deviceID, objectID); } // create a file descriptor for reading the contents of an object over MTP public ParcelFileDescriptor openFile(int deviceID, long objectID) { return native_open_file(deviceID, objectID); // Reads a file from device to host to the specified destination. // Returns true if the transfer succeeds. public boolean importFile(int deviceID, long objectID, String destPath) { return native_import_file(deviceID, objectID, destPath); } public interface Listener { Loading Loading @@ -104,5 +104,5 @@ public class MtpClient { private native boolean native_delete_object(int deviceID, long objectID); private native long native_get_parent(int deviceID, long objectID); private native long native_get_storage_id(int deviceID, long objectID); private native ParcelFileDescriptor native_open_file(int deviceID, long objectID); private native boolean native_import_file(int deviceID, long objectID, String destPath); }
media/java/android/media/MtpCursor.java +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ public final class MtpCursor extends AbstractWindowedCursor { public static final int OBJECT_ID = 6; public static final int STORAGE_CHILDREN = 7; public static final int OBJECT_CHILDREN = 8; public static final int OBJECT_IMPORT = 9; /** The names of the columns in the projection */ private String[] mColumns; Loading
media/jni/android_media_MtpClient.cpp +10 −53 Original line number Diff line number Diff line Loading @@ -39,19 +39,6 @@ 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) { Loading Loading @@ -201,34 +188,19 @@ 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, jlong object_id) static jboolean android_media_MtpClient_import_file(JNIEnv *env, jobject thiz, jint device_id, jlong object_id, jstring dest_path) { #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; if (device) { const char *destPathStr = env->GetStringUTFChars(dest_path, NULL); bool result = device->readObject(object_id, destPathStr); env->ReleaseStringUTFChars(dest_path, destPathStr); return result; } return env->NewObject(gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fileDescriptor); #endif return NULL; } Loading @@ -243,8 +215,8 @@ static JNINativeMethod gMethods[] = { {"native_delete_object", "(IJ)Z", (void *)android_media_MtpClient_delete_object}, {"native_get_parent", "(IJ)J", (void *)android_media_MtpClient_get_parent}, {"native_get_storage_id", "(IJ)J", (void *)android_media_MtpClient_get_storage_id}, {"native_open_file", "(IJ)Landroid/os/ParcelFileDescriptor;", (void *)android_media_MtpClient_open_file}, {"native_import_file", "(IJLjava/lang/String;)Z", (void *)android_media_MtpClient_import_file}, }; static const char* const kClassPathName = "android/media/MtpClient"; Loading Loading @@ -276,21 +248,6 @@ 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)); }
media/mtp/MtpDataPacket.cpp +17 −13 Original line number Diff line number Diff line Loading @@ -413,20 +413,32 @@ int MtpDataPacket::read(struct usb_endpoint *ep) { } int MtpDataPacket::readData(struct usb_endpoint *ep, void* buffer, int length) { int packetSize = usb_endpoint_max_packet(ep); int read = 0; while (read < length) { int ret = transfer(ep, (char *)buffer + read, packetSize); int ret = transfer(ep, (char *)buffer + read, length - read); if (ret < 0) { printf("MtpDataPacket::readData returning %d\n", ret); return ret; } read += ret; } printf("MtpDataPacket::readData returning %d\n", read); return read; } // Queue a read request. Call readDataWait to wait for result int MtpDataPacket::readDataAsync(struct usb_endpoint *ep, void* buffer, int length) { if (usb_endpoint_queue(ep, buffer, length)) { LOGE("usb_endpoint_queue failed, errno: %d", errno); return -1; } return 0; } // Wait for result of readDataAsync int MtpDataPacket::readDataWait(struct usb_endpoint *ep) { int ep_num; return usb_endpoint_wait(usb_endpoint_get_device(ep), &ep_num); } int MtpDataPacket::readDataHeader(struct usb_endpoint *ep) { int length = transfer(ep, mBuffer, usb_endpoint_max_packet(ep)); if (length >= 0) Loading Loading @@ -454,15 +466,7 @@ int MtpDataPacket::write(struct usb_endpoint *ep) { } int MtpDataPacket::write(struct usb_endpoint *ep, void* buffer, uint32_t length) { int ret = 0; int packetSize = usb_endpoint_max_packet(ep); while (length > 0) { int write = (length > packetSize ? packetSize : length); int ret = transfer(ep, buffer, write); if (ret < 0) break; length -= ret; } int ret = transfer(ep, buffer, length); return (ret < 0 ? ret : 0); } Loading