19
19
import android .os .Handler ;
20
20
import android .os .Looper ;
21
21
22
- import java .util .HashMap ;
23
22
import java .util .ArrayList ;
23
+ import java .util .HashMap ;
24
+ import java .util .Iterator ;
24
25
import java .util .List ;
25
26
26
27
public class HIDDeviceManager {
@@ -50,7 +51,6 @@ public static void release(HIDDeviceManager manager) {
50
51
51
52
private Context mContext ;
52
53
private HashMap <Integer , HIDDevice > mDevicesById = new HashMap <Integer , HIDDevice >();
53
- private HashMap <UsbDevice , HIDDeviceUSB > mUSBDevices = new HashMap <UsbDevice , HIDDeviceUSB >();
54
54
private HashMap <BluetoothDevice , HIDDeviceBLESteamController > mBluetoothDevices = new HashMap <BluetoothDevice , HIDDeviceBLESteamController >();
55
55
private int mNextDeviceId = 0 ;
56
56
private SharedPreferences mSharedPreferences = null ;
@@ -241,31 +241,20 @@ private void shutdownUSB() {
241
241
}
242
242
}
243
243
244
- private boolean isHIDDeviceUSB (UsbDevice usbDevice ) {
245
- for (int interface_number = 0 ; interface_number < usbDevice .getInterfaceCount (); ++interface_number ) {
246
- if (isHIDDeviceInterface (usbDevice , interface_number )) {
247
- return true ;
248
- }
249
- }
250
- return false ;
251
- }
252
-
253
- private boolean isHIDDeviceInterface (UsbDevice usbDevice , int interface_number ) {
254
- UsbInterface usbInterface = usbDevice .getInterface (interface_number );
244
+ private boolean isHIDDeviceInterface (UsbDevice usbDevice , UsbInterface usbInterface ) {
255
245
if (usbInterface .getInterfaceClass () == UsbConstants .USB_CLASS_HID ) {
256
246
return true ;
257
247
}
258
- if (interface_number == 0 ) {
259
- if (isXbox360Controller (usbDevice , usbInterface ) || isXboxOneController (usbDevice , usbInterface )) {
260
- return true ;
261
- }
248
+ if (isXbox360Controller (usbDevice , usbInterface ) || isXboxOneController (usbDevice , usbInterface )) {
249
+ return true ;
262
250
}
263
251
return false ;
264
252
}
265
253
266
254
private boolean isXbox360Controller (UsbDevice usbDevice , UsbInterface usbInterface ) {
267
255
final int XB360_IFACE_SUBCLASS = 93 ;
268
- final int XB360_IFACE_PROTOCOL = 1 ; // Wired only
256
+ final int XB360_IFACE_PROTOCOL = 1 ; // Wired
257
+ final int XB360W_IFACE_PROTOCOL = 129 ; // Wireless
269
258
final int [] SUPPORTED_VENDORS = {
270
259
0x0079 , // GPD Win 2
271
260
0x044f , // Thrustmaster
@@ -275,8 +264,9 @@ private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterfa
275
264
0x06a3 , // Saitek
276
265
0x0738 , // Mad Catz
277
266
0x07ff , // Mad Catz
278
- 0x0e6f , // Unknown
267
+ 0x0e6f , // PDP
279
268
0x0f0d , // Hori
269
+ 0x1038 , // SteelSeries
280
270
0x11c9 , // Nacon
281
271
0x12ab , // Unknown
282
272
0x1430 , // RedOctane
@@ -291,7 +281,8 @@ private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterfa
291
281
292
282
if (usbInterface .getInterfaceClass () == UsbConstants .USB_CLASS_VENDOR_SPEC &&
293
283
usbInterface .getInterfaceSubclass () == XB360_IFACE_SUBCLASS &&
294
- usbInterface .getInterfaceProtocol () == XB360_IFACE_PROTOCOL ) {
284
+ (usbInterface .getInterfaceProtocol () == XB360_IFACE_PROTOCOL ||
285
+ usbInterface .getInterfaceProtocol () == XB360W_IFACE_PROTOCOL )) {
295
286
int vendor_id = usbDevice .getVendorId ();
296
287
for (int supportedVid : SUPPORTED_VENDORS ) {
297
288
if (vendor_id == supportedVid ) {
@@ -308,13 +299,15 @@ private boolean isXboxOneController(UsbDevice usbDevice, UsbInterface usbInterfa
308
299
final int [] SUPPORTED_VENDORS = {
309
300
0x045e , // Microsoft
310
301
0x0738 , // Mad Catz
311
- 0x0e6f , // Unknown
302
+ 0x0e6f , // PDP
312
303
0x0f0d , // Hori
313
304
0x1532 , // Razer Wildcat
314
305
0x24c6 , // PowerA
306
+ 0x2e24 , // Hyperkin
315
307
};
316
308
317
- if (usbInterface .getInterfaceClass () == UsbConstants .USB_CLASS_VENDOR_SPEC &&
309
+ if (usbInterface .getId () == 0 &&
310
+ usbInterface .getInterfaceClass () == UsbConstants .USB_CLASS_VENDOR_SPEC &&
318
311
usbInterface .getInterfaceSubclass () == XB1_IFACE_SUBCLASS &&
319
312
usbInterface .getInterfaceProtocol () == XB1_IFACE_PROTOCOL ) {
320
313
int vendor_id = usbDevice .getVendorId ();
@@ -328,45 +321,45 @@ private boolean isXboxOneController(UsbDevice usbDevice, UsbInterface usbInterfa
328
321
}
329
322
330
323
private void handleUsbDeviceAttached (UsbDevice usbDevice ) {
331
- if (isHIDDeviceUSB (usbDevice )) {
332
- connectHIDDeviceUSB (usbDevice );
333
- }
324
+ connectHIDDeviceUSB (usbDevice );
334
325
}
335
326
336
327
private void handleUsbDeviceDetached (UsbDevice usbDevice ) {
337
- HIDDeviceUSB device = mUSBDevices .get (usbDevice );
338
- if (device == null )
339
- return ;
340
-
341
- int id = device .getId ();
342
- mUSBDevices .remove (usbDevice );
343
- mDevicesById .remove (id );
344
- device .shutdown ();
345
- HIDDeviceDisconnected (id );
328
+ List <Integer > devices = new ArrayList <Integer >();
329
+ for (HIDDevice device : mDevicesById .values ()) {
330
+ if (usbDevice .equals (device .getDevice ())) {
331
+ devices .add (device .getId ());
332
+ }
333
+ }
334
+ for (int id : devices ) {
335
+ HIDDevice device = mDevicesById .get (id );
336
+ mDevicesById .remove (id );
337
+ device .shutdown ();
338
+ HIDDeviceDisconnected (id );
339
+ }
346
340
}
347
341
348
342
private void handleUsbDevicePermission (UsbDevice usbDevice , boolean permission_granted ) {
349
- HIDDeviceUSB device = mUSBDevices .get (usbDevice );
350
- if (device == null )
351
- return ;
352
-
353
- boolean opened = false ;
354
- if (permission_granted ) {
355
- opened = device .open ();
343
+ for (HIDDevice device : mDevicesById .values ()) {
344
+ if (usbDevice .equals (device .getDevice ())) {
345
+ boolean opened = false ;
346
+ if (permission_granted ) {
347
+ opened = device .open ();
348
+ }
349
+ HIDDeviceOpenResult (device .getId (), opened );
350
+ }
356
351
}
357
- HIDDeviceOpenResult (device .getId (), opened );
358
352
}
359
353
360
354
private void connectHIDDeviceUSB (UsbDevice usbDevice ) {
361
355
synchronized (this ) {
362
- for (int interface_number = 0 ; interface_number < usbDevice .getInterfaceCount (); interface_number ++) {
363
- if (isHIDDeviceInterface (usbDevice , interface_number )) {
364
- HIDDeviceUSB device = new HIDDeviceUSB (this , usbDevice , interface_number );
356
+ for (int interface_index = 0 ; interface_index < usbDevice .getInterfaceCount (); interface_index ++) {
357
+ UsbInterface usbInterface = usbDevice .getInterface (interface_index );
358
+ if (isHIDDeviceInterface (usbDevice , usbInterface )) {
359
+ HIDDeviceUSB device = new HIDDeviceUSB (this , usbDevice , interface_index );
365
360
int id = device .getId ();
366
- mUSBDevices .put (usbDevice , device );
367
361
mDevicesById .put (id , device );
368
- HIDDeviceConnected (id , device .getIdentifier (), device .getVendorId (), device .getProductId (), device .getSerialNumber (), device .getVersion (), device .getManufacturerName (), device .getProductName (), interface_number );
369
- break ;
362
+ HIDDeviceConnected (id , device .getIdentifier (), device .getVendorId (), device .getProductId (), device .getSerialNumber (), device .getVersion (), device .getManufacturerName (), device .getProductName (), usbInterface .getId (), usbInterface .getInterfaceClass (), usbInterface .getInterfaceSubclass (), usbInterface .getInterfaceProtocol ());
370
363
}
371
364
}
372
365
}
@@ -563,33 +556,27 @@ private HIDDevice getDevice(int id) {
563
556
//////////////////////////////////////////////////////////////////////////////////////////////////////
564
557
565
558
public boolean openDevice (int deviceID ) {
559
+ Log .v (TAG , "openDevice deviceID=" + deviceID );
560
+ HIDDevice device = getDevice (deviceID );
561
+ if (device == null ) {
562
+ HIDDeviceDisconnected (deviceID );
563
+ return false ;
564
+ }
565
+
566
566
// Look to see if this is a USB device and we have permission to access it
567
- for (HIDDeviceUSB device : mUSBDevices .values ()) {
568
- if (deviceID == device .getId ()) {
569
- UsbDevice usbDevice = device .getDevice ();
570
- if (!mUsbManager .hasPermission (usbDevice )) {
571
- HIDDeviceOpenPending (deviceID );
572
- try {
573
- mUsbManager .requestPermission (usbDevice , PendingIntent .getBroadcast (mContext , 0 , new Intent (HIDDeviceManager .ACTION_USB_PERMISSION ), 0 ));
574
- } catch (Exception e ) {
575
- Log .v (TAG , "Couldn't request permission for USB device " + usbDevice );
576
- HIDDeviceOpenResult (deviceID , false );
577
- }
578
- return false ;
579
- }
580
- break ;
567
+ UsbDevice usbDevice = device .getDevice ();
568
+ if (usbDevice != null && !mUsbManager .hasPermission (usbDevice )) {
569
+ HIDDeviceOpenPending (deviceID );
570
+ try {
571
+ mUsbManager .requestPermission (usbDevice , PendingIntent .getBroadcast (mContext , 0 , new Intent (HIDDeviceManager .ACTION_USB_PERMISSION ), 0 ));
572
+ } catch (Exception e ) {
573
+ Log .v (TAG , "Couldn't request permission for USB device " + usbDevice );
574
+ HIDDeviceOpenResult (deviceID , false );
581
575
}
576
+ return false ;
582
577
}
583
578
584
579
try {
585
- Log .v (TAG , "openDevice deviceID=" + deviceID );
586
- HIDDevice device ;
587
- device = getDevice (deviceID );
588
- if (device == null ) {
589
- HIDDeviceDisconnected (deviceID );
590
- return false ;
591
- }
592
-
593
580
return device .open ();
594
581
} catch (Exception e ) {
595
582
Log .e (TAG , "Got exception: " + Log .getStackTraceString (e ));
@@ -599,7 +586,7 @@ public boolean openDevice(int deviceID) {
599
586
600
587
public int sendOutputReport (int deviceID , byte [] report ) {
601
588
try {
602
- Log .v (TAG , "sendOutputReport deviceID=" + deviceID + " length=" + report .length );
589
+ // Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length);
603
590
HIDDevice device ;
604
591
device = getDevice (deviceID );
605
592
if (device == null ) {
@@ -616,7 +603,7 @@ public int sendOutputReport(int deviceID, byte[] report) {
616
603
617
604
public int sendFeatureReport (int deviceID , byte [] report ) {
618
605
try {
619
- Log .v (TAG , "sendFeatureReport deviceID=" + deviceID + " length=" + report .length );
606
+ // Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length);
620
607
HIDDevice device ;
621
608
device = getDevice (deviceID );
622
609
if (device == null ) {
@@ -633,7 +620,7 @@ public int sendFeatureReport(int deviceID, byte[] report) {
633
620
634
621
public boolean getFeatureReport (int deviceID , byte [] report ) {
635
622
try {
636
- Log .v (TAG , "getFeatureReport deviceID=" + deviceID );
623
+ // Log.v(TAG, "getFeatureReport deviceID=" + deviceID);
637
624
HIDDevice device ;
638
625
device = getDevice (deviceID );
639
626
if (device == null ) {
@@ -672,7 +659,7 @@ public void closeDevice(int deviceID) {
672
659
private native void HIDDeviceRegisterCallback ();
673
660
private native void HIDDeviceReleaseCallback ();
674
661
675
- native void HIDDeviceConnected (int deviceID , String identifier , int vendorId , int productId , String serial_number , int release_number , String manufacturer_string , String product_string , int interface_number );
662
+ native void HIDDeviceConnected (int deviceID , String identifier , int vendorId , int productId , String serial_number , int release_number , String manufacturer_string , String product_string , int interface_number , int interface_class , int interface_subclass , int interface_protocol );
676
663
native void HIDDeviceOpenPending (int deviceID );
677
664
native void HIDDeviceOpenResult (int deviceID , boolean opened );
678
665
native void HIDDeviceDisconnected (int deviceID );
0 commit comments