summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml13
-rw-r--r--core/java/android/hardware/UsbConstants.java5
-rw-r--r--core/res/res/values/config.xml8
-rw-r--r--services/java/com/android/server/UsbService.java50
4 files changed, 65 insertions, 11 deletions
diff --git a/api/current.xml b/api/current.xml
index 4a4a355c0bfa..8366600d7a50 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -94408,6 +94408,17 @@
visibility="public"
>
</field>
+<field name="USB_INTERFACE_SUBCLASS_BOOT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="USB_SUBCLASS_VENDOR_SPEC"
type="int"
transient="false"
@@ -263792,7 +263803,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
</parameter>
</method>
</interface>
diff --git a/core/java/android/hardware/UsbConstants.java b/core/java/android/hardware/UsbConstants.java
index 29a335cdbed8..4c8c4d4db9dc 100644
--- a/core/java/android/hardware/UsbConstants.java
+++ b/core/java/android/hardware/UsbConstants.java
@@ -41,6 +41,7 @@ public final class UsbConstants {
public static final int USB_ENDPOINT_XFER_BULK = 2;
public static final int USB_ENDPOINT_XFER_INT = 3;
+ // USB classes
public static final int USB_CLASS_PER_INTERFACE = 0;
public static final int USB_CLASS_AUDIO = 1;
public static final int USB_CLASS_COMM = 2;
@@ -58,6 +59,8 @@ public final class UsbConstants {
public static final int USB_CLASS_MISC = 0xef;
public static final int USB_CLASS_APP_SPEC = 0xfe;
public static final int USB_CLASS_VENDOR_SPEC = 0xff;
- public static final int USB_SUBCLASS_VENDOR_SPEC = 0xff;
+ // USB subclasses
+ public static final int USB_INTERFACE_SUBCLASS_BOOT = 1; // for HID class
+ public static final int USB_SUBCLASS_VENDOR_SPEC = 0xff;
} \ No newline at end of file
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 713fa8e96284..0edd33e35c86 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -284,6 +284,14 @@
<!-- Indicate whether the device has USB host support. -->
<bool name="config_hasUsbHostSupport">false</bool>
+ <!-- List of file paths for USB host busses to exclude from USB host support.
+ For example, if the first USB bus on the device is used to communicate
+ with the modem or some other restricted hardware, add "/dev/bus/usb/001/"
+ to this list. If this is empty, no parts of the host USB bus will be excluded.
+ -->
+ <string-array name="config_usbHostBlacklist">
+ </string-array>
+
<!-- Vibrator pattern for feedback about a long screen/key press -->
<integer-array name="config_longPressVibePattern">
<item>0</item>
diff --git a/services/java/com/android/server/UsbService.java b/services/java/com/android/server/UsbService.java
index 5c03fb2a76e4..460fd4d5eb7c 100644
--- a/services/java/com/android/server/UsbService.java
+++ b/services/java/com/android/server/UsbService.java
@@ -83,6 +83,9 @@ class UsbService extends IUsbManager.Stub {
private final HashMap<String,UsbDevice> mDevices = new HashMap<String,UsbDevice>();
+ // USB busses to exclude from USB host support
+ private final String[] mHostBlacklist;
+
private boolean mSystemReady;
private final Context mContext;
@@ -143,6 +146,9 @@ class UsbService extends IUsbManager.Stub {
public UsbService(Context context) {
mContext = context;
+ mHostBlacklist = context.getResources().getStringArray(
+ com.android.internal.R.array.config_usbHostBlacklist);
+
init(); // set initial status
if (mConfiguration >= 0) {
@@ -197,6 +203,29 @@ class UsbService extends IUsbManager.Stub {
}
}
+ private boolean isBlackListed(String deviceName) {
+ int count = mHostBlacklist.length;
+ for (int i = 0; i < count; i++) {
+ if (deviceName.startsWith(mHostBlacklist[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isBlackListed(int clazz, int subClass, int protocol) {
+ // blacklist hubs
+ if (clazz == UsbConstants.USB_CLASS_HUB) return true;
+
+ // blacklist HID boot devices (mouse and keyboard)
+ if (clazz == UsbConstants.USB_CLASS_HID &&
+ subClass == UsbConstants.USB_INTERFACE_SUBCLASS_BOOT) {
+ return true;
+ }
+
+ return false;
+ }
+
// called from JNI in monitorUsbHostBus()
private void usbDeviceAdded(String deviceName, int vendorID, int productID,
int deviceClass, int deviceSubclass, int deviceProtocol,
@@ -207,8 +236,8 @@ class UsbService extends IUsbManager.Stub {
and interval for each endpoint */
int[] endpointValues) {
- // ignore hubs
- if (deviceClass == UsbConstants.USB_CLASS_HUB) {
+ if (isBlackListed(deviceName) ||
+ isBlackListed(deviceClass, deviceSubclass, deviceProtocol)) {
return;
}
@@ -223,7 +252,6 @@ class UsbService extends IUsbManager.Stub {
try {
// repackage interfaceValues as an array of UsbInterface
int intf, endp, ival = 0, eval = 0;
- boolean hasGoodInterface = false;
for (intf = 0; intf < numInterfaces; intf++) {
int interfaceId = interfaceValues[ival++];
int interfaceClass = interfaceValues[ival++];
@@ -241,16 +269,13 @@ class UsbService extends IUsbManager.Stub {
maxPacketSize, interval);
}
- if (interfaceClass != UsbConstants.USB_CLASS_HUB) {
- hasGoodInterface = true;
+ // don't allow if any interfaces are blacklisted
+ if (isBlackListed(interfaceClass, interfaceSubclass, interfaceProtocol)) {
+ return;
}
interfaces[intf] = new UsbInterface(interfaceId, interfaceClass,
interfaceSubclass, interfaceProtocol, endpoints);
}
-
- if (!hasGoodInterface) {
- return;
- }
} catch (Exception e) {
// beware of index out of bound exceptions, which might happen if
// a device does not set bNumEndpoints correctly
@@ -328,7 +353,14 @@ class UsbService extends IUsbManager.Stub {
}
public ParcelFileDescriptor openDevice(String deviceName) {
+ if (isBlackListed(deviceName)) {
+ throw new SecurityException("USB device is on a restricted bus");
+ }
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
+ if (mDevices.get(deviceName) == null) {
+ // if it is not in mDevices, it either does not exist or is blacklisted
+ throw new IllegalArgumentException("device " + deviceName + " does not exist or is restricted");
+ }
return nativeOpenDevice(deviceName);
}