package com.fwupgrade.saymanss.deviceplug; import android.content.Context; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbInterface; import android.text.TextUtils; import android.util.Log; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; public final class CDeviceFilter { private static final String TAG = "CDeviceFilter"; public final int mVendorId; public final int mProductId; public final int mClass; public final int mSubclass; public final int mProtocol; public final String mManufacturerName; public final String mProductName; public final String mSerialNumber; public CDeviceFilter(int vid, int pid, int clasz, int subclass, int protocol, String manufacturer, String product, String serialnum) { this.mVendorId = vid; this.mProductId = pid; this.mClass = clasz; this.mSubclass = subclass; this.mProtocol = protocol; this.mManufacturerName = manufacturer; this.mProductName = product; this.mSerialNumber = serialnum; } public CDeviceFilter(UsbDevice device) { this.mVendorId = device.getVendorId(); this.mProductId = device.getProductId(); this.mClass = device.getDeviceClass(); this.mSubclass = device.getDeviceSubclass(); this.mProtocol = device.getDeviceProtocol(); this.mManufacturerName = null; this.mProductName = null; this.mSerialNumber = null; } public static List getDeviceFilters(Context context, int deviceFilterXmlId) { XmlResourceParser xmlResourceParser = context.getResources().getXml(deviceFilterXmlId); List deviceFilters = new ArrayList<>(); try { int eventType = xmlResourceParser.getEventType(); while (eventType != 1) { if (eventType == 2) { CDeviceFilter deviceFilter = read(context, (XmlPullParser)xmlResourceParser); if (deviceFilter != null) deviceFilters.add(deviceFilter); } eventType = xmlResourceParser.next(); } } catch (XmlPullParserException e) { Log.d("CDeviceFilter", "XmlPullParserException", (Throwable)e); } catch (IOException e) { Log.d("CDeviceFilter", "IOException", e); } return Collections.unmodifiableList(deviceFilters); } private static final int getAttributeInteger(Context context, XmlPullParser parser, String namespace, String name, int defaultValue) { int result = defaultValue; try { String v = parser.getAttributeValue(namespace, name); if (!TextUtils.isEmpty(v) && v.startsWith("@")) { String r = v.substring(1); int resId = context.getResources().getIdentifier(r, null, context.getPackageName()); if (resId > 0) result = context.getResources().getInteger(resId); } else { int radix = 10; if (v != null && v.length() > 2 && v.charAt(0) == '0' && (v .charAt(1) == 'x' || v.charAt(1) == 'X')) { radix = 16; v = v.substring(2); } result = Integer.parseInt(v, radix); } } catch (Resources.NotFoundException e) { result = defaultValue; } catch (NumberFormatException e) { result = defaultValue; } catch (NullPointerException e) { result = defaultValue; } return result; } private static final String getAttributeString(Context context, XmlPullParser parser, String namespace, String name, String defaultValue) { String result = defaultValue; try { result = parser.getAttributeValue(namespace, name); if (result == null) result = defaultValue; if (!TextUtils.isEmpty(result) && result.startsWith("@")) { String r = result.substring(1); int resId = context.getResources().getIdentifier(r, null, context.getPackageName()); if (resId > 0) result = context.getResources().getString(resId); } } catch (Resources.NotFoundException e) { result = defaultValue; } catch (NumberFormatException e) { result = defaultValue; } catch (NullPointerException e) { result = defaultValue; } return result; } public static CDeviceFilter read(Context context, XmlPullParser parser) throws XmlPullParserException, IOException { int vendorId = -1; int productId = -1; int deviceClass = -1; int deviceSubclass = -1; int deviceProtocol = -1; String manufacturerName = null; String productName = null; String serialNumber = null; boolean hasValue = false; int eventType = parser.getEventType(); while (eventType != 1) { String tag = parser.getName(); if (!TextUtils.isEmpty(tag) && tag.equalsIgnoreCase("usb-device")) if (eventType == 2) { hasValue = true; vendorId = getAttributeInteger(context, parser, null, "vendor-id", -1); if (vendorId == -1) { vendorId = getAttributeInteger(context, parser, null, "vendorId", -1); if (vendorId == -1) vendorId = getAttributeInteger(context, parser, null, "venderId", -1); } productId = getAttributeInteger(context, parser, null, "product-id", -1); if (productId == -1) productId = getAttributeInteger(context, parser, null, "productId", -1); deviceClass = getAttributeInteger(context, parser, null, "class", -1); deviceSubclass = getAttributeInteger(context, parser, null, "subclass", -1); deviceProtocol = getAttributeInteger(context, parser, null, "protocol", -1); manufacturerName = getAttributeString(context, parser, null, "manufacturer-name", null); if (TextUtils.isEmpty(manufacturerName)) manufacturerName = getAttributeString(context, parser, null, "manufacture", null); productName = getAttributeString(context, parser, null, "product-name", null); if (TextUtils.isEmpty(productName)) productName = getAttributeString(context, parser, null, "product", null); serialNumber = getAttributeString(context, parser, null, "serial-number", null); if (TextUtils.isEmpty(serialNumber)) serialNumber = getAttributeString(context, parser, null, "serial", null); } else if (eventType == 3 && hasValue) { return new CDeviceFilter(vendorId, productId, deviceClass, deviceSubclass, deviceProtocol, manufacturerName, productName, serialNumber); } eventType = parser.next(); } return null; } private boolean matches(int clasz, int subclass, int protocol) { return ((this.mClass == -1 || clasz == this.mClass) && (this.mSubclass == -1 || subclass == this.mSubclass) && (this.mProtocol == -1 || protocol == this.mProtocol)); } public boolean matches(UsbDevice device) { if (this.mVendorId != -1 && device.getVendorId() != this.mVendorId) return false; if (this.mProductId != -1 && device.getProductId() != this.mProductId) return false; if (matches(device.getDeviceClass(), device.getDeviceSubclass(), device .getDeviceProtocol())) return true; int count = device.getInterfaceCount(); for (int i = 0; i < count; i++) { UsbInterface intf = device.getInterface(i); if (matches(intf.getInterfaceClass(), intf.getInterfaceSubclass(), intf .getInterfaceProtocol())) return true; } return false; } public boolean matches(CDeviceFilter f) { if (this.mVendorId != -1 && f.mVendorId != this.mVendorId) return false; if (this.mProductId != -1 && f.mProductId != this.mProductId) return false; if (f.mManufacturerName != null && this.mManufacturerName == null) return false; if (f.mProductName != null && this.mProductName == null) return false; if (f.mSerialNumber != null && this.mSerialNumber == null) return false; if (this.mManufacturerName != null && f.mManufacturerName != null && !this.mManufacturerName.equals(f.mManufacturerName)) return false; if (this.mProductName != null && f.mProductName != null && !this.mProductName.equals(f.mProductName)) return false; if (this.mSerialNumber != null && f.mSerialNumber != null && !this.mSerialNumber.equals(f.mSerialNumber)) return false; return matches(f.mClass, f.mSubclass, f.mProtocol); } public boolean equals(Object obj) { if (this.mVendorId == -1 || this.mProductId == -1 || this.mClass == -1 || this.mSubclass == -1 || this.mProtocol == -1) return false; if (obj instanceof CDeviceFilter) { CDeviceFilter filter = (CDeviceFilter)obj; if (filter.mVendorId != this.mVendorId || filter.mProductId != this.mProductId || filter.mClass != this.mClass || filter.mSubclass != this.mSubclass || filter.mProtocol != this.mProtocol) return false; if ((filter.mManufacturerName != null && this.mManufacturerName == null) || (filter.mManufacturerName == null && this.mManufacturerName != null) || (filter.mProductName != null && this.mProductName == null) || (filter.mProductName == null && this.mProductName != null) || (filter.mSerialNumber != null && this.mSerialNumber == null) || (filter.mSerialNumber == null && this.mSerialNumber != null)) return false; if ((filter.mManufacturerName != null && this.mManufacturerName != null && !this.mManufacturerName.equals(filter.mManufacturerName)) || (filter.mProductName != null && this.mProductName != null && !this.mProductName.equals(filter.mProductName)) || (filter.mSerialNumber != null && this.mSerialNumber != null && !this.mSerialNumber.equals(filter.mSerialNumber))) return false; return true; } if (obj instanceof UsbDevice) { UsbDevice device = (UsbDevice)obj; if (device.getVendorId() != this.mVendorId || device .getProductId() != this.mProductId || device .getDeviceClass() != this.mClass || device .getDeviceSubclass() != this.mSubclass || device .getDeviceProtocol() != this.mProtocol) return false; return true; } return false; } public int hashCode() { return (this.mVendorId << 16 | this.mProductId) ^ (this.mClass << 16 | this.mSubclass << 8 | this.mProtocol); } public String toString() { return "DeviceFilter[mVendorId=" + this.mVendorId + ",mProductId=" + this.mProductId + ",mClass=" + this.mClass + ",mSubclass=" + this.mSubclass + ",mProtocol=" + this.mProtocol + ",mManufacturerName=" + this.mManufacturerName + ",mProductName=" + this.mProductName + ",mSerialNumber=" + this.mSerialNumber + "]"; } }