|
@@ -21,6 +21,7 @@ class HIDDeviceUSB implements HIDDevice {
|
|
|
protected InputThread mInputThread;
|
|
protected InputThread mInputThread;
|
|
|
protected boolean mRunning;
|
|
protected boolean mRunning;
|
|
|
protected boolean mFrozen;
|
|
protected boolean mFrozen;
|
|
|
|
|
+ protected boolean mClaimed;
|
|
|
|
|
|
|
|
public HIDDeviceUSB(HIDDeviceManager manager, UsbDevice usbDevice, int interface_index) {
|
|
public HIDDeviceUSB(HIDDeviceManager manager, UsbDevice usbDevice, int interface_index) {
|
|
|
mManager = manager;
|
|
mManager = manager;
|
|
@@ -29,6 +30,7 @@ class HIDDeviceUSB implements HIDDevice {
|
|
|
mInterface = mDevice.getInterface(mInterfaceIndex).getId();
|
|
mInterface = mDevice.getInterface(mInterfaceIndex).getId();
|
|
|
mDeviceId = manager.getDeviceIDForIdentifier(getIdentifier());
|
|
mDeviceId = manager.getDeviceIDForIdentifier(getIdentifier());
|
|
|
mRunning = false;
|
|
mRunning = false;
|
|
|
|
|
+ mClaimed = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
String getIdentifier() {
|
|
String getIdentifier() {
|
|
@@ -114,6 +116,7 @@ class HIDDeviceUSB implements HIDDevice {
|
|
|
close();
|
|
close();
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
+ mClaimed = true;
|
|
|
|
|
|
|
|
// Find the endpoints
|
|
// Find the endpoints
|
|
|
for (int j = 0; j < iface.getEndpointCount(); j++) {
|
|
for (int j = 0; j < iface.getEndpointCount(); j++) {
|
|
@@ -137,6 +140,7 @@ class HIDDeviceUSB implements HIDDevice {
|
|
|
// back to the Android system gamepad functionality (and lose our paddles et al).
|
|
// back to the Android system gamepad functionality (and lose our paddles et al).
|
|
|
if (mInputEndpoint == null) {
|
|
if (mInputEndpoint == null) {
|
|
|
Log.w(TAG, "Missing required endpoint on USB device " + getDeviceName());
|
|
Log.w(TAG, "Missing required endpoint on USB device " + getDeviceName());
|
|
|
|
|
+ mConnection.releaseInterface(iface);
|
|
|
close();
|
|
close();
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
@@ -156,6 +160,11 @@ class HIDDeviceUSB implements HIDDevice {
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (!mClaimed) {
|
|
|
|
|
+ Log.w(TAG, "writeReport() called but some other process currently owns the USB device");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (feature) {
|
|
if (feature) {
|
|
|
int res = -1;
|
|
int res = -1;
|
|
|
int offset = 0;
|
|
int offset = 0;
|
|
@@ -212,6 +221,12 @@ class HIDDeviceUSB implements HIDDevice {
|
|
|
Log.w(TAG, "readReport() called with no device connection");
|
|
Log.w(TAG, "readReport() called with no device connection");
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
+ if (!mClaimed) {
|
|
|
|
|
+ if (feature) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if (report_number == 0x0) {
|
|
if (report_number == 0x0) {
|
|
|
/* Offset the return buffer by 1, so that the report ID
|
|
/* Offset the return buffer by 1, so that the report ID
|
|
@@ -265,10 +280,13 @@ class HIDDeviceUSB implements HIDDevice {
|
|
|
mInputThread = null;
|
|
mInputThread = null;
|
|
|
}
|
|
}
|
|
|
if (mConnection != null) {
|
|
if (mConnection != null) {
|
|
|
- UsbInterface iface = mDevice.getInterface(mInterfaceIndex);
|
|
|
|
|
- mConnection.releaseInterface(iface);
|
|
|
|
|
|
|
+ if (mClaimed) {
|
|
|
|
|
+ UsbInterface iface = mDevice.getInterface(mInterfaceIndex);
|
|
|
|
|
+ mConnection.releaseInterface(iface);
|
|
|
|
|
+ }
|
|
|
mConnection.close();
|
|
mConnection.close();
|
|
|
mConnection = null;
|
|
mConnection = null;
|
|
|
|
|
+ mClaimed = false;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -281,6 +299,22 @@ class HIDDeviceUSB implements HIDDevice {
|
|
|
@Override
|
|
@Override
|
|
|
public void setFrozen(boolean frozen) {
|
|
public void setFrozen(boolean frozen) {
|
|
|
mFrozen = frozen;
|
|
mFrozen = frozen;
|
|
|
|
|
+
|
|
|
|
|
+ /* If we have a valid device connection and the claim state doesn't match what we want, try to correct that. */
|
|
|
|
|
+ if (mConnection != null && mClaimed == mFrozen) {
|
|
|
|
|
+ UsbInterface iface = mDevice.getInterface(mInterfaceIndex);
|
|
|
|
|
+ if (frozen) {
|
|
|
|
|
+ mClaimed = !mConnection.releaseInterface(iface);
|
|
|
|
|
+ if (mClaimed) {
|
|
|
|
|
+ Log.e(TAG, "Tried to release claim on USB device, but failed!");
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ mClaimed = mConnection.claimInterface(iface, true);
|
|
|
|
|
+ if (!mClaimed) {
|
|
|
|
|
+ Log.e(TAG, "Tried to regain claim on USB device, but failed!");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
protected class InputThread extends Thread {
|
|
protected class InputThread extends Thread {
|