Android: remove pollInputDevice() in favor of InputDeviceListener (#15659)

This commit is contained in:
Sylvain Becker 2026-06-04 05:38:04 +02:00 committed by GitHub
parent 42fc082b5e
commit fc3a96e47a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 85 additions and 87 deletions

View file

@ -69,9 +69,9 @@
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLControllerManager {
void joystickSetSensorsEnabled(int, boolean);
void pollInputDevices();
void detectDevices();
void joystickSetLED(int, int, int, int);
void pollHapticDevices();
void detectHapticDevices();
void hapticRun(int, float, int);
void hapticRumble(int, float, float, int);
void hapticStop(int);

View file

@ -465,6 +465,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
mSingleton = this;
SDL.setContext(this);
SDLControllerManager.initializeDeviceListener();
mClipboardHandler = new SDLClipboardHandler();
mHIDDeviceManager = HIDDeviceManager.acquire(this);
@ -545,7 +547,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
if (mHIDDeviceManager != null) {
mHIDDeviceManager.setFrozen(true);
}
}
if (!mHasMultiWindow) {
pauseNativeThread();
@ -559,7 +561,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
if (mHIDDeviceManager != null) {
mHIDDeviceManager.setFrozen(false);
}
}
if (!mHasMultiWindow) {
resumeNativeThread();
@ -638,7 +640,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
if (hasFocus || !SDLActivity.nativeGetHintBoolean("SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS", false)) {
if (mHIDDeviceManager != null) {
mHIDDeviceManager.setFrozen(!hasFocus);
}
}
}
if (SDLActivity.mBrokenLibraries) {

View file

@ -6,6 +6,8 @@ import java.util.Comparator;
import java.util.List;
import android.content.Context;
import android.hardware.input.InputManager;
import android.hardware.input.InputManager.InputDeviceListener;
import android.hardware.lights.Light;
import android.hardware.lights.LightsRequest;
import android.hardware.lights.LightsManager;
@ -68,6 +70,12 @@ public class SDLControllerManager
}
}
static void initializeDeviceListener() {
InputManager im = (InputManager) SDL.getContext().getSystemService(Context.INPUT_SERVICE);
im.registerInputDeviceListener(new SDLDeviceListener(), null);
}
// Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance
static public boolean handleJoystickMotionEvent(MotionEvent event) {
return mJoystickHandler.handleMotionEvent(event);
@ -76,8 +84,8 @@ public class SDLControllerManager
/**
* This method is called by SDL using JNI.
*/
static void pollInputDevices() {
mJoystickHandler.pollInputDevices();
static void detectDevices() {
mJoystickHandler.detectDevices();
}
/**
@ -97,8 +105,8 @@ public class SDLControllerManager
/**
* This method is called by SDL using JNI.
*/
static void pollHapticDevices() {
mHapticHandler.pollHapticDevices();
static void detectHapticDevices() {
mHapticHandler.detectHapticDevices();
}
/**
@ -151,7 +159,27 @@ public class SDLControllerManager
((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD)
);
}
}
class SDLDeviceListener implements InputDeviceListener
{
@Override
public void onInputDeviceAdded(int deviceId) {
if (SDLControllerManager.isDeviceSDLJoystick(deviceId)) {
SDLControllerManager.mJoystickHandler.deviceAdded(deviceId);
}
}
@Override
public void onInputDeviceChanged(int deviceId) {
}
@Override
public void onInputDeviceRemoved(int deviceId) {
// InputDevice.getDevice(deviceId) returns NULL. so we cannot check device type
SDLControllerManager.mJoystickHandler.deviceRemoved(deviceId);
}
}
@ -228,16 +256,21 @@ class SDLJoystickHandler {
/**
* Handles adding and removing of input devices.
*/
synchronized void pollInputDevices() {
int[] deviceIds = InputDevice.getDeviceIds();
synchronized void detectDevices() {
int[] deviceIds = InputDevice.getDeviceIds();
for (int device_id : deviceIds) {
if (SDLControllerManager.isDeviceSDLJoystick(device_id)) {
deviceAdded(device_id);
}
}
}
for (int device_id : deviceIds) {
if (SDLControllerManager.isDeviceSDLJoystick(device_id)) {
SDLJoystick joystick = getJoystick(device_id);
if (joystick == null) {
InputDevice joystickDevice = InputDevice.getDevice(device_id);
joystick = new SDLJoystick();
joystick.device_id = device_id;
void deviceAdded(int device_id) {
SDLJoystick joystick = getJoystick(device_id);
if (joystick == null) {
InputDevice joystickDevice = InputDevice.getDevice(device_id);
joystick = new SDLJoystick();
joystick.device_id = device_id;
joystick.name = joystickDevice.getName();
joystick.desc = getJoystickDescriptor(joystickDevice);
joystick.axes = new ArrayList<InputDevice.MotionRange>();
@ -299,44 +332,27 @@ class SDLJoystickHandler {
getButtonMask(joystickDevice), joystick.axes.size(), getAxisMask(joystick.axes), joystick.hats.size()/2, can_rumble, has_rgb_led,
has_accelerometer, has_gyroscope);
}
}
}
/* Check removed devices */
ArrayList<Integer> removedDevices = null;
for (SDLJoystick joystick : mJoysticks) {
int device_id = joystick.device_id;
int i;
for (i = 0; i < deviceIds.length; i++) {
if (device_id == deviceIds[i]) break;
}
if (i == deviceIds.length) {
if (removedDevices == null) {
removedDevices = new ArrayList<Integer>();
}
removedDevices.add(device_id);
}
}
}
void deviceRemoved(int device_id) {
for (int i = 0; i < mJoysticks.size(); i++) {
if (mJoysticks.get(i).device_id == device_id) {
if (removedDevices != null) {
for (int device_id : removedDevices) {
SDLControllerManager.nativeRemoveJoystick(device_id);
for (int i = 0; i < mJoysticks.size(); i++) {
if (mJoysticks.get(i).device_id == device_id) {
if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
if (mJoysticks.get(i).lightsSession != null) {
try {
mJoysticks.get(i).lightsSession.close();
} catch (Exception e) {
// Session may already be unregistered when device disconnects
}
mJoysticks.get(i).lightsSession = null;
}
if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
if (mJoysticks.get(i).lightsSession != null) {
try {
mJoysticks.get(i).lightsSession.close();
} catch (Exception e) {
// Session may already be unregistered when device disconnects
}
mJoysticks.remove(i);
break;
mJoysticks.get(i).lightsSession = null;
}
}
mJoysticks.remove(i);
break;
}
}
}
@ -701,7 +717,7 @@ class SDLHapticHandler {
}
}
synchronized void pollHapticDevices() {
synchronized void detectHapticDevices() {
final int deviceId_VIBRATOR_SERVICE = 999999;
boolean hasVibratorService = false;