ny00
Unfortunately, simply checking the return codes of "onNativePadDown/Up" as previously done has its own issue:
If an SDL joystick is connected *and* opened, then a proper KeyEvent, say with keycode KEYCODE_BUTTON_1, should lead to an SDL joystick button event as expected.
If, however, the joystick was *not* opened, then "onNativePadDown/Up" will return a negative value, so before the commit from bug 3426, you could unexpectedly get a keyboard event. (In practice, you'll just get a log message, since KEYCODE_BUTTON_1 has no mapping to a proper SDL_ScanCode value, but it's still an problem).
What should still be done, though, is checking the key code itself. We do have the KeyEvent.isGamepadButton method, but according my test, it returns "true" exactly (and only) for the KEYCODE_BUTTON* values, and not for KEYCODE_DPAD* or any other key code.
Here is a possible solution:
- Do check the return codes of "onNativePadDown/Up" as previously done.
- In addition, in "Android_OnPadDown/Up" from src/joystick/android/SDL_sysjoystick.c, 0 should *always* be returned in case the key code can be translated to an SDL_joystick button; Even if no matching joystick can be found.
Sylvain
After a long time, I found out more clearly what was going wrong.
The native libraries should be built with a "APP_PLATFORM" as low as possible.
Ideally, APP_PLATFORM should be equals to the minSdkVersion of the AndroidManifest.xml
So that the application never runs on a lower APP_PLATFORM than it has been built for.
An additional good patch would be to write explicitly in "jni/Application.mk": APP_PLATFORM=android-10
(If no APP_PLATFORM is set, the "targetSdkVersion" of the AndroidManifest.xml is applied as an APP_PLATFORM to the native libraries. And currently, this is bad, because targetSdkVersion is 12, whereas minSdkLevel is 10.
And in fact, there is a warning from ndk: "Android NDK: WARNING: APP_PLATFORM android-12 is larger than android:minSdkVersion 10 in ./AndroidManifest.xml".)
to precise what happened in the initial reported test-case:
Let say the "c" code contains a call to "srand()".
with APP_PLATFORM=android-21, libSDL2.so contains a undef reference to "srand()".
with APP_PLATFORM=android-10, libSDL2.so contains a undef reference to "srand48()".
but srand() is missing on devices with APP_PLATFORM=android-10 (it was in fact replaced by srand48()).
So, if you build for android-21 (where srand() is available), you will really have a call to "srand()" and it will fail on android-10.
That was the issue. The path tried to fix this by in fact always calling srand48().
SDL patches that were applied are beneficial anyway, there are implicitly allowing they backward compatibility of using android-21 on a android-10 platform.
It can be helpful in case you want to target a higher APP_PLATFORM than minSdkVersion to have potentially access to more functions.
Eg you want to have access to GLES3 functions (or other) of "android-21". But, if dlopen() fails (on android-10), you do a fall-back to GLES2.
Deve
When I'm trying to close on-screen keyboard using SDL_StopTextInput() function by touching the screen (SDL_FINGERUP or SDL_FINGERDOWN event), the screen is flickering. It is white for a while.
Note that it usually works without problems when I use phone's "back" button. I noticed flickering occasionally too, but not that often.
Philipp Wiesemann
The attached patch maybe fixes the flicker but not the actual fault causing it.
ny00
This report is going to cover three issues, with a suggestion for fixes. For reference, tests were done using an installation of android-x86-5.1-rc1.iso within a VirtualBox session. I've actually used an adapter that accepts up to two Playstation 1/2 controllers.
A ZIP file should be attached, with the following contents:
- The patch file itself.
- Outputs of joysticks lists from testjoystick with different orders (before fixing bug).
- Game controllers database entries (for reference).
--- Different outputs for different platforms may stem from different tools being used; The Android mapping was manually constructed using a previously available mapping as a base.
--- Note that it turns out the Linux mapping is already out there in some form: https://github.com/gabomdq/SDL_GameControllerDB/blob/master/gamecontrollerdb.txt
And so, let's begin listing the issues:
1. While changeset https://hg.libsdl.org/SDL/rev/9b540bea3cf1 has good intentions, it appears to make various input devices being mistakenly detected as SDL joysticks. I got lists of the devices from joysticktest, given in the ZIP file. "badordering.txt" is what I get if the device has been plugged since a reboot of the virtual machine, while I've gotten "goodordering.txt" after hot-plugging the USB adapter. As expected, only in the latter case I could use the controller in the test program (assuming it isn't modified).
To take care of this, I updated pollInputDevices and added the function SDLActivity.isDeviceSDLJoystick, in order to have a better filter. Note that it also checks that the device id is non-negative, since VIRTUAL_KEYBOARD appears to include a SOURCE_DPAD, and I should probably keep accepting it as an SDL_joystick (good if you want, say, to support multiple independent d-pad devices).
I hope the device id filter does not break support for the virtual remote (mentioned in the changeset above).
2. So there's a weird glitch here, where the game controller is reported to have SOURCE_KEYBOARD and SOURCE_JOYSTICK, while each controller button press/release emits a KeyEvent with SOURCE_KEYBOARD only. So obviously any test going over the event's own sources is expected to fail.
It is possible to try and filter by the key code, but then there are the dpad key codes, which can also be emitted by actual PC keyboard's key presses/releases (the arrow keys).
So instead, I just call the newly added isDeviceSDLJoystick function again and check if the input device (not the event) has any source considered to be a joystick/gamepad for us.
3. Finally, if SDL2 properly detects an SDL_Joystick being connected, but it is not opened, then whenever a KeyEvent is received after a button press/release from the same controller, SDLActivity.onNativePadDown/onNativePadUp returns a negative value. In such a case, the onKey handler continues to check for SOURCE_KEYBOARD (and possibly also SOURCE_MOUSE), which is clearly not desired.
And so, in the given patch, the return values of onNativePadDown and onNativePadUp are ignored and "true" is returned either way.
(Note: Maybe the native functions should be modified to have the return value of "void".)
Finally, as another side-note, I've noticed that the various bitwise tests for sources are wrong. For instance, to check if an InputDevice 'device' has source SOURCE_JOYSTICK, the value (device.getSources() & SOURCE_JOYSTICK) should be compared to SOURCE_JOYSTICK, not 0.
However, I think there's enough that this patch covers. At the least, isDeviceSDLJoystick partially solves this.
This conversation came from Joshua Granick on Twitter, starting here:
https://twitter.com/singmajesty/status/653640543675641857
"We found an issue where certain Android keyboards (like the S6 with
predictive text) wouldn't work ... Certain keyboards use a predictive text
mode that does not dispatch a traditional onKey events, which is troublesome
... but telling the OS to use a "visible password" keyboard helps deal with
this problem ... perhaps there's some other way (onKeyPreIme?) to do
"textediting" events, but for now, this should be a fast fix ...
I hear it affects the Galaxy Tab A 8.0", Galaxy S6, Asus ZenPhone 2, maybe
others"
They were not needed internally since the switch to the common EGL backend.
Thanks to the SDL mailing list for pointing out that the functions seem unused.
It was redundant because SDLActivity already inherits an empty method from the
base class SurfaceView (which does not implement it but inherits it from View).
Visibility of onDraw() in SDLActivity is now protected again instead of public.
The internal function SDL_EGL_LoadLibrary() did not delete and remove a mostly
uninitialized data structure if loading the library first failed. A later try to
use EGL then skipped initialization and assumed it was previously successful
because the data structure now already existed. This led to at least one crash
in the internal function SDL_EGL_ChooseConfig() because a NULL pointer was
dereferenced to make a call to eglBindAPI().