mirror of
				https://github.com/mik3y/usb-serial-for-android
				synced 2025-10-31 10:27:27 +00:00 
			
		
		
		
	probe CDC devices by USB interface types instead of fixed VID+PID
- no more custom prober required for standard CDC devices - legacy (singleInterface) CDC devices still have to be added by VID+PID - for autostart VID+PID still have to be added to device_filter.xml
This commit is contained in:
		
							parent
							
								
									85f64aff96
								
							
						
					
					
						commit
						5db45548ba
					
				
							
								
								
									
										13
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								README.md
									
									
									
									
									
								
							| @ -124,22 +124,23 @@ new device or for one using a custom VID/PID pair. | |||||||
| UsbSerialProber is a class to help you find and instantiate compatible | UsbSerialProber is a class to help you find and instantiate compatible | ||||||
| UsbSerialDrivers from the tree of connected UsbDevices.  Normally, you will use | UsbSerialDrivers from the tree of connected UsbDevices.  Normally, you will use | ||||||
| the default prober returned by ``UsbSerialProber.getDefaultProber()``, which | the default prober returned by ``UsbSerialProber.getDefaultProber()``, which | ||||||
| uses the built-in list of well-known VIDs and PIDs that are supported by our | uses USB interface types and the built-in list of well-known VIDs and PIDs that | ||||||
| drivers. | are supported by our drivers. | ||||||
| 
 | 
 | ||||||
| To use your own set of rules, create and use a custom prober: | To use your own set of rules, create and use a custom prober: | ||||||
| 
 | 
 | ||||||
| ```java | ```java | ||||||
| // Probe for our custom CDC devices, which use VID 0x1234 | // Probe for our custom FTDI device, which use VID 0x1234 and PID 0x0001 and 0x0002. | ||||||
| // and PIDS 0x0001 and 0x0002. |  | ||||||
| ProbeTable customTable = new ProbeTable(); | ProbeTable customTable = new ProbeTable(); | ||||||
| customTable.addProduct(0x1234, 0x0001, CdcAcmSerialDriver.class); | customTable.addProduct(0x1234, 0x0001, FtdiSerialDriver.class); | ||||||
| customTable.addProduct(0x1234, 0x0002, CdcAcmSerialDriver.class); | customTable.addProduct(0x1234, 0x0002, FtdiSerialDriver.class); | ||||||
| 
 | 
 | ||||||
| UsbSerialProber prober = new UsbSerialProber(customTable); | UsbSerialProber prober = new UsbSerialProber(customTable); | ||||||
| List<UsbSerialDriver> drivers = prober.findAllDrivers(usbManager); | List<UsbSerialDriver> drivers = prober.findAllDrivers(usbManager); | ||||||
| // ... | // ... | ||||||
| ``` | ``` | ||||||
|  | *Note*: as of v3.5.0 this library detects CDC devices by USB interface types instead of fixed VID+PID, | ||||||
|  | so custom probers are typically not required any more for CDC devices. | ||||||
| 
 | 
 | ||||||
| Of course, nothing requires you to use UsbSerialProber at all: you can | Of course, nothing requires you to use UsbSerialProber at all: you can | ||||||
| instantiate driver classes directly if you know what you're doing; just supply | instantiate driver classes directly if you know what you're doing; just supply | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| package com.hoho.android.usbserial.examples; | package com.hoho.android.usbserial.examples; | ||||||
| 
 | 
 | ||||||
| import com.hoho.android.usbserial.driver.CdcAcmSerialDriver; | import com.hoho.android.usbserial.driver.FtdiSerialDriver; | ||||||
| import com.hoho.android.usbserial.driver.ProbeTable; | import com.hoho.android.usbserial.driver.ProbeTable; | ||||||
| import com.hoho.android.usbserial.driver.UsbSerialProber; | import com.hoho.android.usbserial.driver.UsbSerialProber; | ||||||
| 
 | 
 | ||||||
