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 1ec85a9377..5c01b871cd 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 @@ -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++) { @@ -157,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; @@ -213,6 +221,18 @@ class HIDDeviceUSB implements HIDDevice { Log.w(TAG, "readReport() called with no device connection"); return false; } + if (!mClaimed) { + Log.w(TAG, "readReport() called but some other process currently owns the USB device"); + if (feature) { + return false; + } + + // For non-feature reports, fake that there's no data available if we aren't claimed. + // byte[] data; + // data = Arrays.copyOfRange(report, 0, res); + // mManager.HIDDeviceReportResponse(mDeviceId, data); + return true; + } if (report_number == 0x0) { /* Offset the return buffer by 1, so that the report ID @@ -265,11 +285,12 @@ class HIDDeviceUSB implements HIDDevice { } mInputThread = null; } - if (mConnection != null) { + if (mConnection != null && mClaimed) { UsbInterface iface = mDevice.getInterface(mInterfaceIndex); mConnection.releaseInterface(iface); mConnection.close(); mConnection = null; + mClaimed = false; } } @@ -281,15 +302,24 @@ class HIDDeviceUSB implements HIDDevice { @Override public void setFrozen(boolean frozen) { - if (frozen != mFrozen && mConnection != null) { + 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) { - mConnection.releaseInterface(iface); - } else { - mConnection.claimInterface(iface, true); + 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!"); + } } } - mFrozen = frozen; } protected class InputThread extends Thread { diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java index 633fa48c61..b62991f768 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -543,9 +543,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh Log.v(TAG, "onPause()"); super.onPause(); - if (mHIDDeviceManager != null) { - mHIDDeviceManager.setFrozen(true); - } if (!mHasMultiWindow) { pauseNativeThread(); } @@ -556,9 +553,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh Log.v(TAG, "onResume()"); super.onResume(); - if (mHIDDeviceManager != null) { - mHIDDeviceManager.setFrozen(false); - } if (!mHasMultiWindow) { resumeNativeThread(); } @@ -631,6 +625,10 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh super.onWindowFocusChanged(hasFocus); Log.v(TAG, "onWindowFocusChanged(): " + hasFocus); + if (mHIDDeviceManager != null) { + mHIDDeviceManager.setFrozen(hasFocus); + } + if (SDLActivity.mBrokenLibraries) { return; }