Added support for claiming individiual interfaces on USB devices on Android This is needed for supporting multiple wireless Xbox 360 controllers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
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 @@ interface HIDDevice
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.BluetoothGattDescriptor;
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 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
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.hardware.usb.*;
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 @@ public class HIDDeviceManager {
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 @@ public class HIDDeviceManager {
}
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 @@ public class HIDDeviceManager {
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 class HIDDeviceManager {
//////////////////////////////////////////////////////////////////////////////////////////////////////
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 class HIDDeviceManager {
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 class HIDDeviceManager {
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 class HIDDeviceManager {
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 @@ class HIDDeviceUSB implements HIDDevice {
}
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 @@ class HIDDeviceUSB implements HIDDevice {
return result;
}
+ @Override
public UsbDevice getDevice() {
return mDevice;
}
@@ -104,19 +105,15 @@ class HIDDeviceUSB implements HIDDevice {
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 @@ class HIDDeviceUSB implements HIDDevice {
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;
}