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

onResume deadlock with pyjnius/pygame/sdl on android #890

Closed
hottwaj opened this issue Sep 24, 2016 · 1 comment
Closed

onResume deadlock with pyjnius/pygame/sdl on android #890

hottwaj opened this issue Sep 24, 2016 · 1 comment

Comments

@hottwaj
Copy link
Contributor

hottwaj commented Sep 24, 2016

It seems that interaction between android.pyx, pyjnius and app pause mode can cause deadlock when going into pause mode or when resuming from pause mode. I am using the pygame bootstrap.

A few logs and things below to show what's going on

Here's the typical sequence - first I press the home button and the app should pause.

I/python  ( 4288): [INFO   ] [Android     ] Must go into sleep mode, check the app
I/python  ( 4288): [INFO   ] [Android     ] App paused, now wait for resume.
I/System.out( 4288): python pyjnius java:invoke(<proxy>, public abstract void android.view.ViewTreeObserver$OnGlobalLayoutListener.onGlobalLayout(), [Ljava.lang.Object;@33d6fa5f)

Note that after the "app paused" message, the Java interface of pyjnius receives a call which it tries to push to Python. The log message is from line 15 of NativeInvocationHandler.java of pyjnius

The above happens before I try to resume my app.

Once I try to resume, I get a black screen and nothing happens. I have logging setup on the pygame bootstrap and I can see that the app's onResume() method in PythonActivity.java is never called.

I get the following log output

W/ActivityManager( 1005): Activity stop timeout for ActivityRecord{20c40984 u0 org.hottwaj.hottwajtest/org.renpy.android.PythonActivity t8207}
I/ActivityManager( 1005): Activity reported stop, but no longer stopping: ActivityRecord{20c40984 u0 org.hottwaj.hottwajtest/org.renpy.android.PythonActivity t8207}
W/ActivityManager( 1005): Activity pause timeout for ActivityRecord{20c40984 u0 org.hottwaj.hottwajtest/org.renpy.android.PythonActivity t8207}
W/ActivityManager( 1005): Activity stop timeout for ActivityRecord{20c40984 u0 org.hottwaj.hottwajtest/org.renpy.android.PythonActivity t8207}
I/ActivityManager( 1005): Killing 4288:org.hottwaj.hottwajtest:python/u0a281 (adj 11): remove task
I/WindowState( 1005): WIN DEATH: Window{2a469087 u0 org.hottwaj.hottwajtest/org.renpy.android.PythonActivity}
W/WindowManager( 1005): Force-removing child win Window{200ab265 u0 SurfaceView} from container Window{2a469087 u0 org.hottwaj.hottwajtest/org.renpy.android.PythonActivity}

Normally I can only trigger this outcome if I press the "home" button. If I open the "apps task switcher" menu and then immediately switch back to my app, resume is handled correctly.

I believe this is a deadlock issue because occasionally an ANR crash occurs (not always though - probably because the call to NativeInvocationHandler.java does not always happen before app pause, but sometimes happens on resume).

Below is the ANR stack trace which sometimes occurs when the app is resumed and has been sat at black screen for a while - the crash occurs because pyjnius' NativeInvocationHandler.java can't get hold of a lock on a python thread (GIL maybe?)

It seems like either pyjnius or PythonActivity.java need to somehow "know" that the app is paused in order to somehow prevent this situation?

"main" prio=5 tid=1 Native
  | group="main" sCount=1 dsCount=0 obj=0x87b73000 self=0xb7eaa318
  | sysTid=16668 nice=0 cgrp=apps sched=0/0 handle=0xb6f9cec8
  | state=S schedstat=( 908140747 218315933 1314 ) utm=82 stm=8 core=3 HZ=100
  | stack=0xbe449000-0xbe44b000 stackSize=8MB
  | held mutexes=
  native: #00 pc 0000f628  /system/lib/libc.so (syscall+28)
  native: #01 pc 00012dfd  /system/lib/libc.so (_Z33__pthread_cond_timedwait_relativeP14pthread_cond_tP15pthread_mutex_tPK8timespec+56)
  native: #02 pc 0012a6c8  /data/app/org.hottwaj.hottwajtest-2/lib/arm/libpython2.7.so (PyThread_acquire_lock+76)
  at org.jnius.NativeInvocationHandler.invoke0(Native method)
  at org.jnius.NativeInvocationHandler.invoke(NativeInvocationHandler.java:26)
  at java.lang.reflect.Proxy.invoke(Proxy.java:397)
  at android.view.ViewTreeObserver$OnGlobalLayoutListener.onGlobalLayout(ViewTreeObserver.java:-2)
  at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:889)
  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2128)
  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1239)
  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6752)
  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
  at android.view.Choreographer.doCallbacks(Choreographer.java:590)
  at android.view.Choreographer.doFrame(Choreographer.java:560)
  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
  at android.os.Handler.handleCallback(Handler.java:739)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:145)
  at android.app.ActivityThread.main(ActivityThread.java:6145)
  at java.lang.reflect.Method.invoke!(Native method)
  at java.lang.reflect.Method.invoke(Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
hottwaj added a commit to hottwaj/python-for-android that referenced this issue Sep 25, 2016
Moved java LayoutListener logic out of 'android' package into pygame bootstrap

This avoids deadlock due to LayoutListener locking python thread with pyjnius when app onPause/onResume occurs
@mrhdias
Copy link
Contributor

mrhdias commented Oct 26, 2016

I have the same problem when back button is pressed (escape). I fix the issue with the following code:

def on_keyboard(self, window, key, scancode=None, codepoint=None, modifier=None):
    if platform == 'android' and key == 27:
        from jnius import autoclass, cast
        PythonActivity = autoclass('org.kivy.android.PythonActivity')
        activity = PythonActivity.mActivity
        Intent = autoclass('android.content.Intent')
        intent = Intent()
        intent.setAction(Intent.ACTION_MAIN)
        intent.addCategory(Intent.CATEGORY_HOME);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        currentActivity = cast('android.app.Activity', activity)
        currentActivity.startActivity(intent)
    return True

akshayaurora added a commit that referenced this issue Oct 27, 2016
fix layout listener related issues. Closes #890
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants