/* Copyright 2011-2013 Google Inc.
 * Copyright 2013 mike wakerly <opensource@hoho.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
 * USA.
 *
 * Project home page: https://github.com/mik3y/usb-serial-for-android
 */

package com.hoho.android.usbserial.driver;

import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author mike wakerly (opensource@hoho.com)
 */
public class UsbSerialProber {

    private final ProbeTable mProbeTable;

    public UsbSerialProber(ProbeTable probeTable) {
        mProbeTable = probeTable;
    }

    public static UsbSerialProber getDefaultProber() {
        return new UsbSerialProber(getDefaultProbeTable());
    }
    
    public static ProbeTable getDefaultProbeTable() {
        final ProbeTable probeTable = new ProbeTable();
        probeTable.addDriver(CdcAcmSerialDriver.class);
        probeTable.addDriver(Cp21xxSerialDriver.class);
        probeTable.addDriver(FtdiSerialDriver.class);
        probeTable.addDriver(ProlificSerialDriver.class);
        return probeTable;
    }

    /**
     * Finds and builds all possible {@link UsbSerialDriver UsbSerialDrivers}
     * from the currently-attached {@link UsbDevice} hierarchy. This method does
     * not require permission from the Android USB system, since it does not
     * open any of the devices.
     *
     * @param usbManager
     * @return a list, possibly empty, of all compatible drivers
     */
    public List<UsbSerialDriver> findAllDrivers(final UsbManager usbManager) {
        final List<UsbSerialDriver> result = new ArrayList<UsbSerialDriver>();

        for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
            final int vendorId = usbDevice.getVendorId();
            final int productId = usbDevice.getProductId();

            final Class<? extends UsbSerialDriver> driverClass =
                    mProbeTable.findDriver(vendorId, productId);
            if (driverClass != null) {
                final UsbSerialDriver driver;
                try {
                    final Constructor<? extends UsbSerialDriver> ctor =
                            driverClass.getConstructor(UsbDevice.class);
                    driver = ctor.newInstance(usbDevice);
                } catch (NoSuchMethodException e) {
                    throw new RuntimeException(e);
                } catch (IllegalArgumentException e) {
                    throw new RuntimeException(e);
                } catch (InstantiationException e) {
                    throw new RuntimeException(e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
                result.add(driver);
            }
        }
        return result;
    }

}

@@ -2508,32 +2508,542 @@
 values()) %7B%0A    
+        final UsbSerialDriver driver = probeDevice(usbDevice);%0A            if (driver != null) %7B%0A                result.add(driver);%0A            %7D%0A        %7D%0A        return result;%0A    %7D%0A    %0A    /**%0A     * Probes a single device for a compatible driver.%0A     * %0A     * @param usbDevice the usb device to probe%0A     * @return a new %7B@link UsbSerialDriver%7D compatible with this device, or%0A     *         %7B@code null%7D if none available.%0A     */%0A    public UsbSerialDriver probeDevice(final UsbDevice usbDevice) %7B%0A
         final in
@@ -3084,28 +3084,24 @@
 ();%0A        
-    
 final int pr
@@ -3133,28 +3133,24 @@
 oductId();%0A%0A
-    
         fina
@@ -3210,28 +3210,24 @@
             
-    
 mProbeTable.
@@ -3259,36 +3259,32 @@
 uctId);%0A        
-    
 if (driverClass 
@@ -3286,36 +3286,32 @@
 lass != null) %7B%0A
-    
             fina
@@ -3352,22 +3352,14 @@
     
-    
 try %7B%0A
-    
     
@@ -3442,28 +3442,24 @@
             
-    
 driverClass.
@@ -3503,28 +3503,24 @@
             
-    
 driver = cto
@@ -3549,36 +3549,32 @@
 e);%0A            
-    
 %7D catch (NoSuchM
@@ -3585,36 +3585,32 @@
 dException e) %7B%0A
-    
                 
@@ -3644,36 +3644,32 @@
 e);%0A            
-    
 %7D catch (Illegal
@@ -3699,36 +3699,32 @@
                 
-    
 throw new Runtim
@@ -3730,36 +3730,32 @@
 meException(e);%0A
-    
             %7D ca
@@ -3795,36 +3795,32 @@
                 
-    
 throw new Runtim
@@ -3826,36 +3826,32 @@
 meException(e);%0A
-    
             %7D ca
@@ -3891,36 +3891,32 @@
                 
-    
 throw new Runtim
@@ -3934,36 +3934,32 @@
 e);%0A            
-    
 %7D catch (Invocat
@@ -3990,36 +3990,32 @@
                 
-    
 throw new Runtim
@@ -4037,34 +4037,26 @@
             
-    %7D%0A    
+%7D%0A
             
@@ -4061,40 +4061,21 @@
   re
-sult.add(
+turn 
 driver
-)
 ;%0A
-            %7D%0A
     
@@ -4087,33 +4087,31 @@
 %0A        return 
-result
+null
 ;%0A    %7D%0A%0A%7D%0A

Add ProbeDevice.