fix: ignore uinput-* system virtual input devices in controller detection (#954)

This commit is contained in:
Resul Övür authored and GitHub committed 2026-10-20 18:39:35 -04:00
1 parent 87763976d8
commit e032f25114
2 files changed
+22 -4

No files matched your search

@@ -146,9 +146,15 @@ public final class PadBridge {
}
}
static boolean isSystemVirtualInputName(String name) {
if (name == null) return false;
String lower = name.trim().toLowerCase(java.util.Locale.ROOT);
return lower.startsWith("uinput-") || lower.startsWith("uinput_");
}
public static boolean isFromController(InputDevice device) {
if (device == null) return false;
if (device.isVirtual()) return false;
if (device.isVirtual() || isSystemVirtualInputName(device.getName())) return false;
int sources = device.getSources();
if ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) return true;
if ((sources & InputDevice.SOURCE_JOYSTICK) != InputDevice.SOURCE_JOYSTICK) return false;
@@ -165,7 +171,7 @@ public final class PadBridge {
public static boolean isControllerKeyEvent(KeyEvent event) {
InputDevice device = event.getDevice();
if (device == null || device.isVirtual()) return false;
if (device == null || device.isVirtual() || isSystemVirtualInputName(device.getName())) return false;
if (KeyEvent.isGamepadButton(event.getKeyCode())) {
return device.supportsSource(InputDevice.SOURCE_GAMEPAD)
|| device.supportsSource(InputDevice.SOURCE_JOYSTICK);
@@ -190,6 +196,7 @@ public final class PadBridge {
public static boolean isControllerMotionEvent(MotionEvent event) {
InputDevice device = event.getDevice();
return event.isFromSource(InputDevice.SOURCE_JOYSTICK) && device != null && !device.isVirtual()
&& !isSystemVirtualInputName(device.getName())
&& (device.supportsSource(InputDevice.SOURCE_GAMEPAD)
|| device.supportsSource(InputDevice.SOURCE_JOYSTICK));
}
@@ -71,6 +71,17 @@ class PadBridgeRoutingTest {
InputDevice.KEYBOARD_TYPE_NONE, id = -1)
assertTrue(virtual.isVirtual)
assertFalse(PadBridge.isFromController(virtual))
for (uinputName in listOf("uinput-xiaomi", "uinput-fpc", "uinput_nav")) {
val phantom = device(
InputDevice.SOURCE_GAMEPAD or InputDevice.SOURCE_JOYSTICK,
InputDevice.KEYBOARD_TYPE_NONE,
name = uinputName,
)
assertFalse(phantom.isVirtual)
assertFalse(PadBridge.isFromController(phantom))
assertFalse(PadBridge.isControllerKeyEvent(key(phantom, KeyEvent.KEYCODE_BUTTON_A, KeyEvent.ACTION_DOWN)))
}
assertFalse(PadBridge.anyControllerConnected())
}
@Test fun keyAndMotionOwnershipDoesNotFollowEverySourceOnTheDevice() {
@@ -146,8 +157,8 @@ class PadBridgeRoutingTest {
private var nextId = 10
private fun device(sources: Int, type: Int, keys: IntArray = intArrayOf(KeyEvent.KEYCODE_A, KeyEvent.KEYCODE_DPAD_UP),
rangeSource: Int? = null, axis: Int = MotionEvent.AXIS_X, id: Int = nextId++): InputDevice {
val builder = InputDeviceBuilder.newBuilder().setId(id).setName("routing fixture $id")
rangeSource: Int? = null, axis: Int = MotionEvent.AXIS_X, id: Int = nextId++, name: String = "routing fixture $id"): InputDevice {
val builder = InputDeviceBuilder.newBuilder().setId(id).setName(name)
.setDescriptor("routing-$id").setExternal(true).setSources(sources).setKeyboardType(type)
.setKeyCharacterMap(KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD))
if (rangeSource != null) builder.addMotionRange(axis, rangeSource, -1f, 1f, 0f, 0f, 0f)