diff --git a/UsbSerialExamples/src/com/hoho/android/usbserial/examples/DemoActivity.java b/UsbSerialExamples/src/com/hoho/android/usbserial/examples/DemoActivity.java
index c69415a..92caaf4 100644
--- a/UsbSerialExamples/src/com/hoho/android/usbserial/examples/DemoActivity.java
+++ b/UsbSerialExamples/src/com/hoho/android/usbserial/examples/DemoActivity.java
@@ -110,7 +110,7 @@ public class DemoActivity extends Activity {
@Override
protected void onResume() {
super.onResume();
- mSerialDevice = UsbSerialProber.acquire(mUsbManager);
+ mSerialDevice = UsbSerialProber.findFirstDevice(mUsbManager);
Log.d(TAG, "Resumed, mSerialDevice=" + mSerialDevice);
if (mSerialDevice == null) {
mTitleTextView.setText("No serial device.");
diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialProber.java b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialProber.java
index 9527a6f..fdad88a 100644
--- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialProber.java
+++ b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialProber.java
@@ -20,15 +20,28 @@
package com.hoho.android.usbserial.driver;
-import java.util.Map;
-
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
/**
- * Helper class to assist in detecting and building {@link UsbSerialDriver}
- * instances from available hardware.
+ * Helper class which finds compatible {@link UsbDevice}s and creates
+ * {@link UsbSerialDriver} instances.
+ *
+ *
+ * You don't need a Prober to use the rest of the library: it is perfectly
+ * acceptable to instantiate driver instances manually. The Prober simply
+ * provides convenience functions.
+ *
+ *
+ * For most drivers, the corresponding {@link #probe(UsbManager, UsbDevice)}
+ * method will either return an empty list (device unknown / unsupported) or a
+ * singleton list. However, multi-port drivers may return multiple instances.
*
* @author mike wakerly (opensource@hoho.com)
*/
@@ -43,102 +56,160 @@ public enum UsbSerialProber {
*/
FTDI_SERIAL {
@Override
- public UsbSerialDriver getDevice(final UsbManager manager, final UsbDevice usbDevice) {
+ public List probe(final UsbManager manager, final UsbDevice usbDevice) {
if (!testIfSupported(usbDevice, FtdiSerialDriver.getSupportedDevices())) {
- return null;
+ return Collections.emptyList();
}
final UsbDeviceConnection connection = manager.openDevice(usbDevice);
if (connection == null) {
- return null;
+ return Collections.emptyList();
}
- return new FtdiSerialDriver(usbDevice, connection);
+ final UsbSerialDriver driver = new FtdiSerialDriver(usbDevice, connection);
+ return Collections.singletonList(driver);
}
},
CDC_ACM_SERIAL {
@Override
- public UsbSerialDriver getDevice(UsbManager manager, UsbDevice usbDevice) {
+ public List probe(UsbManager manager, UsbDevice usbDevice) {
if (!testIfSupported(usbDevice, CdcAcmSerialDriver.getSupportedDevices())) {
- return null;
+ return Collections.emptyList();
}
final UsbDeviceConnection connection = manager.openDevice(usbDevice);
if (connection == null) {
- return null;
+ return Collections.emptyList();
}
- return new CdcAcmSerialDriver(usbDevice, connection);
+ final UsbSerialDriver driver = new CdcAcmSerialDriver(usbDevice, connection);
+ return Collections.singletonList(driver);
}
},
-
+
SILAB_SERIAL {
@Override
- public UsbSerialDriver getDevice(final UsbManager manager, final UsbDevice usbDevice) {
+ public List probe(final UsbManager manager, final UsbDevice usbDevice) {
if (!testIfSupported(usbDevice, Cp2102SerialDriver.getSupportedDevices())) {
- return null;
+ return Collections.emptyList();
}
final UsbDeviceConnection connection = manager.openDevice(usbDevice);
if (connection == null) {
- return null;
+ return Collections.emptyList();
}
- return new Cp2102SerialDriver(usbDevice, connection);
+ final UsbSerialDriver driver = new Cp2102SerialDriver(usbDevice, connection);
+ return Collections.singletonList(driver);
}
};
/**
- * Builds a new {@link UsbSerialDriver} instance from the raw device, or
- * returns null
if it could not be built (for example, if the
- * probe failed).
+ * Tests the supplied {@link UsbDevice} for compatibility with this enum
+ * member, returning one or more driver instances if compatible.
*
* @param manager the {@link UsbManager} to use
* @param usbDevice the raw {@link UsbDevice} to use
- * @return the first available {@link UsbSerialDriver}, or {@code null} if
- * no devices could be acquired
+ * @return zero or more {@link UsbSerialDriver}, depending on compatibility
+ * (never {@code null}).
*/
- public abstract UsbSerialDriver getDevice(final UsbManager manager, final UsbDevice usbDevice);
+ protected abstract List probe(final UsbManager manager, final UsbDevice usbDevice);
/**
- * Acquires and returns the first available serial device among all
- * available {@link UsbDevice}s, or returns {@code null} if no device could
- * be acquired.
+ * Creates and returns a new {@link UsbSerialDriver} instance for the first
+ * compatible {@link UsbDevice} found on the bus. If none are found,
+ * returns {@code null}.
*
- * @param usbManager the {@link UsbManager} to use
+ *
+ * The order of devices is undefined, therefore if there are multiple
+ * devices on the bus, the chosen device may not be predictable (clients
+ * should use {@link #findAllDevices(UsbManager)} instead).
+ *
+ * @param usbManager the {@link UsbManager} to use.
* @return the first available {@link UsbSerialDriver}, or {@code null} if
- * no devices could be acquired
+ * none are available.
*/
- public static UsbSerialDriver acquire(final UsbManager usbManager) {
+ public static UsbSerialDriver findFirstDevice(final UsbManager usbManager) {
for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
- final UsbSerialDriver probedDevice = acquire(usbManager, usbDevice);
- if (probedDevice != null) {
- return probedDevice;
+ for (final UsbSerialProber prober : values()) {
+ final List probedDevices = prober.probe(usbManager, usbDevice);
+ if (!probedDevices.isEmpty()) {
+ return probedDevices.get(0);
+ }
}
}
return null;
}
/**
- * Builds and returns a new {@link UsbSerialDriver} from the given
- * {@link UsbDevice}, or returns {@code null} if no drivers supported this
- * device.
+ * Creates a new {@link UsbSerialDriver} instance for all compatible
+ * {@link UsbDevice}s found on the bus. If no compatible devices are found,
+ * the list will be empty.
*
- * @param usbManager the {@link UsbManager} to use
- * @param usbDevice the {@link UsbDevice} to use
- * @return a new {@link UsbSerialDriver}, or {@code null} if no devices
- * could be acquired
+ * @param usbManager
+ * @return
*/
- public static UsbSerialDriver acquire(final UsbManager usbManager, final UsbDevice usbDevice) {
+ public static List findAllDevices(final UsbManager usbManager) {
+ final List result = new ArrayList();
+
+ // For each UsbDevice, call probe() for each prober.
+ for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
+ result.addAll(probeSingleDevice(usbManager, usbDevice));
+ }
+ return result;
+ }
+
+ /**
+ * Special method for testing a specific device for driver support,
+ * returning any compatible driver(s).
+ *
+ *
+ * Clients should ordinarily use {@link #findAllDevices(UsbManager)}, which
+ * operates against the entire bus of devices. This method is useful when
+ * testing against only a single target is desired.
+ *
+ * @param usbManager the {@link UsbManager} to use.
+ * @param usbDevice the device to test against.
+ * @return a list containing zero or more {@link UsbSerialDriver} instances.
+ */
+ public static List probeSingleDevice(final UsbManager usbManager,
+ UsbDevice usbDevice) {
+ final List result = new ArrayList();
for (final UsbSerialProber prober : values()) {
- final UsbSerialDriver probedDevice = prober.getDevice(usbManager, usbDevice);
- if (probedDevice != null) {
- return probedDevice;
- }
+ final List probedDevices = prober.probe(usbManager, usbDevice);
+ result.addAll(probedDevices);
+ }
+ return result;
+ }
+
+ /**
+ * Deprecated; Use {@link #findFirstDevice(UsbManager)}.
+ *
+ * @param usbManager
+ * @return
+ */
+ @Deprecated
+ public static UsbSerialDriver acquire(final UsbManager usbManager) {
+ return findFirstDevice(usbManager);
+ }
+
+ /**
+ * Deprecated; use {@link #probeSingleDevice(UsbManager, UsbDevice)}.
+ *
+ * @param usbManager
+ * @param usbDevice
+ * @return
+ */
+ @Deprecated
+ public static UsbSerialDriver acquire(final UsbManager usbManager, final UsbDevice usbDevice) {
+ final List probedDevices = probeSingleDevice(usbManager, usbDevice);
+ if (!probedDevices.isEmpty()) {
+ return probedDevices.get(0);
}
return null;
}
/**
- * Returns {@code true} if the given device is found in the vendor/product map.
+ * Returns {@code true} if the given device is found in the driver's
+ * vendor/product map.
*
* @param usbDevice the device to test
- * @param supportedDevices map of vendor ids to product id(s)
+ * @param supportedDevices map of vendor IDs to product ID(s)
* @return {@code true} if supported
*/
private static boolean testIfSupported(final UsbDevice usbDevice,