| @ -14,7 +14,8 @@ class CustomProber { | |||||||
| 
 | 
 | ||||||
|     static UsbSerialProber getCustomProber() { |     static UsbSerialProber getCustomProber() { | ||||||
|         ProbeTable customTable = new ProbeTable(); |         ProbeTable customTable = new ProbeTable(); | ||||||
|         customTable.addProduct(0x16d0, 0x087e, CdcAcmSerialDriver.class); // e.g. Digispark CDC |         customTable.addProduct(0x1234, 0x0001, FtdiSerialDriver.class); // e.g. device with custom VID+PID | ||||||
|  |         customTable.addProduct(0x1234, 0x0002, FtdiSerialDriver.class); // e.g. device with custom VID+PID | ||||||
|         return new UsbSerialProber(customTable); |         return new UsbSerialProber(customTable); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -37,7 +37,21 @@ public class CdcAcmSerialDriver implements UsbSerialDriver { | |||||||
|     public CdcAcmSerialDriver(UsbDevice device) { |     public CdcAcmSerialDriver(UsbDevice device) { | ||||||
|         mDevice = device; |         mDevice = device; | ||||||
|         mPorts = new ArrayList<>(); |         mPorts = new ArrayList<>(); | ||||||
|  |         int ports = countPorts(device); | ||||||
|  |         for (int port = 0; port < ports; port++) { | ||||||
|  |             mPorts.add(new CdcAcmSerialPort(mDevice, port)); | ||||||
|  |         } | ||||||
|  |         if (mPorts.size() == 0) { | ||||||
|  |             mPorts.add(new CdcAcmSerialPort(mDevice, -1)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|  |     @SuppressWarnings({"unused"}) | ||||||
|  |     public static boolean probe(UsbDevice device) { | ||||||
|  |         return countPorts(device) > 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static int countPorts(UsbDevice device) { | ||||||
|         int controlInterfaceCount = 0; |         int controlInterfaceCount = 0; | ||||||
|         int dataInterfaceCount = 0; |         int dataInterfaceCount = 0; | ||||||
|         for (int i = 0; i < device.getInterfaceCount(); i++) { |         for (int i = 0; i < device.getInterfaceCount(); i++) { | ||||||
| @ -46,12 +60,7 @@ public class CdcAcmSerialDriver implements UsbSerialDriver { | |||||||
|             if (device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) |             if (device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) | ||||||
|                 dataInterfaceCount++; |                 dataInterfaceCount++; | ||||||
|         } |         } | ||||||
|         for( int port = 0; port < Math.min(controlInterfaceCount, dataInterfaceCount); port++) { |         return Math.min(controlInterfaceCount, dataInterfaceCount); | ||||||
|             mPorts.add(new CdcAcmSerialPort(mDevice, port)); |  | ||||||
|         } |  | ||||||
|         if(mPorts.size() == 0) { |  | ||||||
|             mPorts.add(new CdcAcmSerialPort(mDevice, -1)); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
| @ -297,51 +306,9 @@ public class CdcAcmSerialDriver implements UsbSerialDriver { | |||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @SuppressWarnings({"unused"}) | ||||||
|     public static Map<Integer, int[]> getSupportedDevices() { |     public static Map<Integer, int[]> getSupportedDevices() { | ||||||
|         final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>(); |         return new LinkedHashMap<>(); | ||||||
|         supportedDevices.put(UsbId.VENDOR_ARDUINO, |  | ||||||
|                 new int[] { |  | ||||||
|                         UsbId.ARDUINO_UNO, |  | ||||||
|                         UsbId.ARDUINO_UNO_R3, |  | ||||||
|                         UsbId.ARDUINO_MEGA_2560, |  | ||||||
|                         UsbId.ARDUINO_MEGA_2560_R3, |  | ||||||
|                         UsbId.ARDUINO_SERIAL_ADAPTER, |  | ||||||
|                         UsbId.ARDUINO_SERIAL_ADAPTER_R3, |  | ||||||
|                         UsbId.ARDUINO_MEGA_ADK, |  | ||||||
|                         UsbId.ARDUINO_MEGA_ADK_R3, |  | ||||||
|                         UsbId.ARDUINO_LEONARDO, |  | ||||||
|                         UsbId.ARDUINO_MICRO, |  | ||||||
|                 }); |  | ||||||
|         supportedDevices.put(UsbId.VENDOR_VAN_OOIJEN_TECH, |  | ||||||
|                 new int[] { |  | ||||||
|                         UsbId.VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL, |  | ||||||
|                 }); |  | ||||||
|         supportedDevices.put(UsbId.VENDOR_ATMEL, |  | ||||||
|                 new int[] { |  | ||||||
|                         UsbId.ATMEL_LUFA_CDC_DEMO_APP, |  | ||||||
|                 }); |  | ||||||
|         supportedDevices.put(UsbId.VENDOR_LEAFLABS, |  | ||||||
|                 new int[] { |  | ||||||
|                         UsbId.LEAFLABS_MAPLE, |  | ||||||
|                 }); |  | ||||||
|         supportedDevices.put(UsbId.VENDOR_ARM, |  | ||||||
|                 new int[] { |  | ||||||
|                         UsbId.ARM_MBED, |  | ||||||
|                 }); |  | ||||||
|         supportedDevices.put(UsbId.VENDOR_ST, |  | ||||||
|                 new int[] { |  | ||||||
|                         UsbId.ST_CDC, |  | ||||||
|                 }); |  | ||||||
|         supportedDevices.put(UsbId.VENDOR_RASPBERRY_PI, |  | ||||||
|                 new int[] { |  | ||||||
|                         UsbId.RASPBERRY_PI_PICO_MICROPYTHON, |  | ||||||
|                         UsbId.RASPBERRY_PI_PICO_SDK, |  | ||||||
|                 }); |  | ||||||
|         supportedDevices.put(UsbId.VENDOR_QINHENG, |  | ||||||
|                 new int[] { |  | ||||||
|                         UsbId.QINHENG_CH9102F, |  | ||||||
|                 }); |  | ||||||
|         return supportedDevices; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -374,6 +374,7 @@ public class Ch34xSerialDriver implements UsbSerialDriver { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@SuppressWarnings({"unused"}) | ||||||
| 	public static Map<Integer, int[]> getSupportedDevices() { | 	public static Map<Integer, int[]> getSupportedDevices() { | ||||||
| 		final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>(); | 		final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>(); | ||||||
| 		supportedDevices.put(UsbId.VENDOR_QINHENG, new int[]{ | 		supportedDevices.put(UsbId.VENDOR_QINHENG, new int[]{ | ||||||
|  | |||||||
| @ -320,6 +320,7 @@ public class Cp21xxSerialDriver implements UsbSerialDriver { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @SuppressWarnings({"unused"}) | ||||||
|     public static Map<Integer, int[]> getSupportedDevices() { |     public static Map<Integer, int[]> getSupportedDevices() { | ||||||
|         final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>(); |         final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>(); | ||||||
|         supportedDevices.put(UsbId.VENDOR_SILABS, |         supportedDevices.put(UsbId.VENDOR_SILABS, | ||||||
|  | |||||||
| @ -414,6 +414,7 @@ public class FtdiSerialDriver implements UsbSerialDriver { | |||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @SuppressWarnings({"unused"}) | ||||||
|     public static Map<Integer, int[]> getSupportedDevices() { |     public static Map<Integer, int[]> getSupportedDevices() { | ||||||
|         final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>(); |         final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>(); | ||||||
|         supportedDevices.put(UsbId.VENDOR_FTDI, |         supportedDevices.put(UsbId.VENDOR_FTDI, | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ | |||||||
| 
 | 
 | ||||||
| package com.hoho.android.usbserial.driver; | package com.hoho.android.usbserial.driver; | ||||||
| 
 | 
 | ||||||
|  | import android.hardware.usb.UsbDevice; | ||||||
| import android.util.Pair; | import android.util.Pair; | ||||||
| 
 | 
 | ||||||
| import java.lang.reflect.InvocationTargetException; | import java.lang.reflect.InvocationTargetException; | ||||||
| @ -14,14 +15,14 @@ import java.util.LinkedHashMap; | |||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Maps (vendor id, product id) pairs to the corresponding serial driver. |  * Maps (vendor id, product id) pairs to the corresponding serial driver, | ||||||
|  * |  * or invoke 'probe' method to check actual USB devices for matching interfaces. | ||||||
|  * @author mike wakerly (opensource@hoho.com) |  | ||||||
|  */ |  */ | ||||||
| public class ProbeTable { | public class ProbeTable { | ||||||
| 
 | 
 | ||||||
|     private final Map<Pair<Integer, Integer>, Class<? extends UsbSerialDriver>> mProbeTable = |     private final Map<Pair<Integer, Integer>, Class<? extends UsbSerialDriver>> mVidPidProbeTable = | ||||||
|             new LinkedHashMap<>(); |             new LinkedHashMap<>(); | ||||||
|  |     private final Map<Method, Class<? extends UsbSerialDriver>> mMethodProbeTable = new LinkedHashMap<>(); | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Adds or updates a (vendor, product) pair in the table. |      * Adds or updates a (vendor, product) pair in the table. | ||||||
| @ -33,7 +34,7 @@ public class ProbeTable { | |||||||
|      */ |      */ | ||||||
|     public ProbeTable addProduct(int vendorId, int productId, |     public ProbeTable addProduct(int vendorId, int productId, | ||||||
|             Class<? extends UsbSerialDriver> driverClass) { |             Class<? extends UsbSerialDriver> driverClass) { | ||||||
|         mProbeTable.put(Pair.create(vendorId, productId), driverClass); |         mVidPidProbeTable.put(Pair.create(vendorId, productId), driverClass); | ||||||
|         return this; |         return this; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -41,12 +42,11 @@ public class ProbeTable { | |||||||
|      * Internal method to add all supported products from |      * Internal method to add all supported products from | ||||||
|      * {@code getSupportedProducts} static method. |      * {@code getSupportedProducts} static method. | ||||||
|      * |      * | ||||||
|      * @param driverClass |      * @param driverClass to be added | ||||||
|      * @return |  | ||||||
|      */ |      */ | ||||||
|     @SuppressWarnings("unchecked") |     @SuppressWarnings("unchecked") | ||||||
|     ProbeTable addDriver(Class<? extends UsbSerialDriver> driverClass) { |     void addDriver(Class<? extends UsbSerialDriver> driverClass) { | ||||||
|         final Method method; |         Method method; | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|             method = driverClass.getMethod("getSupportedDevices"); |             method = driverClass.getMethod("getSupportedDevices"); | ||||||
| @ -68,20 +68,35 @@ public class ProbeTable { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return this; |         try { | ||||||
|  |             method = driverClass.getMethod("probe", UsbDevice.class); | ||||||
|  |             mMethodProbeTable.put(method, driverClass); | ||||||
|  |         } catch (SecurityException | NoSuchMethodException ignored) { | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Returns the driver for the given (vendor, product) pair, or {@code null} |      * Returns the driver for the given USB device, or {@code null} if no match. | ||||||
|      * if no match. |  | ||||||
|      * |      * | ||||||
|      * @param vendorId the USB vendor id |      * @param usbDevice the USB device to be probed | ||||||
|      * @param productId the USB product id |  | ||||||
|      * @return the driver class matching this pair, or {@code null} |      * @return the driver class matching this pair, or {@code null} | ||||||
|      */ |      */ | ||||||
|     public Class<? extends UsbSerialDriver> findDriver(int vendorId, int productId) { |     public Class<? extends UsbSerialDriver> findDriver(final UsbDevice usbDevice) { | ||||||
|         final Pair<Integer, Integer> pair = Pair.create(vendorId, productId); |         final Pair<Integer, Integer> pair = Pair.create(usbDevice.getVendorId(), usbDevice.getProductId()); | ||||||
|         return mProbeTable.get(pair); |         Class<? extends UsbSerialDriver> driverClass = mVidPidProbeTable.get(pair); | ||||||
|  |         if (driverClass != null) | ||||||
|  |             return driverClass; | ||||||
|  |         for (Map.Entry<Method, Class<? extends UsbSerialDriver>> entry : mMethodProbeTable.entrySet()) { | ||||||
|  |             try { | ||||||
|  |                 Method method = entry.getKey(); | ||||||
|  |                 Object o = method.invoke(null, usbDevice); | ||||||
|  |                 if((boolean)o) | ||||||
|  |                     return entry.getValue(); | ||||||
|  |             } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { | ||||||
|  |                 throw new RuntimeException(e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -566,6 +566,7 @@ public class ProlificSerialDriver implements UsbSerialDriver { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @SuppressWarnings({"unused"}) | ||||||
|     public static Map<Integer, int[]> getSupportedDevices() { |     public static Map<Integer, int[]> getSupportedDevices() { | ||||||
|         final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>(); |         final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>(); | ||||||
|         supportedDevices.put(UsbId.VENDOR_PROLIFIC, |         supportedDevices.put(UsbId.VENDOR_PROLIFIC, | ||||||
|  | |||||||
| @ -23,27 +23,6 @@ public final class UsbId { | |||||||
|     public static final int FTDI_FT232H = 0x6014; |     public static final int FTDI_FT232H = 0x6014; | ||||||
|     public static final int FTDI_FT231X = 0x6015; // same ID for FT230X, FT231X, FT234XD |     public static final int FTDI_FT231X = 0x6015; // same ID for FT230X, FT231X, FT234XD | ||||||
| 
 | 
 | ||||||
|     public static final int VENDOR_ATMEL = 0x03EB; |  | ||||||
|     public static final int ATMEL_LUFA_CDC_DEMO_APP = 0x2044; |  | ||||||
| 
 |  | ||||||
|     public static final int VENDOR_ARDUINO = 0x2341; |  | ||||||
|     public static final int ARDUINO_UNO = 0x0001; |  | ||||||
|     public static final int ARDUINO_MEGA_2560 = 0x0010; |  | ||||||
|     public static final int ARDUINO_SERIAL_ADAPTER = 0x003b; |  | ||||||
|     public static final int ARDUINO_MEGA_ADK = 0x003f; |  | ||||||
|     public static final int ARDUINO_MEGA_2560_R3 = 0x0042; |  | ||||||
|     public static final int ARDUINO_UNO_R3 = 0x0043; |  | ||||||
|     public static final int ARDUINO_MEGA_ADK_R3 = 0x0044; |  | ||||||
|     public static final int ARDUINO_SERIAL_ADAPTER_R3 = 0x0044; |  | ||||||
|     public static final int ARDUINO_LEONARDO = 0x8036; |  | ||||||
|     public static final int ARDUINO_MICRO = 0x8037; |  | ||||||
| 
 |  | ||||||
|     public static final int VENDOR_VAN_OOIJEN_TECH = 0x16c0; |  | ||||||
|     public static final int VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL = 0x0483; |  | ||||||
| 
 |  | ||||||
|     public static final int VENDOR_LEAFLABS = 0x1eaf; |  | ||||||
|     public static final int LEAFLABS_MAPLE = 0x0004; |  | ||||||
| 
 |  | ||||||
|     public static final int VENDOR_SILABS = 0x10c4; |     public static final int VENDOR_SILABS = 0x10c4; | ||||||
|     public static final int SILABS_CP2102 = 0xea60; // same ID for CP2101, CP2103, CP2104, CP2109 |     public static final int SILABS_CP2102 = 0xea60; // same ID for CP2101, CP2103, CP2104, CP2109 | ||||||
|     public static final int SILABS_CP2105 = 0xea70; |     public static final int SILABS_CP2105 = 0xea70; | ||||||
| @ -61,18 +40,7 @@ public final class UsbId { | |||||||
|     public static final int VENDOR_QINHENG = 0x1a86; |     public static final int VENDOR_QINHENG = 0x1a86; | ||||||
|     public static final int QINHENG_CH340 = 0x7523; |     public static final int QINHENG_CH340 = 0x7523; | ||||||
|     public static final int QINHENG_CH341A = 0x5523; |     public static final int QINHENG_CH341A = 0x5523; | ||||||
|     public static final int QINHENG_CH9102F = 0x55D4; |  | ||||||
| 
 | 
 | ||||||
|     // at www.linux-usb.org/usb.ids listed for NXP/LPC1768, but all processors supported by ARM mbed DAPLink firmware report these ids |  | ||||||
|     public static final int VENDOR_ARM = 0x0d28; |  | ||||||
|     public static final int ARM_MBED = 0x0204; |  | ||||||
| 
 |  | ||||||
|     public static final int VENDOR_ST = 0x0483; |  | ||||||
|     public static final int ST_CDC = 0x5740; |  | ||||||
| 
 |  | ||||||
|     public static final int VENDOR_RASPBERRY_PI = 0x2e8a; |  | ||||||
|     public static final int RASPBERRY_PI_PICO_MICROPYTHON = 0x0005; |  | ||||||
|     public static final int RASPBERRY_PI_PICO_SDK = 0x000a; |  | ||||||
| 
 | 
 | ||||||
|     private UsbId() { |     private UsbId() { | ||||||
|         throw new IllegalAccessError("Non-instantiable class"); |         throw new IllegalAccessError("Non-instantiable class"); | ||||||
|  | |||||||
| @ -10,12 +10,17 @@ import android.hardware.usb.UsbDevice; | |||||||
| 
 | 
 | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| /** |  | ||||||
|  * |  | ||||||
|  * @author mike wakerly (opensource@hoho.com) |  | ||||||
|  */ |  | ||||||
| public interface UsbSerialDriver { | public interface UsbSerialDriver { | ||||||
| 
 | 
 | ||||||
|  |     /* | ||||||
|  |      * Additional interface properties. Invoked thru reflection. | ||||||
|  |      * | ||||||
|  |         UsbSerialDriver(UsbDevice device);                  // constructor with device | ||||||
|  |         static Map<Integer, int[]> getSupportedDevices(); | ||||||
|  |         static boolean probe(UsbDevice device);             // optional | ||||||
|  |      */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Returns the raw {@link UsbDevice} backing this port. |      * Returns the raw {@link UsbDevice} backing this port. | ||||||
|      * |      * | ||||||
|  | |||||||
| @ -69,11 +69,7 @@ public class UsbSerialProber { | |||||||
|      *         {@code null} if none available. |      *         {@code null} if none available. | ||||||
|      */ |      */ | ||||||
|     public UsbSerialDriver probeDevice(final UsbDevice usbDevice) { |     public UsbSerialDriver probeDevice(final UsbDevice usbDevice) { | ||||||
|         final int vendorId = usbDevice.getVendorId(); |         final Class<? extends UsbSerialDriver> driverClass = mProbeTable.findDriver(usbDevice); | ||||||
|         final int productId = usbDevice.getProductId(); |  | ||||||
| 
 |  | ||||||
|         final Class<? extends UsbSerialDriver> driverClass = |  | ||||||
|                 mProbeTable.findDriver(vendorId, productId); |  | ||||||
|         if (driverClass != null) { |         if (driverClass != null) { | ||||||
|             final UsbSerialDriver driver; |             final UsbSerialDriver driver; | ||||||
|             try { |             try { | ||||||
|  | |||||||
							
								
								
									
										85
									
								
								usbSerialForAndroid/src/test/java/android/util/Pair.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								usbSerialForAndroid/src/test/java/android/util/Pair.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,85 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (C) 2009 The Android Open Source Project | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  * you may not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *      http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package android.util; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | import androidx.annotation.Nullable; | ||||||
|  | 
 | ||||||
|  | import java.util.Objects; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Container to ease passing around a tuple of two objects. This object provides a sensible | ||||||
|  |  * implementation of equals(), returning true if equals() is true on each of the contained | ||||||
|  |  * objects. | ||||||
|  |  */ | ||||||
|  | public class Pair<F, S> { | ||||||
|  |     public final F first; | ||||||
|  |     public final S second; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Constructor for a Pair. | ||||||
|  |      * | ||||||
|  |      * @param first the first object in the Pair | ||||||
|  |      * @param second the second object in the pair | ||||||
|  |      */ | ||||||
|  |     public Pair(F first, S second) { | ||||||
|  |         this.first = first; | ||||||
|  |         this.second = second; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Checks the two objects for equality by delegating to their respective | ||||||
|  |      * {@link Object#equals(Object)} methods. | ||||||
|  |      * | ||||||
|  |      * @param o the {@link Pair} to which this one is to be checked for equality | ||||||
|  |      * @return true if the underlying objects of the Pair are both considered | ||||||
|  |      *         equal | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public boolean equals(@Nullable Object o) { | ||||||
|  |         if (!(o instanceof Pair)) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         Pair<?, ?> p = (Pair<?, ?>) o; | ||||||
|  |         return Objects.equals(p.first, first) && Objects.equals(p.second, second); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Compute a hash code using the hash codes of the underlying objects | ||||||
|  |      * | ||||||
|  |      * @return a hashcode of the Pair | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public int hashCode() { | ||||||
|  |         return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return "Pair{" + String.valueOf(first) + " " + String.valueOf(second) + "}"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Convenience method for creating an appropriately typed pair. | ||||||
|  |      * @param a the first object in the Pair | ||||||
|  |      * @param b the second object in the pair | ||||||
|  |      * @return a Pair that is templatized with the types of a and b | ||||||
|  |      */ | ||||||
|  |     public static <A, B> Pair <A, B> create(A a, B b) { | ||||||
|  |         return new Pair<A, B>(a, b); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -53,6 +53,10 @@ public class CdcAcmSerialDriverTest { | |||||||
|         port.openInt(); |         port.openInt(); | ||||||
|         assertEquals(readEndpoint, port.mReadEndpoint); |         assertEquals(readEndpoint, port.mReadEndpoint); | ||||||
|         assertEquals(writeEndpoint, port.mWriteEndpoint); |         assertEquals(writeEndpoint, port.mWriteEndpoint); | ||||||
|  | 
 | ||||||
|  |         ProbeTable probeTable = UsbSerialProber.getDefaultProbeTable(); | ||||||
|  |         Class<? extends UsbSerialDriver> probeDriver = probeTable.findDriver(usbDevice); | ||||||
|  |         assertEquals(driver.getClass(), probeDriver); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
| @ -84,6 +88,10 @@ public class CdcAcmSerialDriverTest { | |||||||
|         port.openInt(); |         port.openInt(); | ||||||
|         assertEquals(readEndpoint, port.mReadEndpoint); |         assertEquals(readEndpoint, port.mReadEndpoint); | ||||||
|         assertEquals(writeEndpoint, port.mWriteEndpoint); |         assertEquals(writeEndpoint, port.mWriteEndpoint); | ||||||
|  | 
 | ||||||
|  |         ProbeTable probeTable = UsbSerialProber.getDefaultProbeTable(); | ||||||
|  |         Class<? extends UsbSerialDriver> probeDriver = probeTable.findDriver(usbDevice); | ||||||
|  |         assertNull(probeDriver); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user