Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android joystick fixes #24604

Merged
merged 13 commits into from
Feb 2, 2024
Merged

Android joystick fixes #24604

merged 13 commits into from
Feb 2, 2024

Conversation

garbear
Copy link
Member

@garbear garbear commented Jan 29, 2024

Description

This PR introduces fixes for most of the Android bugs demonstrated in the last few months. The fixes are as follows:

  • Fixed mapping PS4 trigger analog axes to digital buttons
  • Fixed missing keyboard keys from newer NDKs in debug log
  • Fixed generic joysticks that Android doesn't know how to map
  • Fixed input for controllers with only a MOUSE source
  • (new) Fixed input for controllers that report buttons from a KEYBOARD source

I also added functionality to automatically configure controllers based on the buttonmaps provided by Android (e.g. android knows which button belongs to AKEYCODE_BUTTON_A).

Note that due to the improved button and axis handling, most Android controllers will need to be remapped. I've provided new mappings for most of our existing buttonmaps in xbmc/peripheral.joystick#297.

I also added a feature that automatically maps controllers on Android, so we don't need new buttonmaps anymore.

Motivation and context

Tracking thread: https://forum.kodi.tv/showthread.php?tid=376084

Fixes #24502.

How has this been tested?

Included in my latest round of test builds: https://github.com/garbear/xbmc/releases/tag/retroplayer-21beta2-20240129

Mapping PS4 trigger

See buttonmaps in xbmc/peripheral.joystick#297 for successful map:

<configuration>
    <button index="6" ignore="true" />
    <button index="7" ignore="true" />
</configuration>
<controller id="game.controller.ps.dualanalog">
    <feature name="lefttrigger" axis="+2" />
    <feature name="righttrigger" axis="+5" />
</controller>

Improved logging

garbear#137 shows buttonmapping the D-pad with improved logging (presence of semiaxis -1 and semiaxis +0):

debug <general>: game.controller.snes: Waiting for input for feature "up"
debug <general>: Normal axis detected on axis 1
debug <general>: game.controller.snes: mapping feature "up" for device android/inputdevice/151 to "semiaxis -1"
debug <general>: game.controller.snes: Waiting for input for feature "right"
debug <general>: Normal axis detected on axis 0
debug <general>: game.controller.snes: mapping feature "right" for device android/inputdevice/151 to "semiaxis +0"

Missing keyboard keys

Keys from newer NDK now appear for my media center keyboard:

debug <general>: CPeripheralBusAndroid: Device discovered:
debug <general>:   Name: "Microsoft Microsoft® Nano Transceiver v2.0"
...
debug <general>:     Has key: AKEYCODE_CUT (277)
debug <general>:     Has key: AKEYCODE_COPY (278)
debug <general>:     Has key: AKEYCODE_PASTE (279)

Generic joysticks that Android can't map

TODO: Report on fix in tracking thread

