Add API for streamed reading on MTP devices.

The existing APIs required to copy all bytes to memory, which will fail in
case of very large files, like movies.

Bug: 22908937
Change-Id: I23bdcbdbf08b7c1b1017591799bbb94e53249a57
This commit is contained in:
Tomasz Mikolajewski
2015-08-04 18:34:03 +09:00
parent 23d4f7cf6e
commit 74d4ff8ab3
4 changed files with 30 additions and 1 deletions

View File

@@ -18088,6 +18088,7 @@ package android.mtp {
method public android.mtp.MtpStorageInfo getStorageInfo(int);
method public byte[] getThumbnail(int);
method public boolean importFile(int, java.lang.String);
method public boolean importFile(int, android.os.ParcelFileDescriptor);
method public boolean open(android.hardware.usb.UsbDeviceConnection);
}

View File

@@ -19602,6 +19602,7 @@ package android.mtp {
method public android.mtp.MtpStorageInfo getStorageInfo(int);
method public byte[] getThumbnail(int);
method public boolean importFile(int, java.lang.String);
method public boolean importFile(int, android.os.ParcelFileDescriptor);
method public boolean open(android.hardware.usb.UsbDeviceConnection);
}

View File

@@ -18,6 +18,7 @@ package android.mtp;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.os.ParcelFileDescriptor;
/**
* This class represents an MTP or PTP device connected on the USB host bus. An application can
@@ -235,6 +236,20 @@ public final class MtpDevice {
return native_import_file(objectHandle, destPath);
}
/**
* Copies the data for an object to a file descriptor.
* This call may block for an arbitrary amount of time depending on the size
* of the data and speed of the devices. The file descriptor is not closed
* on completion, and must be done by the caller.
*
* @param objectHandle handle of the object to read
* @param descriptor file descriptor to write the data to for the file transfer.
* @return true if the file transfer succeeds
*/
public boolean importFile(int objectHandle, ParcelFileDescriptor descriptor) {
return native_import_file(objectHandle, descriptor.getFd());
}
// used by the JNI code
private long mNativeContext;
@@ -251,4 +266,5 @@ public final class MtpDevice {
private native long native_get_parent(int objectHandle);
private native long native_get_storage_id(int objectHandle);
private native boolean native_import_file(int objectHandle, String destPath);
private native boolean native_import_file(int objectHandle, int fd);
}

View File

@@ -393,6 +393,16 @@ android_mtp_MtpDevice_import_file(JNIEnv *env, jobject thiz, jint object_id, jst
return JNI_FALSE;
}
static jboolean
android_mtp_MtpDevice_import_file_to_fd(JNIEnv *env, jobject thiz, jint object_id, jint fd)
{
MtpDevice* device = get_device_from_object(env, thiz);
if (device)
return device->readObject(object_id, fd);
else
return JNI_FALSE;
}
// ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
@@ -413,8 +423,9 @@ static JNINativeMethod gMethods[] = {
{"native_delete_object", "(I)Z", (void *)android_mtp_MtpDevice_delete_object},
{"native_get_parent", "(I)J", (void *)android_mtp_MtpDevice_get_parent},
{"native_get_storage_id", "(I)J", (void *)android_mtp_MtpDevice_get_storage_id},
{"native_import_file", "(ILjava/lang/String;)Z",
{"native_import_file", "(ILjava/lang/String;)Z",
(void *)android_mtp_MtpDevice_import_file},
{"native_import_file", "(II)Z", (void *)android_mtp_MtpDevice_import_file_to_fd}
};
int register_android_mtp_MtpDevice(JNIEnv *env)