MtpClient: Fix problem with getDeviceList() returning empty result in some cases
BUG: 3503128
Change-Id: I2263437d6018848e316ae4096eb07305fc4dc486
Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/media/java/android/mtp/MtpClient.java b/media/java/android/mtp/MtpClient.java
index c4ee19e..40e2f9b 100644
--- a/media/java/android/mtp/MtpClient.java
+++ b/media/java/android/mtp/MtpClient.java
@@ -29,6 +29,7 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
/**
@@ -43,7 +44,10 @@
private final Context mContext;
private final UsbManager mUsbManager;
private final ArrayList<Listener> mListeners = new ArrayList<Listener>();
- private final ArrayList<MtpDevice> mDeviceList = new ArrayList<MtpDevice>();
+ // mDevices contains all MtpDevices that have been seen by our client,
+ // so we can inform when the device has been detached.
+ // mDevices is also used for synchronization in this class.
+ private final HashMap<String, MtpDevice> mDevices = new HashMap<String, MtpDevice>();
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
@@ -51,21 +55,21 @@
UsbDevice usbDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
String deviceName = usbDevice.getDeviceName();
- synchronized (mDeviceList) {
- MtpDevice mtpDevice = getDeviceLocked(deviceName);
+ synchronized (mDevices) {
+ MtpDevice mtpDevice = mDevices.get(deviceName);
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
if (mtpDevice == null) {
- mtpDevice = openDevice(usbDevice);
+ mtpDevice = openDeviceLocked(usbDevice);
}
if (mtpDevice != null) {
- mDeviceList.add(mtpDevice);
+ mDevices.put(deviceName, mtpDevice);
for (Listener listener : mListeners) {
listener.deviceAdded(mtpDevice);
}
}
} else if (mtpDevice != null) {
- mDeviceList.remove(mtpDevice);
+ mDevices.remove(deviceName);
for (Listener listener : mListeners) {
listener.deviceRemoved(mtpDevice);
}
@@ -127,16 +131,6 @@
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
context.registerReceiver(mUsbReceiver, filter);
-
- for (UsbDevice usbDevice : mUsbManager.getDeviceList().values()) {
- MtpDevice mtpDevice = getDeviceLocked(usbDevice.getDeviceName());
- if (mtpDevice == null) {
- mtpDevice = openDevice(usbDevice);
- }
- if (mtpDevice != null) {
- mDeviceList.add(mtpDevice);
- }
- }
}
/**
@@ -146,7 +140,7 @@
* @param device the device to open
* @return an MtpDevice for the device.
*/
- private MtpDevice openDevice(UsbDevice usbDevice) {
+ private MtpDevice openDeviceLocked(UsbDevice usbDevice) {
if (isCamera(usbDevice)) {
MtpDevice mtpDevice = new MtpDevice(usbDevice);
if (mtpDevice.open(mUsbManager)) {
@@ -170,7 +164,7 @@
* @param listener the listener to register
*/
public void addListener(Listener listener) {
- synchronized (mDeviceList) {
+ synchronized (mDevices) {
if (!mListeners.contains(listener)) {
mListeners.add(listener);
}
@@ -183,7 +177,7 @@
* @param listener the listener to unregister
*/
public void removeListener(Listener listener) {
- synchronized (mDeviceList) {
+ synchronized (mDevices) {
mListeners.remove(listener);
}
}
@@ -196,8 +190,8 @@
* @return the MtpDevice, or null if it does not exist
*/
public MtpDevice getDevice(String deviceName) {
- synchronized (mDeviceList) {
- return getDeviceLocked(deviceName);
+ synchronized (mDevices) {
+ return mDevices.get(deviceName);
}
}
@@ -209,28 +203,32 @@
* @return the MtpDevice, or null if it does not exist
*/
public MtpDevice getDevice(int id) {
- synchronized (mDeviceList) {
- return getDeviceLocked(UsbDevice.getDeviceName(id));
+ synchronized (mDevices) {
+ return mDevices.get(UsbDevice.getDeviceName(id));
}
}
- private MtpDevice getDeviceLocked(String deviceName) {
- for (MtpDevice device : mDeviceList) {
- if (device.getDeviceName().equals(deviceName)) {
- return device;
- }
- }
- return null;
- }
-
/**
* Retrieves a list of all currently connected {@link android.mtp.MtpDevice}.
*
* @return the list of MtpDevices
*/
public List<MtpDevice> getDeviceList() {
- synchronized (mDeviceList) {
- return new ArrayList<MtpDevice>(mDeviceList);
+ synchronized (mDevices) {
+ // Query the USB manager since devices might have attached
+ // before we added our listener.
+ for (UsbDevice usbDevice : mUsbManager.getDeviceList().values()) {
+ String deviceName = usbDevice.getDeviceName();
+ MtpDevice mtpDevice = mDevices.get(deviceName);
+ if (mtpDevice == null) {
+ mtpDevice = openDeviceLocked(usbDevice);
+ }
+ if (mtpDevice != null) {
+ mDevices.put(deviceName, mtpDevice);
+ }
+ }
+
+ return new ArrayList<MtpDevice>(mDevices.values());
}
}