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/f6567f77f663 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.
Sylvain
I have an android device to which I try to connect the google virtual remote application.
https://play.google.com/store/apps/details?id=com.google.android.tv.remote
The java method "pollInputDevices()" detects it as an input source 0x701 which is (SOURCE_KEYBOARD | SOURCE_GAMEPAD | SOURCE_DPAD).
It it not added because it does not AND-bitwise with "SOURCE_CLASS_JOYSTICK".
It's only a virtual DPAD and it works when checking also with SOURCE_CLASS_BUTTON
Sylvain
With a Landscape application.
Going to background with Home Key, then foreground.
The screen is distorted.
This has been reported by Samsung. It happens on S5 and Samsung Alpha, see the video attached.
I have captured the following logcat:
V/SDL (20549): onResume()
V/SDL (20549): surfaceCreated()
V/SDL (20549): surfaceChanged()
V/SDL (20549): pixel format RGB_565
V/SDL (20549): Window size:1920x1080
I/SDL (20549): SDL_Android_Init()
I/SDL (20549): SDL_Android_Init() finished!
V/SDL (20549): SDL audio: opening device
V/SDL (20549): SDL audio: wanted stereo 16-bit 22.05kHz, 256 frames buffer
V/SDL (20549): SDL audio: got stereo 16-bit 22.05kHz, 1764 frames buffer
V/SDL (20549): onWindowFocusChanged(): true
V/SDL (20549): onWindowFocusChanged(): false
V/SDL (20549): onPause()
V/SDL (20549): nativePause()
V/SDL (20549): surfaceDestroyed()
Background / Foreground
V/SDL (20549): onResume()
V/SDL (20549): surfaceCreated()
V/SDL (20549): surfaceChanged()
V/SDL (20549): pixel format RGB_565
V/SDL (20549): Window size:1080x1920
V/SDL (20549): surfaceChanged()
V/SDL (20549): pixel format RGB_565
V/SDL (20549): Window size:1920x1080
V/SDL (20549): onWindowFocusChanged(): true
V/SDL (20549): nativeResume()
This seems to be related to the fact that I have in "AndroidManifest.xml":
android:configChanges="..."
Because of the fields: "orientation" and also "screenSize".
I have looked for another way to solve the issue. Discarding the "surfaceChanged" call, based on the "requestedOrientation" and the new Orientation. It seems to be better.
On my failing test case, the first "surfaceChanged()" is discarded. Sometimes the "focusChanged()" might appear between the two "surfaceChanged()", while the surface is not yet ready. Thus, discarding also the "nativeResume()".
So, for robustness, a call to "nativeResume()" is added at the end of "surfaceChanged()".
Some update:
1/ First I tried, to discard the surface using the current orientation (rather than width / heigh). -> that solve the issue sometimes, but not always.
2/ Samsung Certification now accepts my application that were previously failing.
3/ I personally now owns a Samsung S5, and was able to solve the issue on my side.
4/ I now use the patch and get no complaints from my users. (but I admit, nobody seemed to be complaining before neither...).
5/ I have added a v2 because of a new smart-phone called "Black Berry Passport" that has a square screen of 1440x1440. This screen has a "status bar" so the resolution is in fact : 1440x1308. (as reported by "surfaceChanged").
Problem is: the portrait resolution is in fact a Landscape!
So the "v1" patch is always discarding the "surface" of BlackBerry Passport. Which is terribly bad.
Hence, I added the "v2" patch not to discard the surface when aspect ratio is < 1.20. (BB 1440/1308 is : 1.1009). Which seems fair.
This lets SDL-based apps respond to "Open With" commands properly, as they
can now obtain the requested path via a standard SDL dropfile event.
This is only checked on startup, so apps don't get drop events at any other
time, even if Android supports that, but this is still a definite
improvement.
Fixes Bugzilla #2762.
According to the documentation of Android's MotionEvent, the getPressure() may
return values higher than 1 on some devices. To prevent passing such values into
SDL they are now corrected to 1 in Java before the JNI call (where it is assumed
to be correct).
Currently SDL only sends SDL_FINGERMOTION events if the touch state (position or
pressure) changed. By correcting pressure down to 1 some events may get dropped
in the rare case that only the pressure was changed but was out of range and the
position did not change.
This avoids a hint lookup for each mouse event we get by setting a static Java
variable from native code during our hint watcher callback.
Also attempts to do the right thing with mouse buttons if you happen to be
on an API14 (Ice Cream Sandwich, Android 4.0) or later device. We still
target API12 (Honeycomb MR1, Android 3.1) for SDL 2.0.4 though.
This isn't tested, so I'm pushing to see what the Android buildbot says. Stand
back, I'm a professional!
--HG--
extra : amend_source : 7748c650f37edd47c721e4e7e96cf5995f5ac459
If the alert dialog could be canceled the Activity would not be finished here.
Also setting the property to "true" would be redundant because that is default.