android: handle sensor registration synchronized in one place

This commit is contained in:
Sam Lantinga
2026-05-20 14:57:36 -07:00
parent 19d73016e8
commit 47c8dcc968
3 changed files with 40 additions and 14 deletions

View File

@@ -91,13 +91,7 @@ public class SDLControllerManager
* This method is called by SDL using JNI.
*/
static void joystickSetSensorsEnabled(int device_id, boolean enabled) {
// Run this on the UI thread so we don't race with enableSensor() in SDLSurface.java
SDL.getContext().runOnUiThread(new Runnable() {
@Override
public void run() {
mJoystickHandler.setSensorsEnabled(device_id, enabled);
}
});
mJoystickHandler.setSensorsEnabled(device_id, enabled);
}
/**
@@ -558,17 +552,17 @@ class SDLJoystickHandler {
}
if (enabled) {
if (joystick.accelerometerSensor != null) {
joystick.sensorManager.registerListener(joystick.sensorListener, joystick.accelerometerSensor, SensorManager.SENSOR_DELAY_GAME, null);
SDLSensorManager.registerListener(joystick.sensorManager, joystick.sensorListener, joystick.accelerometerSensor, SensorManager.SENSOR_DELAY_GAME);
}
if (joystick.gyroscopeSensor != null) {
joystick.sensorManager.registerListener(joystick.sensorListener, joystick.gyroscopeSensor, SensorManager.SENSOR_DELAY_GAME, null);
SDLSensorManager.registerListener(joystick.sensorManager, joystick.sensorListener, joystick.gyroscopeSensor, SensorManager.SENSOR_DELAY_GAME);
}
} else {
if (joystick.accelerometerSensor != null) {
joystick.sensorManager.unregisterListener(joystick.sensorListener, joystick.accelerometerSensor);
SDLSensorManager.unregisterListener(joystick.sensorManager, joystick.sensorListener, joystick.accelerometerSensor);
}
if (joystick.gyroscopeSensor != null) {
joystick.sensorManager.unregisterListener(joystick.sensorListener, joystick.gyroscopeSensor);
SDLSensorManager.unregisterListener(joystick.sensorManager, joystick.sensorListener, joystick.gyroscopeSensor);
}
}
}

View File

@@ -0,0 +1,32 @@
package org.libsdl.app;
import android.hardware.Sensor;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
// This class coordinates synchronized access to sensor manager registration
//
// This prevents a java.util.ConcurrentModificationException exception on
// Android 16, specifically on the Samsung Tab S9 Ultra.
class SDLSensorManager
{
static private SDLSensorManager mManager = new SDLSensorManager();
public static void registerListener(SensorManager manager, SensorEventListener listener, Sensor sensor, int samplingPeriodUs) {
mManager.RegisterListener(manager, listener, sensor, samplingPeriodUs);
}
public static void unregisterListener(SensorManager manager, SensorEventListener listener, Sensor sensor) {
mManager.UnregisterListener(manager, listener, sensor);
}
private synchronized void RegisterListener(SensorManager manager, SensorEventListener listener, Sensor sensor, int samplingPeriodUs) {
manager.registerListener(listener, sensor, samplingPeriodUs, null);
}
private synchronized void UnregisterListener(SensorManager manager, SensorEventListener listener, Sensor sensor) {
manager.unregisterListener(listener, sensor);
}
}

View File

@@ -328,11 +328,11 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
protected void enableSensor(int sensortype, boolean enabled) {
// TODO: This uses getDefaultSensor - what if we have >1 accels?
if (enabled) {
mSensorManager.registerListener(this,
SDLSensorManager.registerListener(mSensorManager, this,
mSensorManager.getDefaultSensor(sensortype),
SensorManager.SENSOR_DELAY_GAME, null);
SensorManager.SENSOR_DELAY_GAME);
} else {
mSensorManager.unregisterListener(this,
SDLSensorManager.unregisterListener(mSensorManager, this,
mSensorManager.getDefaultSensor(sensortype));
}
}