Open Eagle-Faulkner opened 3 years ago
For the record, this was originally posted on Reddit. Quoting for posterity:
I've been working on a game and using gamepads on my computer for testing controls and I've noticed something that seems odd to me. On PC I have the inputs mapped to be from Device 0, which works perfectly fine there, but not at all on my Android export, however, changing to Device 1 for the Android export will get the controllers working just fine. Is that how that's supposed to be or am I missing some information?
Looking into this a bit further and I find that the device it's picking up on for device 0 is named "uinput-fpc" which seems to be my phone's fingerprint reader, so pretty sure that's an android issue, not a godot issue.
The problem exists even on some devices that do not have a fingerprint sensor. I tried to fix the gamepad detection like here, but that only fixed the issue on Xiaomi devices. The only solution is to ignoring the "gamepads" with the names "uinput-fpc", "uinput-goodix", but this most likely should happen at the engine level
Godot 3.5 the same problem is reported from Redmi note 10 lite with android 11
I did some reasearch and I came up with the following list:
Input name | Company Name |
---|---|
uinput-fpc | Fingerprint Cards AB |
uinput-goodix | Goodix |
uinput-synaptics | Synaptics |
uinput-elan | ElanTech |
uinput-vfs | Validity Sensors (acquired by Synaptics) |
uinput-atrus | Atrua Technologies |
As @ICatRegister mentioned, I think this "blacklist" should be controlled via the engine, and disregard those names as inputs (or at least as joypad/controller inputs)
As a side note, because this issue is for Android, I found out that iOS also seems to get some kind of "ghost" controller on 0
, called "Gamepad". It might be also related to the fingerprint or face ID drivers. Just wanted to let you know that.
Someone on Twitter pointed out that those inputs might be used "to read gestures like swiping and such", so now I don't know if it might be a good idea to just disregard them, but maybe control them in some way so they are treated as "special" input or something.
Here's what I ended up doing. Basically, brute force :P
const INPUT_BLACKLIST := [
"uinput-fpc",
"uinput-goodix",
"uinput-synaptics",
"uinput-elan",
"uinput-vfs",
"uinput-atrus",
"Gamepad",
]
if (
(OS.has_feature("Android") or OS.has_feature("iOS"))
and Input.get_joy_name(0) in INPUT_BLACKLIST
):
return
I ran into this problem myself.
This is an OS bug that must be workarounded. This is the output of a POCO X4 Pro:
uinput-goodix
Device ID: 3
Vendor ID: 1638
Device ID: 2184
Sources Mask: 16778513
Virtual :false
External :false
All numbers are in decimal.
"uinput-goodix" literally pretends to be a SOURCE_GAMEPAD
(1025) and SOURCE_JOYSTICK
(16777232). This has no proper solution since the OS is lying.
The only proper workaround is the proposed one: ignore at engine level these broken devices by name:
if (device.name.startsWith("uinput-")) {
// Broken OS that report fingerprint scanner and other
// unrelated devices as both GAMEPAD and JOYSTICK.
//
// At the very least these are known to cause problems:
// uinput-fpc
// uinput-fortsense
// uinput-goodix
Log.w("Godot", "Ignoring input device: " + device.name)
return false;
}
CC @m4gr3d
Godot version: 3.2.3
OS/device: Running Godot on Windows 10 Running game on Xiaomi Redmi 9 with Android 10 (MIUI 12 if that's relevant)
Issue description: Expected: Device 0 is nothing or bluetooth joypad that is synced Result: Device 0 is "uinput-fpc" and if a joypad is synced the joypad is device 1
Steps to reproduce: make Input.get_joy_name(0) readable while running a game on the device
minimal example.zip