mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-06-04 19:55:19 +00:00
Ensure we release exclusive USB access to controllers when backgrounded. #15694
This commit is contained in:
parent
59a302e601
commit
ac177763aa
2 changed files with 48 additions and 4 deletions
|
|
@ -21,6 +21,7 @@ class HIDDeviceUSB implements HIDDevice {
|
|||
protected InputThread mInputThread;
|
||||
protected boolean mRunning;
|
||||
protected boolean mFrozen;
|
||||
protected boolean mClaimed;
|
||||
|
||||
public HIDDeviceUSB(HIDDeviceManager manager, UsbDevice usbDevice, int interface_index) {
|
||||
mManager = manager;
|
||||
|
|
@ -29,6 +30,7 @@ class HIDDeviceUSB implements HIDDevice {
|
|||
mInterface = mDevice.getInterface(mInterfaceIndex).getId();
|
||||
mDeviceId = manager.getDeviceIDForIdentifier(getIdentifier());
|
||||
mRunning = false;
|
||||
mClaimed = false;
|
||||
}
|
||||
|
||||
String getIdentifier() {
|
||||
|
|
@ -114,6 +116,7 @@ class HIDDeviceUSB implements HIDDevice {
|
|||
close();
|
||||
return false;
|
||||
}
|
||||
mClaimed = true;
|
||||
|
||||
// Find the endpoints
|
||||
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).
|
||||
if (mInputEndpoint == null) {
|
||||
Log.w(TAG, "Missing required endpoint on USB device " + getDeviceName());
|
||||
mConnection.releaseInterface(iface);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -156,6 +160,11 @@ class HIDDeviceUSB implements HIDDevice {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!mClaimed) {
|
||||
Log.w(TAG, "writeReport() called but some other process currently owns the USB device");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (feature) {
|
||||
int res = -1;
|
||||
int offset = 0;
|
||||
|
|
@ -212,6 +221,12 @@ class HIDDeviceUSB implements HIDDevice {
|
|||
Log.w(TAG, "readReport() called with no device connection");
|
||||
return false;
|
||||
}
|
||||
if (!mClaimed) {
|
||||
if (feature) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (report_number == 0x0) {
|
||||
/* Offset the return buffer by 1, so that the report ID
|
||||
|
|
@ -265,10 +280,13 @@ class HIDDeviceUSB implements HIDDevice {
|
|||
mInputThread = 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 = null;
|
||||
mClaimed = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -281,6 +299,22 @@ class HIDDeviceUSB implements HIDDevice {
|
|||
@Override
|
||||
public void setFrozen(boolean 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 {
|
||||
|
|
|
|||
|
|
@ -545,7 +545,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
|
||||
if (mHIDDeviceManager != null) {
|
||||
mHIDDeviceManager.setFrozen(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mHasMultiWindow) {
|
||||
pauseNativeThread();
|
||||
}
|
||||
|
|
@ -558,7 +559,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
|
||||
if (mHIDDeviceManager != null) {
|
||||
mHIDDeviceManager.setFrozen(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mHasMultiWindow) {
|
||||
resumeNativeThread();
|
||||
}
|
||||
|
|
@ -631,6 +633,14 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
super.onWindowFocusChanged(hasFocus);
|
||||
Log.v(TAG, "onWindowFocusChanged(): " + hasFocus);
|
||||
|
||||
// If we are gaining focus, we can always try to restore our USB devices. If we are losing focus,
|
||||
// only try to relinquish them if we don't have background events allowed (for multi-window Android setups).
|
||||
if (hasFocus || !SDLActivity.nativeGetHintBoolean("SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS", false)) {
|
||||
if (mHIDDeviceManager != null) {
|
||||
mHIDDeviceManager.setFrozen(!hasFocus);
|
||||
}
|
||||
}
|
||||
|
||||
if (SDLActivity.mBrokenLibraries) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue