We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2258

Summary: Crash when using Android clipboard
Product: SDL Reporter: chw
Component: eventsAssignee: Gabriel Jacobo <gabomdq>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: gabomdq, philipp.wiesemann
Version: 2.0.0   
Hardware: All   
OS: Android (All)   
Attachments: Android clipboard crash fix etc.
Patch for creating a single ClipboardManager on correct thread.
Patch for creating a single ClipboardManager on correct thread by blocking.
Android clipboard crash fix etc. (Second try)

Description chw 2013-11-21 06:23:19 UTC
Created attachment 1463 [details]
Android clipboard crash fix etc.

The Android clipboard manager methods must be called from the UI thread, otherwise crashes of the dalvikvm happen. The attached patch fixes this by wrapping the clipboard manager calls in Android.runOnUiThread calls.

Additionally, a public API has been added to allow the SDL application code to find out the path name of its APK.
Comment 1 Gabriel Jacobo 2013-11-22 13:41:26 UTC
I wonder if this can be fixed in a simpler manner. According to this answer: http://stackoverflow.com/a/12946228/991573 it seems that it may be possible to create the clipboard service in Java on the main thread (probably before starting the native thread), and then pass that to the native side, which would require a minor change in SETUP_CLIPBOARD and in SDLActivity.

How does this sound? Is there anything I'm missing?
Comment 2 Philipp Wiesemann 2013-11-23 11:34:02 UTC
runOnUiThread() already checks if this is the UI thread and executes the runnable immediately if this is the case. [1] Checking this manually saves the creation of one Runnable object but produces two nearly identical sequences of statements (three times because of three functions).

I do not see what SDL_AndroidGetPackageCodePath() may be useful for. [2] There is already a possibility in SDL to access the assets and the returned path should be read-only on most devices anyway.

Also for me this did not crash yet (which does not matter if it crashes on other devices :). Maybe this is the reason problem was not found and fixed earlier.

[1] http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29
[2] http://developer.android.com/reference/android/content/ContextWrapper.html#getPackageCodePath%28%29
Comment 3 Gabriel Jacobo 2013-11-23 12:58:49 UTC
Let's try to avoid adding more stuff on the Java side if possible! If getting the clipboard service once in the main thread and then using it from C works, let's do that.
Comment 4 Philipp Wiesemann 2013-11-23 15:43:08 UTC
Created attachment 1467 [details]
Patch for creating a single ClipboardManager on correct thread.

I added a patch for creating a single ClipboardManager on UI thread. It is always created and reused (was not the case before). Therefore this might be a new overhead for applications not using the clipboard.

A different solution would be to use the idea from the original patch (blocking the calling thread until something happened on UI thread) and just write a "wrapper" for getSystemService() which may be called from another thread. This solution could also be used if more system services are needed in the future (e.g. vibration for SDL's haptic subsystem).
Comment 5 Philipp Wiesemann 2013-11-23 17:19:11 UTC
Created attachment 1468 [details]
Patch for creating a single ClipboardManager on correct thread by blocking.

I added a new patch and marked the previous as obsolete because this one is better. It just wraps getSystemService() to be executed on UI thread using the "blocking" idea from the original patch. This way there is no overhead if clipboard is not used and few new Java source and the actual problem should be fixed.

It was now possible for me to get the "crash" in the Android emulator but not on a real device (maybe it depends on Android version). The "crash" did not happen with this and the last patch active.
Comment 6 chw 2013-11-23 17:56:55 UTC
Created attachment 1469 [details]
Android clipboard crash fix etc. (Second try)
Comment 7 chw 2013-11-23 17:58:17 UTC
The reason for SDL_AndroidGetPackageCodePath is my port of Tcl/Tk on Android. The Tcl part wants to "mount" the APK to get the "/assets..." payload without going through SDL's filesystem layer and needs therefore knowledge of the path name of the APK.

Regarding the Clipboard I think it's more complicated. On my Android 4.x devices it seems to be sufficient to obtain the clipboard service during SDLActivity.onCreate as described in the stackoverlow posting. But then there's API level < 11.

Another point is that it is desirable to get SDL_CLIPBOARDUPDATE events at least for API level >= 11.

I've tried to address these points in the attached patch.
Comment 8 Gabriel Jacobo 2013-11-23 21:04:12 UTC
@Philip, your patch looks ok to me, let's get it committed.
@chw, I'm not opposed to having notifications for clipboard updates on API level >=11, let's try to get that reworked after Philipp lands his patch and remember to try to keep the Java side to the bare minimum. Thanks!
Comment 9 chw 2013-11-23 22:43:26 UTC
@Gabriel, Philipp: please consider to take in SDL_AndroidGetPackageCodePath(), I desperately need it for Tcl/Tk on Android. And please check my X11 patch, too. It handles SelectionClear X11 events by sending SDL_CLIPBOARDUPDATE.
Comment 10 Philipp Wiesemann 2013-11-23 22:47:25 UTC
Fixed (reported bug, not additional features):
https://hg.libsdl.org/SDL/rev/cf81e6709b3d
Comment 11 Sam Lantinga 2013-11-23 22:52:50 UTC
chw, please report separate bugs for the individual improvements you're proposing.

Thanks!
Comment 12 Gabriel Jacobo 2013-11-23 22:56:45 UTC
Thanks!

@chw, I guess I don't really see the overall benefit of the SDL_AndroidGetPackageCodePath function for users in general, but I'm open to hearing the argument, either from reason or from popularity :)

BTW, you should submit your enhancements separately, that way it'll be easier to keep track of them (don't cram two Android and a X11 fixes in a single patch/bug report). Anyway, sorry for the red tape, and thanks for your time and effort!
Comment 13 Philipp Wiesemann 2013-11-23 23:14:17 UTC
(In reply to chw from comment #9)
> @Gabriel, Philipp: please consider to take in
> SDL_AndroidGetPackageCodePath(), I desperately need it for Tcl/Tk on
> Android. And please check my X11 patch, too. It handles SelectionClear X11
> events by sending SDL_CLIPBOARDUPDATE.

SDL_AndroidGetPackageCodePath() should work outside SDL_android.c if Android_JNI_GetEnv() would be replaced with SDL_AndroidGetJNIEnv() and the "get context" section would be replaced with SDL_AndroidGetActivity(). Both functions are public API of SDL_system.h. Also jni.h would be needed to make the JNI functions available.