Handle error result returned from MTP API correctly.
* Check null result for all MTP APIs that can return null.
* Don't regard valid parent handles that are more than 0x80000000 as
error.
* Check boolean result from importFile.
Change-Id: I262511ac3c935ebb54e52c03eaefd3535a3e2f29
Fix: 28155538
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 00d31a71a..90dd440 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -16,6 +16,7 @@
package com.android.mtp;
+import android.annotation.Nullable;
import android.content.Context;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
@@ -27,6 +28,7 @@
import android.mtp.MtpDeviceInfo;
import android.mtp.MtpEvent;
import android.mtp.MtpObjectInfo;
+import android.mtp.MtpStorageInfo;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -80,9 +82,7 @@
}
}
- if (rawDevice == null) {
- throw new IOException("Not found USB device: " + deviceId);
- }
+ ensureNotNull(rawDevice, "Not found USB device: " + deviceId);
if (!mManager.hasPermission(rawDevice)) {
mManager.grantPermission(rawDevice);
@@ -93,10 +93,9 @@
final MtpDevice device = new MtpDevice(rawDevice);
- final UsbDeviceConnection connection = mManager.openDevice(rawDevice);
- if (connection == null) {
- throw new IOException("Failed to open a USB connection.");
- }
+ final UsbDeviceConnection connection = ensureNotNull(
+ mManager.openDevice(rawDevice),
+ "Failed to open a USB connection.");
if (!device.open(connection)) {
// We cannot open connection when another application use the device.
@@ -104,13 +103,11 @@
}
// Handle devices that fail to obtain storages just after opening a MTP session.
- final int[] storageIds = device.getStorageIds();
- if (storageIds == null) {
- throw new IOException("Not found MTP storages in the device.");
- }
+ final int[] storageIds = ensureNotNull(
+ device.getStorageIds(),
+ "Not found MTP storages in the device.");
mDevices.put(deviceId, device);
-
return createDeviceRecord(rawDevice);
}
@@ -133,11 +130,9 @@
MtpObjectInfo getObjectInfo(int deviceId, int objectHandle) throws IOException {
final MtpDevice device = getDevice(deviceId);
synchronized (device) {
- final MtpObjectInfo info = device.getObjectInfo(objectHandle);
- if (info == null) {
- throw new IOException("Failed to get object info: " + objectHandle);
- }
- return info;
+ return ensureNotNull(
+ device.getObjectInfo(objectHandle),
+ "Failed to get object info: " + objectHandle);
}
}
@@ -145,12 +140,9 @@
throws IOException {
final MtpDevice device = getDevice(deviceId);
synchronized (device) {
- final int[] handles =
- device.getObjectHandles(storageId, 0 /* all format */, parentObjectHandle);
- if (handles == null) {
- throw new IOException("Failed to fetch object handles.");
- }
- return handles;
+ return ensureNotNull(
+ device.getObjectHandles(storageId, 0 /* all format */, parentObjectHandle),
+ "Failed to fetch object handles.");
}
}
@@ -158,7 +150,9 @@
throws IOException {
final MtpDevice device = getDevice(deviceId);
synchronized (device) {
- return device.getObject(objectHandle, expectedSize);
+ return ensureNotNull(
+ device.getObject(objectHandle, expectedSize),
+ "Failed to fetch object bytes");
}
}
@@ -181,7 +175,9 @@
byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
final MtpDevice device = getDevice(deviceId);
synchronized (device) {
- return device.getThumbnail(objectHandle);
+ return ensureNotNull(
+ device.getThumbnail(objectHandle),
+ "Failed to obtain thumbnail bytes");
}
}
@@ -216,7 +212,7 @@
final MtpDevice device = getDevice(deviceId);
synchronized (device) {
final int result = (int) device.getParent(objectHandle);
- if (result < 0) {
+ if (result == 0xffffffff) {
throw new FileNotFoundException("Not found parent object");
}
return result;
@@ -227,7 +223,9 @@
throws IOException {
final MtpDevice device = getDevice(deviceId);
synchronized (device) {
- device.importFile(objectHandle, target);
+ if (!device.importFile(objectHandle, target)) {
+ throw new IOException("Failed to import file to FD");
+ }
}
}
@@ -243,26 +241,25 @@
}
private synchronized MtpDevice getDevice(int deviceId) throws IOException {
- final MtpDevice device = mDevices.get(deviceId);
- if (device == null) {
- throw new IOException("USB device " + deviceId + " is not opened.");
- }
- return device;
+ return ensureNotNull(
+ mDevices.get(deviceId),
+ "USB device " + deviceId + " is not opened.");
}
private MtpRoot[] getRoots(int deviceId) throws IOException {
final MtpDevice device = getDevice(deviceId);
synchronized (device) {
- final int[] storageIds = device.getStorageIds();
- if (storageIds == null) {
- throw new IOException("Failed to obtain storage IDs.");
- }
- final MtpRoot[] results = new MtpRoot[storageIds.length];
+ final int[] storageIds =
+ ensureNotNull(device.getStorageIds(), "Failed to obtain storage IDs.");
+ final ArrayList<MtpRoot> roots = new ArrayList<>();
for (int i = 0; i < storageIds.length; i++) {
- results[i] = new MtpRoot(
- device.getDeviceId(), device.getStorageInfo(storageIds[i]));
+ final MtpStorageInfo info = device.getStorageInfo(storageIds[i]);
+ if (info == null) {
+ continue;
+ }
+ roots.add(new MtpRoot(device.getDeviceId(), info));
}
- return results;
+ return roots.toArray(new MtpRoot[roots.size()]);
}
}
@@ -313,4 +310,12 @@
}
return false;
}
+
+ private static <T> T ensureNotNull(@Nullable T t, String errorMessage) throws IOException {
+ if (t != null) {
+ return t;
+ } else {
+ throw new IOException(errorMessage);
+ }
+ }
}