mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2025-03-07 16:56:59 +01:00
Added support for claiming individiual interfaces on USB devices on Android
This is needed for supporting multiple wireless Xbox 360 controllers
This commit is contained in:
parent
acbf25935e
commit
1d321850b6
@ -1,5 +1,7 @@
|
|||||||
package org.libsdl.app;
|
package org.libsdl.app;
|
||||||
|
|
||||||
|
import android.hardware.usb.UsbDevice;
|
||||||
|
|
||||||
interface HIDDevice
|
interface HIDDevice
|
||||||
{
|
{
|
||||||
public int getId();
|
public int getId();
|
||||||
@ -9,6 +11,7 @@ interface HIDDevice
|
|||||||
public int getVersion();
|
public int getVersion();
|
||||||
public String getManufacturerName();
|
public String getManufacturerName();
|
||||||
public String getProductName();
|
public String getProductName();
|
||||||
|
public UsbDevice getDevice();
|
||||||
public boolean open();
|
public boolean open();
|
||||||
public int sendFeatureReport(byte[] report);
|
public int sendFeatureReport(byte[] report);
|
||||||
public int sendOutputReport(byte[] report);
|
public int sendOutputReport(byte[] report);
|
||||||
|
@ -9,6 +9,7 @@ import android.bluetooth.BluetoothGattDescriptor;
|
|||||||
import android.bluetooth.BluetoothManager;
|
import android.bluetooth.BluetoothManager;
|
||||||
import android.bluetooth.BluetoothProfile;
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.bluetooth.BluetoothGattService;
|
import android.bluetooth.BluetoothGattService;
|
||||||
|
import android.hardware.usb.UsbDevice;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -564,6 +565,11 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public UsbDevice getDevice() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean open() {
|
public boolean open() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,9 @@ import android.hardware.usb.*;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class HIDDeviceManager {
|
public class HIDDeviceManager {
|
||||||
@ -50,7 +51,6 @@ public class HIDDeviceManager {
|
|||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private HashMap<Integer, HIDDevice> mDevicesById = new HashMap<Integer, HIDDevice>();
|
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 HashMap<BluetoothDevice, HIDDeviceBLESteamController> mBluetoothDevices = new HashMap<BluetoothDevice, HIDDeviceBLESteamController>();
|
||||||
private int mNextDeviceId = 0;
|
private int mNextDeviceId = 0;
|
||||||
private SharedPreferences mSharedPreferences = null;
|
private SharedPreferences mSharedPreferences = null;
|
||||||
@ -337,28 +337,31 @@ public class HIDDeviceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleUsbDeviceDetached(UsbDevice usbDevice) {
|
private void handleUsbDeviceDetached(UsbDevice usbDevice) {
|
||||||
HIDDeviceUSB device = mUSBDevices.get(usbDevice);
|
List<Integer> devices = new ArrayList<Integer>();
|
||||||
if (device == null)
|
for (HIDDevice device : mDevicesById.values()) {
|
||||||
return;
|
if (usbDevice.equals(device.getDevice())) {
|
||||||
|
devices.add(device.getId());
|
||||||
int id = device.getId();
|
}
|
||||||
mUSBDevices.remove(usbDevice);
|
}
|
||||||
|
for (int id : devices) {
|
||||||
|
HIDDevice device = mDevicesById.get(id);
|
||||||
mDevicesById.remove(id);
|
mDevicesById.remove(id);
|
||||||
device.shutdown();
|
device.shutdown();
|
||||||
HIDDeviceDisconnected(id);
|
HIDDeviceDisconnected(id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) {
|
private void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) {
|
||||||
HIDDeviceUSB device = mUSBDevices.get(usbDevice);
|
for (HIDDevice device : mDevicesById.values()) {
|
||||||
if (device == null)
|
if (usbDevice.equals(device.getDevice())) {
|
||||||
return;
|
|
||||||
|
|
||||||
boolean opened = false;
|
boolean opened = false;
|
||||||
if (permission_granted) {
|
if (permission_granted) {
|
||||||
opened = device.open();
|
opened = device.open();
|
||||||
}
|
}
|
||||||
HIDDeviceOpenResult(device.getId(), opened);
|
HIDDeviceOpenResult(device.getId(), opened);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void connectHIDDeviceUSB(UsbDevice usbDevice) {
|
private void connectHIDDeviceUSB(UsbDevice usbDevice) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
@ -366,10 +369,8 @@ public class HIDDeviceManager {
|
|||||||
if (isHIDDeviceInterface(usbDevice, interface_number)) {
|
if (isHIDDeviceInterface(usbDevice, interface_number)) {
|
||||||
HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_number);
|
HIDDeviceUSB device = new HIDDeviceUSB(this, usbDevice, interface_number);
|
||||||
int id = device.getId();
|
int id = device.getId();
|
||||||
mUSBDevices.put(usbDevice, device);
|
|
||||||
mDevicesById.put(id, device);
|
mDevicesById.put(id, device);
|
||||||
HIDDeviceConnected(id, device.getIdentifier(), device.getVendorId(), device.getProductId(), device.getSerialNumber(), device.getVersion(), device.getManufacturerName(), device.getProductName(), interface_number);
|
HIDDeviceConnected(id, device.getIdentifier(), device.getVendorId(), device.getProductId(), device.getSerialNumber(), device.getVersion(), device.getManufacturerName(), device.getProductName(), interface_number);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -566,11 +567,16 @@ public class HIDDeviceManager {
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public boolean openDevice(int deviceID) {
|
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
|
// 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();
|
UsbDevice usbDevice = device.getDevice();
|
||||||
if (!mUsbManager.hasPermission(usbDevice)) {
|
if (usbDevice != null && !mUsbManager.hasPermission(usbDevice)) {
|
||||||
HIDDeviceOpenPending(deviceID);
|
HIDDeviceOpenPending(deviceID);
|
||||||
try {
|
try {
|
||||||
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), 0));
|
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), 0));
|
||||||
@ -580,19 +586,8 @@ public class HIDDeviceManager {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Log.v(TAG, "openDevice deviceID=" + deviceID);
|
|
||||||
HIDDevice device;
|
|
||||||
device = getDevice(deviceID);
|
|
||||||
if (device == null) {
|
|
||||||
HIDDeviceDisconnected(deviceID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return device.open();
|
return device.open();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Got exception: " + Log.getStackTraceString(e));
|
Log.e(TAG, "Got exception: " + Log.getStackTraceString(e));
|
||||||
@ -602,7 +597,7 @@ public class HIDDeviceManager {
|
|||||||
|
|
||||||
public int sendOutputReport(int deviceID, byte[] report) {
|
public int sendOutputReport(int deviceID, byte[] report) {
|
||||||
try {
|
try {
|
||||||
Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length);
|
//Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length);
|
||||||
HIDDevice device;
|
HIDDevice device;
|
||||||
device = getDevice(deviceID);
|
device = getDevice(deviceID);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
@ -619,7 +614,7 @@ public class HIDDeviceManager {
|
|||||||
|
|
||||||
public int sendFeatureReport(int deviceID, byte[] report) {
|
public int sendFeatureReport(int deviceID, byte[] report) {
|
||||||
try {
|
try {
|
||||||
Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length);
|
//Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length);
|
||||||
HIDDevice device;
|
HIDDevice device;
|
||||||
device = getDevice(deviceID);
|
device = getDevice(deviceID);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
@ -636,7 +631,7 @@ public class HIDDeviceManager {
|
|||||||
|
|
||||||
public boolean getFeatureReport(int deviceID, byte[] report) {
|
public boolean getFeatureReport(int deviceID, byte[] report) {
|
||||||
try {
|
try {
|
||||||
Log.v(TAG, "getFeatureReport deviceID=" + deviceID);
|
//Log.v(TAG, "getFeatureReport deviceID=" + deviceID);
|
||||||
HIDDevice device;
|
HIDDevice device;
|
||||||
device = getDevice(deviceID);
|
device = getDevice(deviceID);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
|
@ -29,7 +29,7 @@ class HIDDeviceUSB implements HIDDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getIdentifier() {
|
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
|
@Override
|
||||||
@ -88,6 +88,7 @@ class HIDDeviceUSB implements HIDDevice {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public UsbDevice getDevice() {
|
public UsbDevice getDevice() {
|
||||||
return mDevice;
|
return mDevice;
|
||||||
}
|
}
|
||||||
@ -104,19 +105,15 @@ class HIDDeviceUSB implements HIDDevice {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force claim all interfaces
|
// Force claim our interface
|
||||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
UsbInterface iface = mDevice.getInterface(mInterface);
|
||||||
UsbInterface iface = mDevice.getInterface(i);
|
|
||||||
|
|
||||||
if (!mConnection.claimInterface(iface, true)) {
|
if (!mConnection.claimInterface(iface, true)) {
|
||||||
Log.w(TAG, "Failed to claim interfaces on USB device " + getDeviceName());
|
Log.w(TAG, "Failed to claim interfaces on USB device " + getDeviceName());
|
||||||
close();
|
close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Find the endpoints
|
// Find the endpoints
|
||||||
UsbInterface iface = mDevice.getInterface(mInterface);
|
|
||||||
for (int j = 0; j < iface.getEndpointCount(); j++) {
|
for (int j = 0; j < iface.getEndpointCount(); j++) {
|
||||||
UsbEndpoint endpt = iface.getEndpoint(j);
|
UsbEndpoint endpt = iface.getEndpoint(j);
|
||||||
switch (endpt.getDirection()) {
|
switch (endpt.getDirection()) {
|
||||||
@ -250,10 +247,8 @@ class HIDDeviceUSB implements HIDDevice {
|
|||||||
mInputThread = null;
|
mInputThread = null;
|
||||||
}
|
}
|
||||||
if (mConnection != null) {
|
if (mConnection != null) {
|
||||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
UsbInterface iface = mDevice.getInterface(mInterface);
|
||||||
UsbInterface iface = mDevice.getInterface(i);
|
|
||||||
mConnection.releaseInterface(iface);
|
mConnection.releaseInterface(iface);
|
||||||
}
|
|
||||||
mConnection.close();
|
mConnection.close();
|
||||||
mConnection = null;
|
mConnection = null;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user