mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-10-26 22:10:01 +00:00
Fix crashes and ANRs in controller LED handling
This commit is contained in:
1 parent
ad8614907c
commit
abde6021e8
1 file changed
+53
-22
@@ -786,6 +786,13 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Light.hasRgbControl() was totally broken prior to Android 14.
|
||||||
|
// It always returned true because LIGHT_CAPABILITY_RGB was defined as 0,
|
||||||
|
// so we will just guess RGB is supported if it's a PlayStation controller.
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE && context.vendorId != 0x054c) {
|
||||||
|
context.hasRgbLed = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect if the gamepad has Mode and Select buttons according to the Android key layouts.
|
// Detect if the gamepad has Mode and Select buttons according to the Android key layouts.
|
||||||
@@ -2305,25 +2312,11 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
|
|
||||||
// Ignore input devices without an RGB LED
|
// Ignore input devices without an RGB LED
|
||||||
if (deviceContext.controllerNumber == controllerNumber && deviceContext.hasRgbLed) {
|
if (deviceContext.controllerNumber == controllerNumber && deviceContext.hasRgbLed) {
|
||||||
// Create a new light session if one doesn't already exist
|
|
||||||
if (deviceContext.lightsSession == null) {
|
|
||||||
deviceContext.lightsSession = deviceContext.inputDevice.getLightsManager().openSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the RGB components into the integer value that LightState uses
|
// Convert the RGB components into the integer value that LightState uses
|
||||||
int argbValue = 0xFF000000 | ((r << 16) & 0xFF0000) | ((g << 8) & 0xFF00) | (b & 0xFF);
|
deviceContext.ledArgbValue = 0xFF000000 | ((r << 16) & 0xFF0000) | ((g << 8) & 0xFF00) | (b & 0xFF);
|
||||||
LightState lightState = new LightState.Builder().setColor(argbValue).build();
|
|
||||||
|
|
||||||
// Set the RGB value for each RGB-controllable LED on the device
|
backgroundThreadHandler.removeCallbacks(deviceContext.setLedStateRunnable);
|
||||||
LightsRequest.Builder lightsRequestBuilder = new LightsRequest.Builder();
|
backgroundThreadHandler.post(deviceContext.setLedStateRunnable);
|
||||||
for (Light light : deviceContext.inputDevice.getLightsManager().getLights()) {
|
|
||||||
if (light.hasRgbControl()) {
|
|
||||||
lightsRequestBuilder.addLight(light, lightState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply the LED changes
|
|
||||||
deviceContext.lightsSession.requestLights(lightsRequestBuilder.build());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2958,6 +2951,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
|
|
||||||
public boolean hasRgbLed;
|
public boolean hasRgbLed;
|
||||||
public LightsManager.LightsSession lightsSession;
|
public LightsManager.LightsSession lightsSession;
|
||||||
|
public int ledArgbValue;
|
||||||
|
|
||||||
// These are BatteryState values, not Moonlight values
|
// These are BatteryState values, not Moonlight values
|
||||||
public int lastReportedBatteryStatus;
|
public int lastReportedBatteryStatus;
|
||||||
@@ -3034,6 +3028,34 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public final Runnable setLedStateRunnable = new Runnable() {
|
||||||
|
@TargetApi(Build.VERSION_CODES.S)
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
LightState lightState = new LightState.Builder().setColor(ledArgbValue).build();
|
||||||
|
|
||||||
|
// Set the RGB value for each RGB-controllable LED on the device
|
||||||
|
boolean hasRgbLight = false;
|
||||||
|
LightsRequest.Builder lightsRequestBuilder = new LightsRequest.Builder();
|
||||||
|
for (Light light : inputDevice.getLightsManager().getLights()) {
|
||||||
|
if (light.hasRgbControl()) {
|
||||||
|
lightsRequestBuilder.addLight(light, lightState);
|
||||||
|
hasRgbLight = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRgbLight) {
|
||||||
|
// Create a new light session if one doesn't already exist
|
||||||
|
if (lightsSession == null) {
|
||||||
|
lightsSession = inputDevice.getLightsManager().openSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the LED changes
|
||||||
|
lightsSession.requestLights(lightsRequestBuilder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
@@ -3046,6 +3068,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
}
|
}
|
||||||
|
|
||||||
backgroundThreadHandler.removeCallbacks(enableSensorRunnable);
|
backgroundThreadHandler.removeCallbacks(enableSensorRunnable);
|
||||||
|
backgroundThreadHandler.removeCallbacks(setLedStateRunnable);
|
||||||
|
|
||||||
if (gyroListener != null) {
|
if (gyroListener != null) {
|
||||||
sensorManager.unregisterListener(gyroListener);
|
sensorManager.unregisterListener(gyroListener);
|
||||||
@@ -3056,7 +3079,11 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
if (lightsSession != null) {
|
if (lightsSession != null) {
|
||||||
lightsSession.close();
|
try {
|
||||||
|
lightsSession.close();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
LimeLog.warning("Error closing LightsSession: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3128,10 +3155,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
capabilities |= MoonBridge.LI_CCAP_BATTERY_STATE;
|
capabilities |= MoonBridge.LI_CCAP_BATTERY_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Light.hasRgbControl() was totally broken prior to Android 14.
|
if (hasRgbLed) {
|
||||||
// It always returned true because LIGHT_CAPABILITY_RGB was defined as 0,
|
|
||||||
// so we will just guess RGB is supported if it's a PlayStation controller.
|
|
||||||
if (hasRgbLed && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE || type == MoonBridge.LI_CTYPE_PS)) {
|
|
||||||
capabilities |= MoonBridge.LI_CCAP_RGB_LED;
|
capabilities |= MoonBridge.LI_CCAP_RGB_LED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3195,6 +3219,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
this.lightsSession = oldContext.lightsSession;
|
this.lightsSession = oldContext.lightsSession;
|
||||||
oldContext.lightsSession = null;
|
oldContext.lightsSession = null;
|
||||||
}
|
}
|
||||||
|
this.ledArgbValue = oldContext.ledArgbValue;
|
||||||
this.gyroReportRateHz = oldContext.gyroReportRateHz;
|
this.gyroReportRateHz = oldContext.gyroReportRateHz;
|
||||||
this.accelReportRateHz = oldContext.accelReportRateHz;
|
this.accelReportRateHz = oldContext.accelReportRateHz;
|
||||||
|
|
||||||
@@ -3219,6 +3244,12 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
// Re-enable sensors on the new context
|
// Re-enable sensors on the new context
|
||||||
enableSensors();
|
enableSensors();
|
||||||
|
|
||||||
|
// Refresh the LED state if it's set. We don't know if there was a pending LED state
|
||||||
|
// callback when the context was migrated, so we'll reset it just to be safe.
|
||||||
|
if (this.lightsSession != null) {
|
||||||
|
backgroundThreadHandler.post(setLedStateRunnable);
|
||||||
|
}
|
||||||
|
|
||||||
// Refresh battery state and start the battery state polling again
|
// Refresh battery state and start the battery state polling again
|
||||||
backgroundThreadHandler.post(batteryStateUpdateRunnable);
|
backgroundThreadHandler.post(batteryStateUpdateRunnable);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user