Problematic controller from debug log in reporting thread (https://forum.kodi.tv/showthread.php?tid=374826):

debug <general>: CPeripheralBusAndroid: Device added:
debug <general>:   Name: "ShanWan USB WirelessGamepad "
debug <general>:     ID: 8
debug <general>:     Controller number: 0
debug <general>:     Descriptor: "8fc8f592930f33..."
debug <general>:     Product ID: 0523
debug <general>:     Vendor ID: 2563
debug <general>:     Has microphone: false
debug <general>:     Is virtual: false
debug <general>:     Source flags: 0x1000111
debug <general>:     Has source: SOURCE_JOYSTICK (0x1000010)
debug <general>:     Has source: SOURCE_KEYBOARD (0x000101)
debug <general>:     Has key: AKEYCODE_BUTTON_1 (188)
debug <general>:     Has key: AKEYCODE_BUTTON_2 (189)
debug <general>:     Has key: AKEYCODE_BUTTON_3 (190)
debug <general>:     Has key: AKEYCODE_BUTTON_4 (191)
debug <general>:     Has key: AKEYCODE_BUTTON_5 (192)
debug <general>:     Has key: AKEYCODE_BUTTON_6 (193)
debug <general>:     Has key: AKEYCODE_BUTTON_7 (194)
debug <general>:     Has key: AKEYCODE_BUTTON_8 (195)
debug <general>:     Has key: AKEYCODE_BUTTON_9 (196)
debug <general>:     Has key: AKEYCODE_BUTTON_10 (197)
debug <general>:     Has key: AKEYCODE_BUTTON_11 (198)
debug <general>:     Has key: AKEYCODE_BUTTON_12 (199)
debug <general>:     Has axis: AMOTION_EVENT_AXIS_HAT_Y (16)
debug <general>:       Endpoints: [-1.000000, 1.000000]
debug <general>:       Center: 0.000000
debug <general>:       Fuzz: 0.000000
debug <general>:     Has axis: AMOTION_EVENT_AXIS_Z (11)
debug <general>:       Endpoints: [-1.000000, 1.000000]
debug <general>:       Center: 0.117647
debug <general>:       Fuzz: 0.000000
debug <general>:     Has axis: AMOTION_EVENT_AXIS_RZ (14)
debug <general>:       Endpoints: [-1.000000, 1.000000]
debug <general>:       Center: 0.117647
debug <general>:       Fuzz: 0.000000
debug <general>:     Has axis: AMOTION_EVENT_AXIS_HAT_X (15)
debug <general>:       Endpoints: [-1.000000, 1.000000]
debug <general>:       Center: 0.000000
debug <general>:       Fuzz: 0.000000
debug <general>:     Has axis: AMOTION_EVENT_AXIS_Y (1)
debug <general>:       Endpoints: [-1.000000, 1.000000]
debug <general>:       Center: 0.117647
debug <general>:       Fuzz: 0.000000
debug <general>:     Has axis: AMOTION_EVENT_AXIS_X (0)
debug <general>:       Endpoints: [-1.000000, 1.000000]
debug <general>:       Center: 0.117647
debug <general>:       Fuzz: 0.000000
debug <general>: CPeripheralBusAndroid: input device with ID 8 added

Problematic controller from debug log in reporting issue (garbear#137):

debug <general>: CPeripheralBusAndroid: Device discovered:
debug <general>:   Name: "Logitech Logitech(R) Precision(TM) Gamepad"
debug <general>:     ID: 132
debug <general>:     Controller number: 0
debug <general>:     Descriptor: "4704e7c96f110c..."
debug <general>:     Product ID: C21A
debug <general>:     Vendor ID: 046D
debug <general>:     Has microphone: false
debug <general>:     Is virtual: false
debug <general>:     Source flags: 0x1000111
debug <general>:     Has source: SOURCE_JOYSTICK (0x1000010)
debug <general>:     Has source: SOURCE_KEYBOARD (0x000101)
debug <general>:     Has key: AKEYCODE_BUTTON_1 (188)
debug <general>:     Has key: AKEYCODE_BUTTON_2 (189)
debug <general>:     Has key: AKEYCODE_BUTTON_3 (190)
debug <general>:     Has key: AKEYCODE_BUTTON_4 (191)
debug <general>:     Has key: AKEYCODE_BUTTON_5 (192)
debug <general>:     Has key: AKEYCODE_BUTTON_6 (193)
debug <general>:     Has key: AKEYCODE_BUTTON_7 (194)
debug <general>:     Has key: AKEYCODE_BUTTON_8 (195)
debug <general>:     Has key: AKEYCODE_BUTTON_9 (196)
debug <general>:     Has key: AKEYCODE_BUTTON_10 (197)
debug <general>:     Has axis: AMOTION_EVENT_AXIS_X (0)
debug <general>:       Endpoints: [-1.000000, 1.000000]
debug <general>:       Center: 0.117647
debug <general>:       Fuzz: 0.000000
debug <general>:     Has axis: AMOTION_EVENT_AXIS_Y (1)
debug <general>:       Endpoints: [-1.000000, 1.000000]
debug <general>:       Center: 0.117647
debug <general>:       Fuzz: 0.000000
info <general>: CPeripheralBusAndroid: added input device

Input for controllers with only MOUSE source

TODO: Report on fix in tracking thread

Problematic controller(s) from debug log in reporting thread (https://forum.kodi.tv/showthread.php?tid=375790):

debug <general>: Input device added: 17
debug <general>: CPeripheralBusAndroid: Device added:
debug <general>:   Name: "Wireless Controller Touchpad"
debug <general>:     ID: 17
debug <general>:     Controller number: 0
debug <general>:     Descriptor: "c3cae1a006dd5b..."
debug <general>:     Product ID: 05C4
debug <general>:     Vendor ID: 054C
debug <general>:     Has microphone: false
debug <general>:     Is virtual: false
debug <general>:     Source flags: 0x002002
debug <general>:     Has source: SOURCE_MOUSE (0x002002)
debug <general>:     Has axis: AMOTION_EVENT_AXIS_X (0)
debug <general>:       Endpoints: [0.000000, 1919.000000]
debug <general>:       Center: 0.000000
debug <general>:       Fuzz: 0.000000
debug <general>:     Has axis: AMOTION_EVENT_AXIS_Y (1)
debug <general>:       Endpoints: [0.000000, 1079.000000]
debug <general>:       Center: 0.000000
debug <general>:       Fuzz: 0.000000
debug <general>:     Has axis: AMOTION_EVENT_AXIS_PRESSURE (2)
debug <general>:       Endpoints: [0.000000, 1.000000]
debug <general>:       Center: 0.000000
debug <general>:       Fuzz: 0.000000
debug <general>: CPeripheralBusAndroid: ignoring non-joystick device
warning <general>: CPeripheralBusAndroid: ignoring input event for unknown input device with ID 17
...
debug <general>: Input device added: 18
debug <general>: CPeripheralBusAndroid: Device added:
debug <general>:   Name: "Wireless Controller Touchpad"
debug <general>:     ID: 18
debug <general>:     Controller number: 0
debug <general>:     Descriptor: "16624c4a49f8e5..."
debug <general>:     Product ID: 05C4
debug <general>:     Vendor ID: 054C
debug <general>:     Has microphone: false
debug <general>:     Is virtual: false
debug <general>:     Source flags: 0x002002
debug <general>:     Has source: SOURCE_MOUSE (0x002002)
debug <general>:     Has key: AKEYCODE_BUTTON_A (96)
debug <general>:     Has key: AKEYCODE_BUTTON_B (97)
debug <general>:     Has key: AKEYCODE_BUTTON_X (99)
debug <general>:     Has key: AKEYCODE_BUTTON_Y (100)
debug <general>:     Has key: AKEYCODE_BUTTON_L1 (102)
debug <general>:     Has key: AKEYCODE_BUTTON_R1 (103)
debug <general>:     Has key: AKEYCODE_BUTTON_L2 (104)
debug <general>:     Has key: AKEYCODE_BUTTON_R2 (105)
debug <general>:     Has key: AKEYCODE_BUTTON_THUMBL (106)
debug <general>:     Has key: AKEYCODE_BUTTON_THUMBR (107)
debug <general>:     Has key: AKEYCODE_BUTTON_START (108)
debug <general>:     Has key: AKEYCODE_BUTTON_SELECT (109)
debug <general>:     Has key: AKEYCODE_BUTTON_MODE (110)
debug <general>:     Has axis: AMOTION_EVENT_AXIS_X (0)
debug <general>:       Endpoints: [0.000000, 1919.000000]
debug <general>:       Center: 0.000000
debug <general>:       Fuzz: 0.000000
debug <general>:     Has axis: AMOTION_EVENT_AXIS_Y (1)
debug <general>:       Endpoints: [0.000000, 1079.000000]
debug <general>:       Center: 0.000000
debug <general>:       Fuzz: 0.000000
debug <general>:     Has axis: AMOTION_EVENT_AXIS_PRESSURE (2)
debug <general>:       Endpoints: [0.000000, 1.000000]
debug <general>:       Center: 0.000000
debug <general>:       Fuzz: 0.000000
debug <general>: CPeripheralBusAndroid: ignoring non-joystick device
warning <general>: CPeripheralBusAndroid: ignoring input event for unknown input device with ID 18

What is the effect on users?

See list of fixes in description

Types of change

  • Bug fix (non-breaking change which fixes an issue)
  • Clean up (non-breaking change which removes non-working, unmaintained functionality)
  • Improvement (non-breaking change which improves existing functionality)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that will cause existing functionality to change)
  • Cosmetic change (non-breaking change that doesn't touch code)
  • Student submission (PR was done for educational purposes and will be treated as such)
  • None of the above (please explain below)

Rapid input is dropped when buttonmapping, because some controllers send multiple
events per button press with different button IDs.

However, on the PS4 controller, two events from the same button are sent, one
analog and one digital. Because the digital one is ignored, we shouldn't consider
the analog event a case of rapid input.
Likely due to a past format with clang-format that didn't properly de-indent
the comment blocks.
AKEYCODE_PROFILE_SWITCH is now the final key in keys.h as of NDK 21.4.7075529.
@garbear
Copy link
Member Author

garbear commented Jan 31, 2024

PR updated. I added a nifty feature, because Android maps most controllers, we initialize the buttonmap with Android's mapping, so controllers work out of the box in the UI and in games without having to map it first.

As the PR changes the button counts, it'll wipe out all existing buttonmaps, so it's nice to have the buttonmap regenerated without temporarily losing functionality of the controller.

I'm also getting reports that mapped controllers are working as they should. The only problem controllers left are ones that Android can't map. We're hunting down that bug in garbear#137.

@garbear
Copy link
Member Author

garbear commented Jan 31, 2024

We fixed the last problem I've come across over at garbear#137. The problem was that Android was reporting the button events as coming from a KEYBOARD source. I added a check for this, and now all keyboard keys will first go to the joystick handler, but this should be safe because it mostly ignores non-button keycodes, and the ones it doesn't ignore are automatically mapped to controller actions.

@garbear
Copy link
Member Author

garbear commented Feb 2, 2024

I think this is ready for merge, with the only outstanding problem being some broken input on a Firestick (which I don't think worked before). I've prepared a backport PR, which I'll open after this is merged. Then hopefully we can get 20.4 out soon to fix controllers for most users.

@garbear garbear merged commit f7d0ef9 into xbmc:master Feb 2, 2024
2 checks passed
@garbear garbear deleted the android-joysticks branch February 2, 2024 16:40
@garbear garbear mentioned this pull request Feb 2, 2024
8 tasks
@garbear garbear mentioned this pull request Feb 14, 2024
8 tasks
@Abasz
Copy link

Abasz commented Feb 22, 2024

I can see that the Android joystick fixes have been reverted. Does that mean that these will not make version 21 at all? Its probably not too representative, but I've been using the build with the fixes for 2 weeks without any problems :)

@garbear
Copy link
Member Author

garbear commented Feb 23, 2024

I did a mass-revert for v21 because I ran out of Kodi time and have to focus on other projects.

Not sure when I can return to Kodi (probably some weekend in the near term) but, as fixes, even if I miss the v21.0 point release, fixes in v22 can be backported to v21.

And even if the v21 release branch takes a while to accrue joystick fixes, I'll keep the current ones in my test builds for you and others that don't need remotes.

@Abasz
Copy link

Abasz commented Feb 24, 2024

And even if the v21 release branch takes a while to accrue joystick fixes, I'll keep the current ones in my test builds for you and others that don't need remotes.

This would have been my question whether your will keep this in your test builds. I mean I was prepared to compile my own with your fixes against the main 21 branch but clearly its easier if I dont have to do it :) thanks

@garbear
Copy link
Member Author

garbear commented May 10, 2024

I went through all changes with a fine-toothed comb and broke out most into separate PRs for a much safer process:

The only "unsafe" commit left was the one that touched AINPUT_SOURCE_KEYBOARD, which is the cause of all remotes breaking everywhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Kodi 20.3] Controller integration on Android broke (tested on Ayn Odin and Retroid devices)
3 participants