diff options
-rw-r--r-- | api/current.txt | 3 | ||||
-rw-r--r-- | core/java/android/hardware/usb/UsbDevice.java | 49 | ||||
-rw-r--r-- | services/java/com/android/server/usb/UsbHostManager.java | 4 | ||||
-rw-r--r-- | services/java/com/android/server/usb/UsbSettingsManager.java | 169 | ||||
-rw-r--r-- | services/jni/com_android_server_UsbHostManager.cpp | 14 |
5 files changed, 206 insertions, 33 deletions
diff --git a/api/current.txt b/api/current.txt index 8e69592..2bd9c05 100644 --- a/api/current.txt +++ b/api/current.txt @@ -11027,7 +11027,10 @@ package android.hardware.usb { method public int getDeviceSubclass(); method public android.hardware.usb.UsbInterface getInterface(int); method public int getInterfaceCount(); + method public java.lang.String getManufacturerName(); method public int getProductId(); + method public java.lang.String getProductName(); + method public java.lang.String getSerialNumber(); method public int getVendorId(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java index 9bd38f9..d1e63f6 100644 --- a/core/java/android/hardware/usb/UsbDevice.java +++ b/core/java/android/hardware/usb/UsbDevice.java @@ -46,6 +46,9 @@ public class UsbDevice implements Parcelable { private static final String TAG = "UsbDevice"; private final String mName; + private final String mManufacturerName; + private final String mProductName; + private final String mSerialNumber; private final int mVendorId; private final int mProductId; private final int mClass; @@ -58,13 +61,18 @@ public class UsbDevice implements Parcelable { * @hide */ public UsbDevice(String name, int vendorId, int productId, - int Class, int subClass, int protocol, Parcelable[] interfaces) { + int Class, int subClass, int protocol, + String manufacturerName, String productName, String serialNumber, + Parcelable[] interfaces) { mName = name; mVendorId = vendorId; mProductId = productId; mClass = Class; mSubclass = subClass; mProtocol = protocol; + mManufacturerName = manufacturerName; + mProductName = productName; + mSerialNumber = serialNumber; mInterfaces = interfaces; } @@ -80,6 +88,33 @@ public class UsbDevice implements Parcelable { } /** + * Returns the manufacturer name of the device. + * + * @return the manufacturer name + */ + public String getManufacturerName() { + return mManufacturerName; + } + + /** + * Returns the product name of the device. + * + * @return the product name + */ + public String getProductName() { + return mProductName; + } + + /** + * Returns the serial number of the device. + * + * @return the serial number name + */ + public String getSerialNumber() { + return mSerialNumber; + } + + /** * Returns a unique integer ID for the device. * This is a convenience for clients that want to use an integer to represent * the device, rather than the device name. @@ -176,7 +211,8 @@ public class UsbDevice implements Parcelable { return "UsbDevice[mName=" + mName + ",mVendorId=" + mVendorId + ",mProductId=" + mProductId + ",mClass=" + mClass + ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol + - ",mInterfaces=" + mInterfaces + "]"; + ",mManufacturerName=" + mManufacturerName + ",mProductName=" + mProductName + + ",mSerialNumber=" + mSerialNumber + ",mInterfaces=" + mInterfaces + "]"; } public static final Parcelable.Creator<UsbDevice> CREATOR = @@ -188,8 +224,12 @@ public class UsbDevice implements Parcelable { int clasz = in.readInt(); int subClass = in.readInt(); int protocol = in.readInt(); + String manufacturerName = in.readString(); + String productName = in.readString(); + String serialNumber = in.readString(); Parcelable[] interfaces = in.readParcelableArray(UsbInterface.class.getClassLoader()); - return new UsbDevice(name, vendorId, productId, clasz, subClass, protocol, interfaces); + return new UsbDevice(name, vendorId, productId, clasz, subClass, protocol, + manufacturerName, productName, serialNumber, interfaces); } public UsbDevice[] newArray(int size) { @@ -208,6 +248,9 @@ public class UsbDevice implements Parcelable { parcel.writeInt(mClass); parcel.writeInt(mSubclass); parcel.writeInt(mProtocol); + parcel.writeString(mManufacturerName); + parcel.writeString(mProductName); + parcel.writeString(mSerialNumber); parcel.writeParcelableArray(mInterfaces, 0); } diff --git a/services/java/com/android/server/usb/UsbHostManager.java b/services/java/com/android/server/usb/UsbHostManager.java index 10272f2..dfaad0b 100644 --- a/services/java/com/android/server/usb/UsbHostManager.java +++ b/services/java/com/android/server/usb/UsbHostManager.java @@ -96,6 +96,7 @@ public class UsbHostManager { /* Called from JNI in monitorUsbHostBus() to report new USB devices */ private void usbDeviceAdded(String deviceName, int vendorID, int productID, int deviceClass, int deviceSubclass, int deviceProtocol, + String manufacturerName, String productName, String serialNumber, /* array of quintuples containing id, class, subclass, protocol and number of endpoints for each interface */ int[] interfaceValues, @@ -151,7 +152,8 @@ public class UsbHostManager { } UsbDevice device = new UsbDevice(deviceName, vendorID, productID, - deviceClass, deviceSubclass, deviceProtocol, interfaces); + deviceClass, deviceSubclass, deviceProtocol, + manufacturerName, productName, serialNumber, interfaces); mDevices.put(deviceName, device); getCurrentSettings().deviceAttached(device); } diff --git a/services/java/com/android/server/usb/UsbSettingsManager.java b/services/java/com/android/server/usb/UsbSettingsManager.java index 9b5b312..ff4857b 100644 --- a/services/java/com/android/server/usb/UsbSettingsManager.java +++ b/services/java/com/android/server/usb/UsbSettingsManager.java @@ -108,13 +108,23 @@ class UsbSettingsManager { public final int mSubclass; // USB device protocol (or -1 for unspecified) public final int mProtocol; - - public DeviceFilter(int vid, int pid, int clasz, int subclass, int protocol) { + // USB device manufacturer name string (or null for unspecified) + public final String mManufacturerName; + // USB device product name string (or null for unspecified) + public final String mProductName; + // USB device serial number string (or null for unspecified) + public final String mSerialNumber; + + public DeviceFilter(int vid, int pid, int clasz, int subclass, int protocol, + String manufacturer, String product, String serialnum) { mVendorId = vid; mProductId = pid; mClass = clasz; mSubclass = subclass; mProtocol = protocol; + mManufacturerName = manufacturer; + mProductName = product; + mSerialNumber = serialnum; } public DeviceFilter(UsbDevice device) { @@ -123,6 +133,9 @@ class UsbSettingsManager { mClass = device.getDeviceClass(); mSubclass = device.getDeviceSubclass(); mProtocol = device.getDeviceProtocol(); + mManufacturerName = device.getManufacturerName(); + mProductName = device.getProductName(); + mSerialNumber = device.getSerialNumber(); } public static DeviceFilter read(XmlPullParser parser) @@ -132,27 +145,52 @@ class UsbSettingsManager { int deviceClass = -1; int deviceSubclass = -1; int deviceProtocol = -1; + String manufacturerName = null; + String productName = null; + String serialNumber = null; int count = parser.getAttributeCount(); for (int i = 0; i < count; i++) { String name = parser.getAttributeName(i); - // All attribute values are ints - int value = Integer.parseInt(parser.getAttributeValue(i)); - - if ("vendor-id".equals(name)) { - vendorId = value; - } else if ("product-id".equals(name)) { - productId = value; - } else if ("class".equals(name)) { - deviceClass = value; - } else if ("subclass".equals(name)) { - deviceSubclass = value; - } else if ("protocol".equals(name)) { - deviceProtocol = value; + String value = parser.getAttributeValue(i); + // Attribute values are ints or strings + if ("manufacturer-name".equals(name)) { + manufacturerName = value; + } else if ("product-name".equals(name)) { + productName = value; + } else if ("serial-number".equals(name)) { + serialNumber = value; + } else { + int intValue = -1; + int radix = 10; + if (value != null && value.length() > 2 && value.charAt(0) == '0' && + (value.charAt(1) == 'x' || value.charAt(1) == 'X')) { + // allow hex values starting with 0x or 0X + radix = 16; + value = value.substring(2); + } + try { + intValue = Integer.parseInt(value, radix); + } catch (NumberFormatException e) { + Slog.e(TAG, "invalid number for field " + name, e); + continue; + } + if ("vendor-id".equals(name)) { + vendorId = intValue; + } else if ("product-id".equals(name)) { + productId = intValue; + } else if ("class".equals(name)) { + deviceClass = intValue; + } else if ("subclass".equals(name)) { + deviceSubclass = intValue; + } else if ("protocol".equals(name)) { + deviceProtocol = intValue; + } } } return new DeviceFilter(vendorId, productId, - deviceClass, deviceSubclass, deviceProtocol); + deviceClass, deviceSubclass, deviceProtocol, + manufacturerName, productName, serialNumber); } public void write(XmlSerializer serializer) throws IOException { @@ -172,6 +210,15 @@ class UsbSettingsManager { if (mProtocol != -1) { serializer.attribute(null, "protocol", Integer.toString(mProtocol)); } + if (mManufacturerName != null) { + serializer.attribute(null, "manufacturer-name", mManufacturerName); + } + if (mProductName != null) { + serializer.attribute(null, "product-name", mProductName); + } + if (mSerialNumber != null) { + serializer.attribute(null, "serial-number", mSerialNumber); + } serializer.endTag(null, "usb-device"); } @@ -184,6 +231,15 @@ class UsbSettingsManager { public boolean matches(UsbDevice device) { if (mVendorId != -1 && device.getVendorId() != mVendorId) return false; if (mProductId != -1 && device.getProductId() != mProductId) return false; + if (mManufacturerName != null && device.getManufacturerName() == null) return false; + if (mProductName != null && device.getProductName() == null) return false; + if (mSerialNumber != null && device.getSerialNumber() == null) return false; + if (mManufacturerName != null && device.getManufacturerName() != null && + !mManufacturerName.equals(device.getManufacturerName())) return false; + if (mProductName != null && device.getProductName() != null && + !mProductName.equals(device.getProductName())) return false; + if (mSerialNumber != null && device.getSerialNumber() != null && + !mSerialNumber.equals(device.getSerialNumber())) return false; // check device class/subclass/protocol if (matches(device.getDeviceClass(), device.getDeviceSubclass(), @@ -203,6 +259,15 @@ class UsbSettingsManager { public boolean matches(DeviceFilter f) { if (mVendorId != -1 && f.mVendorId != mVendorId) return false; if (mProductId != -1 && f.mProductId != mProductId) return false; + if (f.mManufacturerName != null && mManufacturerName == null) return false; + if (f.mProductName != null && mProductName == null) return false; + if (f.mSerialNumber != null && mSerialNumber == null) return false; + if (mManufacturerName != null && f.mManufacturerName != null && + !mManufacturerName.equals(f.mManufacturerName)) return false; + if (mProductName != null && f.mProductName != null && + !mProductName.equals(f.mProductName)) return false; + if (mSerialNumber != null && f.mSerialNumber != null && + !mSerialNumber.equals(f.mSerialNumber)) return false; // check device class/subclass/protocol return matches(f.mClass, f.mSubclass, f.mProtocol); @@ -217,19 +282,67 @@ class UsbSettingsManager { } if (obj instanceof DeviceFilter) { DeviceFilter filter = (DeviceFilter)obj; - return (filter.mVendorId == mVendorId && - filter.mProductId == mProductId && - filter.mClass == mClass && - filter.mSubclass == mSubclass && - filter.mProtocol == mProtocol); + + if (filter.mVendorId != mVendorId || + filter.mProductId != mProductId || + filter.mClass != mClass || + filter.mSubclass != mSubclass || + filter.mProtocol != mProtocol) { + return(false); + } + if ((filter.mManufacturerName != null && + mManufacturerName == null) || + (filter.mManufacturerName == null && + mManufacturerName != null) || + (filter.mProductName != null && + mProductName == null) || + (filter.mProductName == null && + mProductName != null) || + (filter.mSerialNumber != null && + mSerialNumber == null) || + (filter.mSerialNumber == null && + mSerialNumber != null)) { + return(false); + } + if ((filter.mManufacturerName != null && + mManufacturerName != null && + !mManufacturerName.equals(filter.mManufacturerName)) || + (filter.mProductName != null && + mProductName != null && + !mProductName.equals(filter.mProductName)) || + (filter.mSerialNumber != null && + mSerialNumber != null && + !mSerialNumber.equals(filter.mSerialNumber))) { + return(false); + } + return(true); } if (obj instanceof UsbDevice) { UsbDevice device = (UsbDevice)obj; - return (device.getVendorId() == mVendorId && - device.getProductId() == mProductId && - device.getDeviceClass() == mClass && - device.getDeviceSubclass() == mSubclass && - device.getDeviceProtocol() == mProtocol); + if (device.getVendorId() != mVendorId || + device.getProductId() != mProductId || + device.getDeviceClass() != mClass || + device.getDeviceSubclass() != mSubclass || + device.getDeviceProtocol() != mProtocol) { + return(false); + } + if ((mManufacturerName != null && device.getManufacturerName() == null) || + (mManufacturerName == null && device.getManufacturerName() != null) || + (mProductName != null && device.getProductName() == null) || + (mProductName == null && device.getProductName() != null) || + (mSerialNumber != null && device.getSerialNumber() == null) || + (mSerialNumber == null && device.getSerialNumber() != null)) { + return(false); + } + if ((device.getManufacturerName() != null && + !mManufacturerName.equals(device.getManufacturerName())) || + (device.getProductName() != null && + !mProductName.equals(device.getProductName())) || + (device.getSerialNumber() != null && + !mSerialNumber.equals(device.getSerialNumber()))) { + return(false); + } + return true; } return false; } @@ -244,7 +357,9 @@ class UsbSettingsManager { public String toString() { return "DeviceFilter[mVendorId=" + mVendorId + ",mProductId=" + mProductId + ",mClass=" + mClass + ",mSubclass=" + mSubclass + - ",mProtocol=" + mProtocol + "]"; + ",mProtocol=" + mProtocol + ",mManufacturerName=" + mManufacturerName + + ",mProductName=" + mProductName + ",mSerialNumber=" + mSerialNumber + + "]"; } } diff --git a/services/jni/com_android_server_UsbHostManager.cpp b/services/jni/com_android_server_UsbHostManager.cpp index 639790b..f1fa6cf 100644 --- a/services/jni/com_android_server_UsbHostManager.cpp +++ b/services/jni/com_android_server_UsbHostManager.cpp @@ -73,6 +73,9 @@ static int usb_device_added(const char *devname, void* client_data) { uint8_t deviceClass = deviceDesc->bDeviceClass; uint8_t deviceSubClass = deviceDesc->bDeviceSubClass; uint8_t protocol = deviceDesc->bDeviceProtocol; + char *manufacturer = usb_device_get_manufacturer_name(device); + char *product = usb_device_get_product_name(device); + char *serial = usb_device_get_serial(device); usb_descriptor_iter_init(device, &iter); @@ -109,12 +112,19 @@ static int usb_device_added(const char *devname, void* client_data) { env->SetIntArrayRegion(endpointArray, 0, length, endpointValues.array()); jstring deviceName = env->NewStringUTF(devname); + jstring manufacturerName = env->NewStringUTF(manufacturer); + jstring productName = env->NewStringUTF(product); + jstring serialNumber = env->NewStringUTF(serial); env->CallVoidMethod(thiz, method_usbDeviceAdded, deviceName, vendorId, productId, deviceClass, - deviceSubClass, protocol, interfaceArray, endpointArray); + deviceSubClass, protocol, manufacturerName, + productName, serialNumber, interfaceArray, endpointArray); env->DeleteLocalRef(interfaceArray); env->DeleteLocalRef(endpointArray); + env->DeleteLocalRef(serialNumber); + env->DeleteLocalRef(productName); + env->DeleteLocalRef(manufacturerName); env->DeleteLocalRef(deviceName); checkAndClearExceptionFromCallback(env, __FUNCTION__); @@ -179,7 +189,7 @@ int register_android_server_UsbHostManager(JNIEnv *env) ALOGE("Can't find com/android/server/usb/UsbHostManager"); return -1; } - method_usbDeviceAdded = env->GetMethodID(clazz, "usbDeviceAdded", "(Ljava/lang/String;IIIII[I[I)V"); + method_usbDeviceAdded = env->GetMethodID(clazz, "usbDeviceAdded", "(Ljava/lang/String;IIIIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[I[I)V"); if (method_usbDeviceAdded == NULL) { ALOGE("Can't find usbDeviceAdded"); return -1; |