Loading packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java +17 −11 Original line number Diff line number Diff line Loading @@ -47,16 +47,16 @@ class DocumentLoader implements AutoCloseable { static final int NUM_LOADING_ENTRIES = 20; static final int NOTIFY_PERIOD_MS = 500; private final int mDeviceId; private final MtpDeviceRecord mDevice; private final MtpManager mMtpManager; private final ContentResolver mResolver; private final MtpDatabase mDatabase; private final TaskList mTaskList = new TaskList(); private Thread mBackgroundThread; DocumentLoader(int deviceId, MtpManager mtpManager, ContentResolver resolver, DocumentLoader(MtpDeviceRecord device, MtpManager mtpManager, ContentResolver resolver, MtpDatabase database) { mDeviceId = deviceId; mDevice = device; mMtpManager = mtpManager; mResolver = resolver; mDatabase = database; Loading @@ -69,7 +69,7 @@ class DocumentLoader implements AutoCloseable { */ synchronized Cursor queryChildDocuments(String[] columnNames, Identifier parent) throws IOException { Preconditions.checkArgument(parent.mDeviceId == mDeviceId); Preconditions.checkArgument(parent.mDeviceId == mDevice.deviceId); LoaderTask task = mTaskList.findTask(parent); if (task == null) { if (parent.mDocumentId == null) { Loading @@ -81,7 +81,7 @@ class DocumentLoader implements AutoCloseable { // 3. startAddingChildDocuemnts. // 4. stopAddingChildDocuments - It removes the new document added at the step 2, // because it is not updated between start/stopAddingChildDocuments. task = LoaderTask.create(mDatabase, mMtpManager, parent); task = LoaderTask.create(mDatabase, mMtpManager, mDevice.operationsSupported, parent); task.fillDocuments(loadDocuments( mMtpManager, parent.mDeviceId, Loading Loading @@ -123,7 +123,7 @@ class DocumentLoader implements AutoCloseable { return task; } final Identifier identifier = mDatabase.getUnmappedDocumentsParent(mDeviceId); final Identifier identifier = mDatabase.getUnmappedDocumentsParent(mDevice.deviceId); if (identifier != null) { final LoaderTask existingTask = mTaskList.findTask(identifier); if (existingTask != null) { Loading @@ -131,7 +131,8 @@ class DocumentLoader implements AutoCloseable { mTaskList.remove(existingTask); } try { final LoaderTask newTask = LoaderTask.create(mDatabase, mMtpManager, identifier); final LoaderTask newTask = LoaderTask.create( mDatabase, mMtpManager, mDevice.operationsSupported, identifier); mTaskList.addFirst(newTask); return newTask; } catch (IOException exception) { Loading Loading @@ -275,14 +276,17 @@ class DocumentLoader implements AutoCloseable { static final int STATE_ERROR = 2; final MtpDatabase mDatabase; int[] mOperationsSupported; final Identifier mIdentifier; final int[] mObjectHandles; Date mLastNotified; int mNumLoaded; Exception mError; LoaderTask(MtpDatabase database, Identifier identifier, int[] objectHandles) { LoaderTask(MtpDatabase database, int[] operationsSupported, Identifier identifier, int[] objectHandles) { mDatabase = database; mOperationsSupported = operationsSupported; mIdentifier = identifier; mObjectHandles = objectHandles; mNumLoaded = 0; Loading Loading @@ -355,7 +359,8 @@ class DocumentLoader implements AutoCloseable { mDatabase.getMapper().startAddingDocuments(mIdentifier.mDocumentId); } mDatabase.getMapper().putChildDocuments( mIdentifier.mDeviceId, mIdentifier.mDocumentId, objectInfoList); mIdentifier.mDeviceId, mIdentifier.mDocumentId, mOperationsSupported, objectInfoList); mNumLoaded += objectInfoList.length; if (getState() != STATE_LOADING) { mDatabase.getMapper().stopAddingDocuments(mIdentifier.mDocumentId); Loading Loading @@ -394,7 +399,8 @@ class DocumentLoader implements AutoCloseable { /** * Creates a LoaderTask that loads children of the given document. */ static LoaderTask create(MtpDatabase database, MtpManager manager, Identifier parent) static LoaderTask create(MtpDatabase database, MtpManager manager, int[] operationsSupported, Identifier parent) throws IOException { int parentHandle = parent.mObjectHandle; // Need to pass the special value MtpManager.OBJECT_HANDLE_ROOT_CHILDREN to Loading @@ -402,7 +408,7 @@ class DocumentLoader implements AutoCloseable { if (parent.mDocumentType == MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE) { parentHandle = MtpManager.OBJECT_HANDLE_ROOT_CHILDREN; } return new LoaderTask(database, parent, manager.getObjectHandles( return new LoaderTask(database, operationsSupported, parent, manager.getObjectHandles( parent.mDeviceId, parent.mStorageId, parentHandle)); } } Loading packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java +4 −2 Original line number Diff line number Diff line Loading @@ -130,12 +130,14 @@ class Mapper { * @param documents List of document information. * @throws FileNotFoundException */ synchronized void putChildDocuments(int deviceId, String parentId, MtpObjectInfo[] documents) synchronized void putChildDocuments( int deviceId, String parentId, int[] operationsSupported, MtpObjectInfo[] documents) throws FileNotFoundException { final ContentValues[] valuesList = new ContentValues[documents.length]; for (int i = 0; i < documents.length; i++) { valuesList[i] = new ContentValues(); MtpDatabase.getObjectDocumentValues(valuesList[i], deviceId, parentId, documents[i]); MtpDatabase.getObjectDocumentValues( valuesList[i], deviceId, parentId, operationsSupported, documents[i]); } putDocuments( parentId, Loading packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java +36 −18 Original line number Diff line number Diff line Loading @@ -372,9 +372,10 @@ class MtpDatabase { * @param info * @return Document ID of added document. */ String putNewDocument(int deviceId, String parentDocumentId, MtpObjectInfo info) { String putNewDocument( int deviceId, String parentDocumentId, int[] operationsSupported, MtpObjectInfo info) { final ContentValues values = new ContentValues(); getObjectDocumentValues(values, deviceId, parentDocumentId, info); getObjectDocumentValues(values, deviceId, parentDocumentId, operationsSupported, info); mDatabase.beginTransaction(); try { final long id = mDatabase.insert(TABLE_DOCUMENTS, null, values); Loading Loading @@ -582,9 +583,10 @@ class MtpDatabase { } } void updateObject(String documentId, int deviceId, String parentId, MtpObjectInfo info) { void updateObject(String documentId, int deviceId, String parentId, int[] operationsSupported, MtpObjectInfo info) { final ContentValues values = new ContentValues(); getObjectDocumentValues(values, deviceId, parentId, info); getObjectDocumentValues(values, deviceId, parentId, operationsSupported, info); mDatabase.beginTransaction(); try { Loading Loading @@ -738,20 +740,10 @@ class MtpDatabase { * @param info MTP object info. */ static void getObjectDocumentValues( ContentValues values, int deviceId, String parentId, MtpObjectInfo info) { ContentValues values, int deviceId, String parentId, int[] operationsSupported, MtpObjectInfo info) { values.clear(); final String mimeType = getMimeType(info); int flag = 0; if (info.getProtectionStatus() == 0) { flag |= Document.FLAG_SUPPORTS_DELETE | Document.FLAG_SUPPORTS_WRITE; if (mimeType == Document.MIME_TYPE_DIR) { flag |= Document.FLAG_DIR_SUPPORTS_CREATE; } } if (info.getThumbCompressedSize() > 0) { flag |= Document.FLAG_SUPPORTS_THUMBNAIL; } values.put(COLUMN_DEVICE_ID, deviceId); values.put(COLUMN_STORAGE_ID, info.getStorageId()); values.put(COLUMN_OBJECT_HANDLE, info.getObjectHandle()); Loading @@ -765,8 +757,10 @@ class MtpDatabase { Document.COLUMN_LAST_MODIFIED, info.getDateModified() != 0 ? info.getDateModified() : null); values.putNull(Document.COLUMN_ICON); values.put(Document.COLUMN_FLAGS, flag); values.put(Document.COLUMN_SIZE, info.getCompressedSize()); values.put(Document.COLUMN_FLAGS, getDocumentFlags( operationsSupported, mimeType, info.getThumbCompressedSizeLong(), info.getProtectionStatus())); values.put(Document.COLUMN_SIZE, info.getCompressedSizeLong()); } private static String getMimeType(MtpObjectInfo info) { Loading @@ -793,6 +787,30 @@ class MtpDatabase { return rootFlag; } private static int getDocumentFlags( int[] operationsSupported, String mimeType, long thumbnailSize, int protectionState) { int flag = 0; if (MtpDeviceRecord.isWritingSupported(operationsSupported) && protectionState == MtpConstants.PROTECTION_STATUS_NONE) { flag |= Document.FLAG_SUPPORTS_WRITE; } if (MtpDeviceRecord.isSupported( operationsSupported, MtpConstants.OPERATION_DELETE_OBJECT) && (protectionState == MtpConstants.PROTECTION_STATUS_NONE || protectionState == MtpConstants.PROTECTION_STATUS_NON_TRANSFERABLE_DATA)) { flag |= Document.FLAG_SUPPORTS_DELETE; } if (mimeType.equals(Document.MIME_TYPE_DIR) && MtpDeviceRecord.isWritingSupported(operationsSupported) && protectionState == MtpConstants.PROTECTION_STATUS_NONE) { flag |= Document.FLAG_DIR_SUPPORTS_CREATE; } if (thumbnailSize > 0) { flag |= Document.FLAG_SUPPORTS_THUMBNAIL; } return flag; } static String[] strings(Object... args) { final String[] results = new String[args.length]; for (int i = 0; i < args.length; i++) { Loading packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +9 −7 Original line number Diff line number Diff line Loading @@ -220,7 +220,7 @@ public class MtpDocumentsProvider extends DocumentsProvider { // when writing is completed. if (MtpDeviceRecord.isWritingSupported(device.operationsSupported)) { return getPipeManager(identifier).writeDocument( getContext(), mMtpManager, identifier); getContext(), mMtpManager, identifier, device.operationsSupported); } else { throw new UnsupportedOperationException( "The device does not support writing operation."); Loading Loading @@ -316,7 +316,8 @@ public class MtpDocumentsProvider extends DocumentsProvider { final MtpObjectInfo infoWithHandle = new MtpObjectInfo.Builder(info).setObjectHandle(objectHandle).build(); final String documentId = mDatabase.putNewDocument( parentId.mDeviceId, parentDocumentId, infoWithHandle); parentId.mDeviceId, parentDocumentId, record.operationsSupported, infoWithHandle); getDocumentLoader(parentId).clearTask(parentId); notifyChildDocumentsChange(parentDocumentId); return documentId; Loading @@ -336,7 +337,7 @@ public class MtpDocumentsProvider extends DocumentsProvider { } final MtpDeviceRecord device = mMtpManager.openDevice(deviceId); final DeviceToolkit toolkit = new DeviceToolkit(deviceId, mMtpManager, mResolver, mDatabase, device); new DeviceToolkit(mMtpManager, mResolver, mDatabase, device); mDeviceToolkits.put(deviceId, toolkit); mIntentSender.sendUpdateNotificationIntent(); try { Loading Loading @@ -499,11 +500,12 @@ public class MtpDocumentsProvider extends DocumentsProvider { public final DocumentLoader mDocumentLoader; public final MtpDeviceRecord mDeviceRecord; public DeviceToolkit( int deviceId, MtpManager manager, ContentResolver resolver, MtpDatabase database, public DeviceToolkit(MtpManager manager, ContentResolver resolver, MtpDatabase database, MtpDeviceRecord record) { mPipeManager = new PipeManager(database); mDocumentLoader = new DocumentLoader(deviceId, manager, resolver, database); mDocumentLoader = new DocumentLoader(record, manager, resolver, database); mDeviceRecord = record; } } Loading packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java +0 −1 Original line number Diff line number Diff line Loading @@ -155,7 +155,6 @@ class MtpManager { } } @VisibleForTesting long getPartialObject(int deviceId, int objectHandle, long offset, long size, byte[] buffer) throws IOException { final MtpDevice device = getDevice(deviceId); Loading Loading
packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java +17 −11 Original line number Diff line number Diff line Loading @@ -47,16 +47,16 @@ class DocumentLoader implements AutoCloseable { static final int NUM_LOADING_ENTRIES = 20; static final int NOTIFY_PERIOD_MS = 500; private final int mDeviceId; private final MtpDeviceRecord mDevice; private final MtpManager mMtpManager; private final ContentResolver mResolver; private final MtpDatabase mDatabase; private final TaskList mTaskList = new TaskList(); private Thread mBackgroundThread; DocumentLoader(int deviceId, MtpManager mtpManager, ContentResolver resolver, DocumentLoader(MtpDeviceRecord device, MtpManager mtpManager, ContentResolver resolver, MtpDatabase database) { mDeviceId = deviceId; mDevice = device; mMtpManager = mtpManager; mResolver = resolver; mDatabase = database; Loading @@ -69,7 +69,7 @@ class DocumentLoader implements AutoCloseable { */ synchronized Cursor queryChildDocuments(String[] columnNames, Identifier parent) throws IOException { Preconditions.checkArgument(parent.mDeviceId == mDeviceId); Preconditions.checkArgument(parent.mDeviceId == mDevice.deviceId); LoaderTask task = mTaskList.findTask(parent); if (task == null) { if (parent.mDocumentId == null) { Loading @@ -81,7 +81,7 @@ class DocumentLoader implements AutoCloseable { // 3. startAddingChildDocuemnts. // 4. stopAddingChildDocuments - It removes the new document added at the step 2, // because it is not updated between start/stopAddingChildDocuments. task = LoaderTask.create(mDatabase, mMtpManager, parent); task = LoaderTask.create(mDatabase, mMtpManager, mDevice.operationsSupported, parent); task.fillDocuments(loadDocuments( mMtpManager, parent.mDeviceId, Loading Loading @@ -123,7 +123,7 @@ class DocumentLoader implements AutoCloseable { return task; } final Identifier identifier = mDatabase.getUnmappedDocumentsParent(mDeviceId); final Identifier identifier = mDatabase.getUnmappedDocumentsParent(mDevice.deviceId); if (identifier != null) { final LoaderTask existingTask = mTaskList.findTask(identifier); if (existingTask != null) { Loading @@ -131,7 +131,8 @@ class DocumentLoader implements AutoCloseable { mTaskList.remove(existingTask); } try { final LoaderTask newTask = LoaderTask.create(mDatabase, mMtpManager, identifier); final LoaderTask newTask = LoaderTask.create( mDatabase, mMtpManager, mDevice.operationsSupported, identifier); mTaskList.addFirst(newTask); return newTask; } catch (IOException exception) { Loading Loading @@ -275,14 +276,17 @@ class DocumentLoader implements AutoCloseable { static final int STATE_ERROR = 2; final MtpDatabase mDatabase; int[] mOperationsSupported; final Identifier mIdentifier; final int[] mObjectHandles; Date mLastNotified; int mNumLoaded; Exception mError; LoaderTask(MtpDatabase database, Identifier identifier, int[] objectHandles) { LoaderTask(MtpDatabase database, int[] operationsSupported, Identifier identifier, int[] objectHandles) { mDatabase = database; mOperationsSupported = operationsSupported; mIdentifier = identifier; mObjectHandles = objectHandles; mNumLoaded = 0; Loading Loading @@ -355,7 +359,8 @@ class DocumentLoader implements AutoCloseable { mDatabase.getMapper().startAddingDocuments(mIdentifier.mDocumentId); } mDatabase.getMapper().putChildDocuments( mIdentifier.mDeviceId, mIdentifier.mDocumentId, objectInfoList); mIdentifier.mDeviceId, mIdentifier.mDocumentId, mOperationsSupported, objectInfoList); mNumLoaded += objectInfoList.length; if (getState() != STATE_LOADING) { mDatabase.getMapper().stopAddingDocuments(mIdentifier.mDocumentId); Loading Loading @@ -394,7 +399,8 @@ class DocumentLoader implements AutoCloseable { /** * Creates a LoaderTask that loads children of the given document. */ static LoaderTask create(MtpDatabase database, MtpManager manager, Identifier parent) static LoaderTask create(MtpDatabase database, MtpManager manager, int[] operationsSupported, Identifier parent) throws IOException { int parentHandle = parent.mObjectHandle; // Need to pass the special value MtpManager.OBJECT_HANDLE_ROOT_CHILDREN to Loading @@ -402,7 +408,7 @@ class DocumentLoader implements AutoCloseable { if (parent.mDocumentType == MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE) { parentHandle = MtpManager.OBJECT_HANDLE_ROOT_CHILDREN; } return new LoaderTask(database, parent, manager.getObjectHandles( return new LoaderTask(database, operationsSupported, parent, manager.getObjectHandles( parent.mDeviceId, parent.mStorageId, parentHandle)); } } Loading
packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java +4 −2 Original line number Diff line number Diff line Loading @@ -130,12 +130,14 @@ class Mapper { * @param documents List of document information. * @throws FileNotFoundException */ synchronized void putChildDocuments(int deviceId, String parentId, MtpObjectInfo[] documents) synchronized void putChildDocuments( int deviceId, String parentId, int[] operationsSupported, MtpObjectInfo[] documents) throws FileNotFoundException { final ContentValues[] valuesList = new ContentValues[documents.length]; for (int i = 0; i < documents.length; i++) { valuesList[i] = new ContentValues(); MtpDatabase.getObjectDocumentValues(valuesList[i], deviceId, parentId, documents[i]); MtpDatabase.getObjectDocumentValues( valuesList[i], deviceId, parentId, operationsSupported, documents[i]); } putDocuments( parentId, Loading
packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java +36 −18 Original line number Diff line number Diff line Loading @@ -372,9 +372,10 @@ class MtpDatabase { * @param info * @return Document ID of added document. */ String putNewDocument(int deviceId, String parentDocumentId, MtpObjectInfo info) { String putNewDocument( int deviceId, String parentDocumentId, int[] operationsSupported, MtpObjectInfo info) { final ContentValues values = new ContentValues(); getObjectDocumentValues(values, deviceId, parentDocumentId, info); getObjectDocumentValues(values, deviceId, parentDocumentId, operationsSupported, info); mDatabase.beginTransaction(); try { final long id = mDatabase.insert(TABLE_DOCUMENTS, null, values); Loading Loading @@ -582,9 +583,10 @@ class MtpDatabase { } } void updateObject(String documentId, int deviceId, String parentId, MtpObjectInfo info) { void updateObject(String documentId, int deviceId, String parentId, int[] operationsSupported, MtpObjectInfo info) { final ContentValues values = new ContentValues(); getObjectDocumentValues(values, deviceId, parentId, info); getObjectDocumentValues(values, deviceId, parentId, operationsSupported, info); mDatabase.beginTransaction(); try { Loading Loading @@ -738,20 +740,10 @@ class MtpDatabase { * @param info MTP object info. */ static void getObjectDocumentValues( ContentValues values, int deviceId, String parentId, MtpObjectInfo info) { ContentValues values, int deviceId, String parentId, int[] operationsSupported, MtpObjectInfo info) { values.clear(); final String mimeType = getMimeType(info); int flag = 0; if (info.getProtectionStatus() == 0) { flag |= Document.FLAG_SUPPORTS_DELETE | Document.FLAG_SUPPORTS_WRITE; if (mimeType == Document.MIME_TYPE_DIR) { flag |= Document.FLAG_DIR_SUPPORTS_CREATE; } } if (info.getThumbCompressedSize() > 0) { flag |= Document.FLAG_SUPPORTS_THUMBNAIL; } values.put(COLUMN_DEVICE_ID, deviceId); values.put(COLUMN_STORAGE_ID, info.getStorageId()); values.put(COLUMN_OBJECT_HANDLE, info.getObjectHandle()); Loading @@ -765,8 +757,10 @@ class MtpDatabase { Document.COLUMN_LAST_MODIFIED, info.getDateModified() != 0 ? info.getDateModified() : null); values.putNull(Document.COLUMN_ICON); values.put(Document.COLUMN_FLAGS, flag); values.put(Document.COLUMN_SIZE, info.getCompressedSize()); values.put(Document.COLUMN_FLAGS, getDocumentFlags( operationsSupported, mimeType, info.getThumbCompressedSizeLong(), info.getProtectionStatus())); values.put(Document.COLUMN_SIZE, info.getCompressedSizeLong()); } private static String getMimeType(MtpObjectInfo info) { Loading @@ -793,6 +787,30 @@ class MtpDatabase { return rootFlag; } private static int getDocumentFlags( int[] operationsSupported, String mimeType, long thumbnailSize, int protectionState) { int flag = 0; if (MtpDeviceRecord.isWritingSupported(operationsSupported) && protectionState == MtpConstants.PROTECTION_STATUS_NONE) { flag |= Document.FLAG_SUPPORTS_WRITE; } if (MtpDeviceRecord.isSupported( operationsSupported, MtpConstants.OPERATION_DELETE_OBJECT) && (protectionState == MtpConstants.PROTECTION_STATUS_NONE || protectionState == MtpConstants.PROTECTION_STATUS_NON_TRANSFERABLE_DATA)) { flag |= Document.FLAG_SUPPORTS_DELETE; } if (mimeType.equals(Document.MIME_TYPE_DIR) && MtpDeviceRecord.isWritingSupported(operationsSupported) && protectionState == MtpConstants.PROTECTION_STATUS_NONE) { flag |= Document.FLAG_DIR_SUPPORTS_CREATE; } if (thumbnailSize > 0) { flag |= Document.FLAG_SUPPORTS_THUMBNAIL; } return flag; } static String[] strings(Object... args) { final String[] results = new String[args.length]; for (int i = 0; i < args.length; i++) { Loading
packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +9 −7 Original line number Diff line number Diff line Loading @@ -220,7 +220,7 @@ public class MtpDocumentsProvider extends DocumentsProvider { // when writing is completed. if (MtpDeviceRecord.isWritingSupported(device.operationsSupported)) { return getPipeManager(identifier).writeDocument( getContext(), mMtpManager, identifier); getContext(), mMtpManager, identifier, device.operationsSupported); } else { throw new UnsupportedOperationException( "The device does not support writing operation."); Loading Loading @@ -316,7 +316,8 @@ public class MtpDocumentsProvider extends DocumentsProvider { final MtpObjectInfo infoWithHandle = new MtpObjectInfo.Builder(info).setObjectHandle(objectHandle).build(); final String documentId = mDatabase.putNewDocument( parentId.mDeviceId, parentDocumentId, infoWithHandle); parentId.mDeviceId, parentDocumentId, record.operationsSupported, infoWithHandle); getDocumentLoader(parentId).clearTask(parentId); notifyChildDocumentsChange(parentDocumentId); return documentId; Loading @@ -336,7 +337,7 @@ public class MtpDocumentsProvider extends DocumentsProvider { } final MtpDeviceRecord device = mMtpManager.openDevice(deviceId); final DeviceToolkit toolkit = new DeviceToolkit(deviceId, mMtpManager, mResolver, mDatabase, device); new DeviceToolkit(mMtpManager, mResolver, mDatabase, device); mDeviceToolkits.put(deviceId, toolkit); mIntentSender.sendUpdateNotificationIntent(); try { Loading Loading @@ -499,11 +500,12 @@ public class MtpDocumentsProvider extends DocumentsProvider { public final DocumentLoader mDocumentLoader; public final MtpDeviceRecord mDeviceRecord; public DeviceToolkit( int deviceId, MtpManager manager, ContentResolver resolver, MtpDatabase database, public DeviceToolkit(MtpManager manager, ContentResolver resolver, MtpDatabase database, MtpDeviceRecord record) { mPipeManager = new PipeManager(database); mDocumentLoader = new DocumentLoader(deviceId, manager, resolver, database); mDocumentLoader = new DocumentLoader(record, manager, resolver, database); mDeviceRecord = record; } } Loading
packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java +0 −1 Original line number Diff line number Diff line Loading @@ -155,7 +155,6 @@ class MtpManager { } } @VisibleForTesting long getPartialObject(int deviceId, int objectHandle, long offset, long size, byte[] buffer) throws IOException { final MtpDevice device = getDevice(deviceId); Loading