From 30822c1ba57871b21055b4634d60325917d9679b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 7 Oct 2023 19:07:00 -0500 Subject: [PATCH] Only check for motion sensors on Sony or Nintendo gamepads on Android 12 This works around a bug in Android 12 that leads to random crashes when input devices change. --- .../limelight/binding/input/ControllerHandler.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/limelight/binding/input/ControllerHandler.java b/app/src/main/java/com/limelight/binding/input/ControllerHandler.java index a158bcdd..84e87fef 100644 --- a/app/src/main/java/com/limelight/binding/input/ControllerHandler.java +++ b/app/src/main/java/com/limelight/binding/input/ControllerHandler.java @@ -681,7 +681,16 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD // On Android 12, we can try to use the InputDevice's sensors. This may not work if the // Linux kernel version doesn't have motion sensor support, which is common for third-party // gamepads. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && prefConfig.gamepadMotionSensors) { + // + // Android 12 has a bug that causes InputDeviceSensorManager to cause a NPE on a background + // thread due to bad error checking in InputListener callbacks. InputDeviceSensorManager is + // created upon the first call to InputDevice.getSensorManager(), so we avoid calling this + // on Android 12 unless we have a gamepad that could plausibly have motion sensors. + // https://cs.android.com/android/_/android/platform/frameworks/base/+/8970010a5e9f3dc5c069f56b4147552accfcbbeb + if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU || + (Build.VERSION.SDK_INT == Build.VERSION_CODES.S && + (context.vendorId == 0x054c || context.vendorId == 0x057e))) && // Sony or Nintendo + prefConfig.gamepadMotionSensors) { if (dev.getSensorManager().getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null || dev.getSensorManager().getDefaultSensor(Sensor.TYPE_GYROSCOPE) != null) { context.sensorManager = dev.getSensorManager(); }