diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java index 1fd471cb48e2d..777dc606f6c30 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java @@ -144,6 +144,8 @@ public class AppFuse { return mCallback.getFileSize(inode); } catch (FileNotFoundException e) { return -OsConstants.ENOENT; + } catch (UnsupportedOperationException e) { + return -OsConstants.ENOTSUP; } } diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java index 393c4de89ea4e..c52b81d76d362 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java @@ -56,8 +56,15 @@ class MtpDeviceRecord { } static boolean isPartialReadSupported(@Nullable int[] supportedList, long fileSize) { - return fileSize <= 0xffffffffl && - isSupported(supportedList, MtpConstants.OPERATION_GET_PARTIAL_OBJECT); + if (isSupported(supportedList, MtpConstants.OPERATION_GET_PARTIAL_OBJECT_64)) { + return true; + } + if (0 <= fileSize && + fileSize <= 0xffffffffL && + isSupported(supportedList, MtpConstants.OPERATION_GET_PARTIAL_OBJECT)) { + return true; + } + return false; } static boolean isWritingSupported(@Nullable int[] supportedList) { diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java index 167cb37f72443..9f64046ce64af 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java @@ -234,11 +234,14 @@ public class MtpDocumentsProvider extends DocumentsProvider { final MtpDeviceRecord device = getDeviceToolkit(identifier.mDeviceId).mDeviceRecord; switch (mode) { case "r": - final long fileSize = getFileSize(documentId); + long fileSize; + try { + fileSize = getFileSize(documentId); + } catch (UnsupportedOperationException exception) { + fileSize = -1; + } // MTP getPartialObject operation does not support files that are larger than // 4GB. Fallback to non-seekable file descriptor. - // TODO: Use getPartialObject64 for MTP devices that support Android vendor - // extension. if (MtpDeviceRecord.isPartialReadSupported( device.operationsSupported, fileSize)) { return mAppFuse.openFile( @@ -543,6 +546,9 @@ public class MtpDocumentsProvider extends DocumentsProvider { MtpDatabase.strings(Document.COLUMN_SIZE, Document.COLUMN_DISPLAY_NAME)); try { if (cursor.moveToNext()) { + if (cursor.isNull(0)) { + throw new UnsupportedOperationException(); + } return cursor.getLong(0); } else { throw new FileNotFoundException(); @@ -594,12 +600,20 @@ public class MtpDocumentsProvider extends DocumentsProvider { int inode, long offset, long size, byte[] buffer) throws IOException { final Identifier identifier = mDatabase.createIdentifier(Integer.toString(inode)); final MtpDeviceRecord record = getDeviceToolkit(identifier.mDeviceId).mDeviceRecord; - if (MtpDeviceRecord.isPartialReadSupported(record.operationsSupported, offset)) { + + if (MtpDeviceRecord.isSupported( + record.operationsSupported, MtpConstants.OPERATION_GET_PARTIAL_OBJECT_64)) { + return mMtpManager.getPartialObject64( + identifier.mDeviceId, identifier.mObjectHandle, offset, size, buffer); + } + + if (0 <= offset && offset <= 0xffffffffL && MtpDeviceRecord.isSupported( + record.operationsSupported, MtpConstants.OPERATION_GET_PARTIAL_OBJECT)) { return mMtpManager.getPartialObject( identifier.mDeviceId, identifier.mObjectHandle, offset, size, buffer); - } else { - throw new UnsupportedOperationException(); } + + throw new UnsupportedOperationException(); } @Override diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java index 53873fbe2a7f2..00d31a71a2d66 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java @@ -170,6 +170,14 @@ class MtpManager { } } + long getPartialObject64(int deviceId, int objectHandle, long offset, long size, byte[] buffer) + throws IOException { + final MtpDevice device = getDevice(deviceId); + synchronized (device) { + return device.getPartialObject64(objectHandle, offset, size, buffer); + } + } + byte[] getThumbnail(int deviceId, int objectHandle) throws IOException { final MtpDevice device = getDevice(deviceId); synchronized (device) {