Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 77a1c656 authored by Daichi Hirono's avatar Daichi Hirono
Browse files

Open 4G+ file by using AppFuse.

To open files by using AppFuse, the provider needs to know the size of
file. Previously we cannot open 4G+ files because we cannot obtain file
size for such large files.

Now MtpDatabase contains correct size for 4GB+ file size. The CL starts
opening files by using AppFuse which obtains partial bytes by using
getObjectPartial64 operation.

FIXED=26840097

Change-Id: I1cb41972175c2b98f4aa76981decc6b3ad35486d
parent 4d9b6e4f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -144,6 +144,8 @@ public class AppFuse {
            return mCallback.getFileSize(inode);
        } catch (FileNotFoundException e) {
            return -OsConstants.ENOENT;
        } catch (UnsupportedOperationException e) {
            return -OsConstants.ENOTSUP;
        }
    }

+9 −2
Original line number Diff line number Diff line
@@ -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) {
+20 −6
Original line number Diff line number Diff line
@@ -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
+8 −0
Original line number Diff line number Diff line
@@ -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) {