Added support for claiming individiual interfaces on USB devices on Android
This is needed for supporting multiple wireless Xbox 360 controllers
diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDevice.java b/android-project/app/src/main/java/org/libsdl/app/HIDDevice.java
index aa358d1..955df5d 100644
--- a/android-project/app/src/main/java/org/libsdl/app/HIDDevice.java
+++ b/android-project/app/src/main/java/org/libsdl/app/HIDDevice.java
@@ -1,5 +1,7 @@
package org.libsdl.app;
+import android.hardware.usb.UsbDevice;
+
interface HIDDevice
{
public int getId();
@@ -9,6 +11,7 @@
public int getVersion();
public String getManufacturerName();
public String getProductName();
+ public UsbDevice getDevice();
public boolean open();
public int sendFeatureReport(byte[] report);
public int sendOutputReport(byte[] report);
diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java
index 51538fa..7e104b6 100644
--- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java
+++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java
@@ -9,6 +9,7 @@
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothGattService;
+import android.hardware.usb.UsbDevice;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
@@ -563,6 +564,11 @@
return "Steam Controller";
}
+ @Override
+ public UsbDevice getDevice() {
+ return null;
+ }
+
@Override
public boolean open() {
return true;
diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java
index bdd14aa..38ed444 100644
--- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java
+++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java
@@ -19,8 +19,9 @@
import android.os.Handler;
import android.os.Looper;
-import java.util.HashMap;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
public class HIDDeviceManager {
@@ -50,7 +51,6 @@
private Context mContext;
private HashMap<Integer, HIDDevice> mDevicesById = new HashMap<Integer, HIDDevice>();
- private HashMap<UsbDevice, HIDDeviceUSB> mUSBDevices = new HashMap<UsbDevice, HIDDeviceUSB>();
private HashMap<BluetoothDevice, HIDDeviceBLESteamController> mBluetoothDevices = new HashMap<BluetoothDevice, HIDDeviceBLESteamController>();
private int mNextDeviceId = 0;
private SharedPreferences mSharedPreferences = null;
@@ -337,27 +337,30 @@
}
private void handleUsbDeviceDetached(UsbDevice usbDevice) {
- HIDDeviceUSB device = mUSBDevices.get(usbDevice);
- if (device == null)
- return;
-
- int id = device.getId();
- mUSBDevices.remove(usbDevice);
- mDevicesById.remove(id);
- device.shutdown();
- HIDDeviceDisconnected(id);
+ List<Integer> devices = new ArrayList<Integer>();
+ for (HIDDevice device : mDevicesById.values()) {
+ if (usbDevice.equals(device.getDevice())) {
+ devices.add(device.getId());
+ }
+ }
+ for (int id : devices) {
+ HIDDevice device = mDevicesById.get(id);
+ mDevicesById.remove(id);
+ device.shutdown();
+ HIDDeviceDisconnected(id);
+ }
}
private void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) {
- HIDDeviceUSB device = mUSBDevices.get(usbDevice);
- if (device == null)
- return;
-
- boolean opened = false;
- if (permission_granted) {
- opened = device.open();
+ for (HIDDevice device : mDevicesById.values()) {
+ if (usbDevice.equals(device.getDevice())) {
+ boolean opened = false;
+ if (permission_granted) {
+ opened = device.open();
+ }
+ HIDDeviceOpenResult(device.getId(), opened);
+ }
}
- HIDDeviceOpenResult(device.getId(), opened);
}
private void connectHIDDeviceUSB(UsbDevice usbDevice) {
@@ -366,10 +369,8 @@
if (isHIDDeviceInterface(usbDevice, interface_number)) {
HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_number);
int id = device.getId();
- mUSBDevices.put(usbDevice, device);
mDevicesById.put(id, device);
HIDDeviceConnected(id, device.getIdentifier(), device.getVendorId(), device.getProductId(), device.getSerialNumber(), device.getVersion(), device.getManufacturerName(), device.getProductName(), interface_number);
- break;
}
}
}
@@ -566,33 +567,27 @@
//////////////////////////////////////////////////////////////////////////////////////////////////////
public boolean openDevice(int deviceID) {
+ Log.v(TAG, "openDevice deviceID=" + deviceID);
+ HIDDevice device = getDevice(deviceID);
+ if (device == null) {
+ HIDDeviceDisconnected(deviceID);
+ return false;
+ }
+
// Look to see if this is a USB device and we have permission to access it
- for (HIDDeviceUSB device : mUSBDevices.values()) {
- if (deviceID == device.getId()) {
- UsbDevice usbDevice = device.getDevice();
- if (!mUsbManager.hasPermission(usbDevice)) {
- HIDDeviceOpenPending(deviceID);
- try {
- mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), 0));
- } catch (Exception e) {
- Log.v(TAG, "Couldn't request permission for USB device " + usbDevice);
- HIDDeviceOpenResult(deviceID, false);
- }
- return false;
- }
- break;
+ UsbDevice usbDevice = device.getDevice();
+ if (usbDevice != null && !mUsbManager.hasPermission(usbDevice)) {
+ HIDDeviceOpenPending(deviceID);
+ try {
+ mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), 0));
+ } catch (Exception e) {
+ Log.v(TAG, "Couldn't request permission for USB device " + usbDevice);
+ HIDDeviceOpenResult(deviceID, false);
}
+ return false;
}
try {
- Log.v(TAG, "openDevice deviceID=" + deviceID);
- HIDDevice device;
- device = getDevice(deviceID);
- if (device == null) {
- HIDDeviceDisconnected(deviceID);
- return false;
- }
-
return device.open();
} catch (Exception e) {
Log.e(TAG, "Got exception: " + Log.getStackTraceString(e));
@@ -602,7 +597,7 @@
public int sendOutputReport(int deviceID, byte[] report) {
try {
- Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length);
+ //Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length);
HIDDevice device;
device = getDevice(deviceID);
if (device == null) {
@@ -619,7 +614,7 @@
public int sendFeatureReport(int deviceID, byte[] report) {
try {
- Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length);
+ //Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length);
HIDDevice device;
device = getDevice(deviceID);
if (device == null) {
@@ -636,7 +631,7 @@
public boolean getFeatureReport(int deviceID, byte[] report) {
try {
- Log.v(TAG, "getFeatureReport deviceID=" + deviceID);
+ //Log.v(TAG, "getFeatureReport deviceID=" + deviceID);
HIDDevice device;
device = getDevice(deviceID);
if (device == null) {
diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java
index c9fc58e..e3e0936 100644
--- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java
+++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java
@@ -29,7 +29,7 @@
}
public String getIdentifier() {
- return String.format("%s/%x/%x", mDevice.getDeviceName(), mDevice.getVendorId(), mDevice.getProductId());
+ return String.format("%s/%x/%x/%d", mDevice.getDeviceName(), mDevice.getVendorId(), mDevice.getProductId(), mInterface);
}
@Override
@@ -88,6 +88,7 @@
return result;
}
+ @Override
public UsbDevice getDevice() {
return mDevice;
}
@@ -104,19 +105,15 @@
return false;
}
- // Force claim all interfaces
- for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
- UsbInterface iface = mDevice.getInterface(i);
-
- if (!mConnection.claimInterface(iface, true)) {
- Log.w(TAG, "Failed to claim interfaces on USB device " + getDeviceName());
- close();
- return false;
- }
+ // Force claim our interface
+ UsbInterface iface = mDevice.getInterface(mInterface);
+ if (!mConnection.claimInterface(iface, true)) {
+ Log.w(TAG, "Failed to claim interfaces on USB device " + getDeviceName());
+ close();
+ return false;
}
// Find the endpoints
- UsbInterface iface = mDevice.getInterface(mInterface);
for (int j = 0; j < iface.getEndpointCount(); j++) {
UsbEndpoint endpt = iface.getEndpoint(j);
switch (endpt.getDirection()) {
@@ -250,10 +247,8 @@
mInputThread = null;
}
if (mConnection != null) {
- for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
- UsbInterface iface = mDevice.getInterface(i);
- mConnection.releaseInterface(iface);
- }
+ UsbInterface iface = mDevice.getInterface(mInterface);
+ mConnection.releaseInterface(iface);
mConnection.close();
mConnection = null;
}