Avoid unnecessary reinitialization of PS4/PS5 gamepads during stream exit

onInputDeviceChanged() is triggered by starting/stopping pointer capture, so we should
unregister our callbacks before that happens to avoid triggering several gamepad context
reinitializations right as the stream is exiting
This commit is contained in:
Cameron Gutman
2023-10-29 16:45:07 -05:00
parent fc77322f59
commit c356862ac1
3 changed files with 34 additions and 3 deletions

View File

@@ -495,7 +495,6 @@ public class Game extends Activity implements SurfaceHolder.Callback,
keyboardTranslator = new KeyboardTranslator();
InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE);
inputManager.registerInputDeviceListener(controllerHandler, null);
inputManager.registerInputDeviceListener(keyboardTranslator, null);
// Initialize touch contexts
@@ -1079,12 +1078,11 @@ public class Game extends Activity implements SurfaceHolder.Callback,
protected void onDestroy() {
super.onDestroy();
InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE);
if (controllerHandler != null) {
inputManager.unregisterInputDeviceListener(controllerHandler);
controllerHandler.destroy();
}
if (keyboardTranslator != null) {
InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE);
inputManager.unregisterInputDeviceListener(keyboardTranslator);
}
@@ -1104,6 +1102,21 @@ public class Game extends Activity implements SurfaceHolder.Callback,
inputCaptureProvider.destroy();
}
@Override
protected void onPause() {
if (isFinishing()) {
// Stop any further input device notifications before we lose focus (and pointer capture)
if (controllerHandler != null) {
controllerHandler.stop();
}
// Ungrab input to prevent further input device notifications
setInputGrabState(false);
}
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
@@ -2310,6 +2323,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
// Let the display go to sleep now
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// Stop processing controller input
controllerHandler.stop();
// Ungrab input
setInputGrabState(false);

View File

@@ -114,6 +114,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
private final double stickDeadzone;
private final InputDeviceContext defaultContext = new InputDeviceContext();
private final GameGestures gestures;
private final InputManager inputManager;
private final Vibrator deviceVibrator;
private final VibratorManager deviceVibratorManager;
private final SensorManager deviceSensorManager;
@@ -134,6 +135,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
this.prefConfig = prefConfig;
this.deviceVibrator = (Vibrator) activityContext.getSystemService(Context.VIBRATOR_SERVICE);
this.deviceSensorManager = (SensorManager) activityContext.getSystemService(Context.SENSOR_SERVICE);
this.inputManager = (InputManager) activityContext.getSystemService(Context.INPUT_SERVICE);
this.mainThreadHandler = new Handler(Looper.getMainLooper());
// Create a HandlerThread to process battery state updates. These can be slow enough
@@ -205,6 +207,9 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
// currentControllers set which will allow them to properly unplug
// if they are removed.
initialControllers = getAttachedControllerMask(activityContext);
// Register ourselves for input device notifications
inputManager.registerInputDeviceListener(this, null);
}
private static InputDevice.MotionRange getMotionRangeForJoystickAxis(InputDevice dev, int axis) {
@@ -260,9 +265,16 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
}
public void stop() {
if (stopped) {
return;
}
// Stop new device contexts from being created or used
stopped = true;
// Unregister our input device callbacks
inputManager.unregisterInputDeviceListener(this);
for (int i = 0; i < inputDeviceContexts.size(); i++) {
InputDeviceContext deviceContext = inputDeviceContexts.valueAt(i);
deviceContext.destroy();

View File

@@ -65,6 +65,9 @@ public class AndroidNativePointerCaptureProvider extends AndroidPointerIconCaptu
public void showCursor() {
super.showCursor();
// It is important to unregister the listener *before* releasing pointer capture,
// because releasing pointer capture can cause an onInputDeviceChanged() callback
// for devices with a touchpad (like a DS4 controller).
inputManager.unregisterInputDeviceListener(this);
targetView.releasePointerCapture();
}