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

App.on_pause / on_resume on iOS not called properly? #3202

Closed
rnixx opened this issue Mar 30, 2015 · 27 comments
Closed

App.on_pause / on_resume on iOS not called properly? #3202

rnixx opened this issue Mar 30, 2015 · 27 comments
Assignees
Labels
Milestone

Comments

@rnixx
Copy link
Member

rnixx commented Mar 30, 2015

It seems that on_pause/on_resume is not called properly on iOS (iPad mini with iOS 8.2).

Neither when leaving the app via home button, nor when pressing power button on_pause is called, on_resume is not called either when reentering the application.

Any hints?

@tito tito added Status: Needs-analysis Issue needs to be analyzed if it's real Platform: IOS labels Mar 30, 2015
@tito tito added this to the 1.9.1 milestone Mar 30, 2015
@kmonson
Copy link

kmonson commented Apr 14, 2015

I'll second this. I've seen in in the simulator (iOS 6 and 8) and on an Ipad running 7.0. on_stop does not appear to be called either.

@rnixx
Copy link
Member Author

rnixx commented May 5, 2015

Hi, any new insights on this?

@rnixx
Copy link
Member Author

rnixx commented Jun 25, 2015

@dessant on android pause and resume events work fine for me. have you encountered this issue on android as well?

And referring iOS. Anybody with the required knowledge motivated to take a look about this?

@thica
Copy link

thica commented Jul 2, 2015

I can confim, that on Android 5 the on_resume is called very unreliable. It's called most of the time, but not every time. I didn't had this issue with 4.4

@rnixx
Copy link
Member Author

rnixx commented Jul 5, 2015

This issue may be related #1261

@rnixx
Copy link
Member Author

rnixx commented Jul 7, 2015

The iOS App lifecycle, states and corresponding events are documented here
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html#//apple_ref/doc/uid/TP40007072-CH2-SW3

I greped my project and kivy-ios for those events but cannot find anything.

Where does the code for bridging iOS lifecycle events to kivy lifes? Is it implemented at all?

@dessant
Copy link
Contributor

dessant commented Jul 9, 2015

@rnixx somebody on irc reported the same issue on android iirc.

@rnixx
Copy link
Member Author

rnixx commented Jul 14, 2015

now i tried to react as delegate via pyobjus directly. The code looks something like:

if platform == 'ios':
    from pyobjus import protocol

    class IOSPlatformMixin(PlatformMixin):

        @protocol('NSApplicationDelegate.applicationDidBecomeActive')
        def app_did_become_active(self, *args, **kw):
            Logger.debug('IOSPlatformMixin.app_did_become_active')

        @protocol('NSApplicationDelegate.applicationWillResignActive')
        def app_will_resign_active(self, *args, **kw):
            Logger.debug('IOSPlatformMixin.app_will_resign_active')

    PlatformMixin = IOSPlatformMixin

class MyApp(App, PlatformMixin):
    ...

But i cannot get this work either. How do i correctly setup the app lifecycle delegates?

@tito
Copy link
Member

tito commented Jul 14, 2015

I don't think adding specific delegates will work, we are using SDL2, and so, we need to double-check why SDL2 doesn't send the events at all. Or if we correctly manage them or not.

@tito
Copy link
Member

tito commented Jul 14, 2015

Ok, we completly missed thoses when switching to SDL2:

SDL_APP_TERMINATING
OS is terminating the application
SDL_APP_LOWMEMORY
OS is low on memory; free some
SDL_APP_WILLENTERBACKGROUND
application is entering background
SDL_APP_DIDENTERBACKGROUND
application entered background
SDL_APP_WILLENTERFOREGROUND
application is entering foreground
SDL_APP_DIDENTERFOREGROUND
application entered foreground

Will add them and test it right now.

@tito
Copy link
Member

tito commented Jul 14, 2015

Reference: https://wiki.libsdl.org/SDL_EventType

@tito
Copy link
Member

tito commented Jul 14, 2015

So weird. Even without implementing theses event, i can actually pause/resume the pictures demo. I see the vent called.

Currently, pause/resume are implemented on the window minimzed/restored. We could change to will enter background/foreground for android/ios, but still, i don't get the issue on iPad 2 simulator, iPad 3 real device, both iOS 8.2. Checking iPad mini air on iOS 8.4 in simulator.

@tito
Copy link
Member

tito commented Jul 14, 2015

Ok no, my bad, i did change the implementation. One change in kivy for minimizing the app did break this behavior. Fixing it;

@tito tito closed this as completed in d9ae83c Jul 14, 2015
@tito
Copy link
Member

tito commented Jul 14, 2015

You need to use kivy master, not kivy 1.9.0 when compiling (1.9.0 is the default in the recipe). Enjoy!

@kmonson
Copy link

kmonson commented Jul 14, 2015

Huzzah!

Thanks tito!

@rnixx
Copy link
Member Author

rnixx commented Jul 14, 2015

Thanks!

@kmonson
Copy link

kmonson commented Jul 14, 2015

I think you've got a bad copy paste:

  •    elif event.type == SDL_APP_WILLENTERBACKGROUND:
    
  •        return ('app_willenterbackground', )
    
  •    elif event.type == SDL_APP_DIDENTERBACKGROUND:
    
  •        return ('app_didenterbackground', )
    
  •    elif event.type == SDL_APP_WILLENTERFOREGROUND:
    
  •        return ('app_willenterforeground', )
    
  •    elif event.type == SDL_APP_DIDENTERBACKGROUND:
    
  •        return ('app_didenterbackground', )
    

SDL_APP_DIDENTERBACKGROUND is repeated twice and SDL_APP_DIDENTERFOREGROUND is missing I think.

@kmonson
Copy link

kmonson commented Jul 14, 2015

The return statement needs to be fixed as well for the same reason.

@tito
Copy link
Member

tito commented Jul 14, 2015

Fixed, thanks for your eyes ^^

@rnixx
Copy link
Member Author

rnixx commented Jul 15, 2015

Unfortunately the behavior is still not correct on iOS (tested on ipad mini with ios 8.3)

  • When pressing the home button, on_pause and on_resume work as expected.
  • When pressing device lock, the device goes to sleep immediately and nothing is called.
  • When unlocking the device on_pause is called instead of on_resume.

Update:

  • On iOS 6 emulator it seems to work.
  • On iOS 6 physical device the behavior is wrong as well
  • On iPad 2 emulator it also works

@kmonson can you confirm this? or anybody else?

@rnixx
Copy link
Member Author

rnixx commented Jul 15, 2015

For me this looks like a timing problem and the app not receives the event before going into sleep or similar. pause event on emulator happens somewhat deferred. Also https://github.com/kivy/kivy/blob/master/kivy/core/window/window_sdl2.py#L542 might be related to the whole story

@rnixx
Copy link
Member Author

rnixx commented Jul 15, 2015

can someone reopen this please?

@rnixx
Copy link
Member Author

rnixx commented Jul 15, 2015

The related SDL documentation (https://wiki.libsdl.org/SDL_EventType) says:

"These events must be handled in an event filter, since often the OS needs an immediate response and will terminate your process shortly after sending the event, and if it sits in the SDL event queue, it'll be too late."

and

"You can handle everything else through a normal SDL_PollEvent() loop, but you should set up a callback with SDL_SetEventFilter() for these specific events."

grep'ing kivy for SDL_PollEvent and SDL_SetEventFilter tells me:

~/workspace/kivy/kivy$ grep -rnI 'SDL_PollEvent' .
./core/window/_window_sdl2.pyx:201:        if SDL_PollEvent(&event) == 0:
./core/window/_window_sdl2.c:3389: *         if SDL_PollEvent(&event) == 0:             # <<<<<<<<<<<<<<
./core/window/_window_sdl2.c:3393:  __pyx_t_1 = ((SDL_PollEvent((&__pyx_v_event)) == 0) != 0);
./core/window/_window_sdl2.c:3398: *         if SDL_PollEvent(&event) == 0:
./lib/sdl2.pxi:468:    cdef int SDL_PollEvent(SDL_Event * event)
~/workspace/kivy/kivy$ grep -rnI 'SDL_SetEventFilter' .
~/workspace/kivy/kivy$

Looks like the event filter callback is missing for the lifecycle events

@dessant dessant reopened this Jul 15, 2015
@tito tito self-assigned this Jul 15, 2015
@rnixx
Copy link
Member Author

rnixx commented Jul 15, 2015

That's what i found in the SDL sources https://hg.libsdl.org/SDL/file/704a0bfecf75/README-ios.txt#l58

@rnixx
Copy link
Member Author

rnixx commented Jul 15, 2015

Here i began to integrate SDL_EventFilter master...rnixx:sld2_mainloop_overhauling. Took me some time with my rudimentary cython skills, but maybe it saves you some minutes ;)

@tito tito closed this as completed in 9b026c8 Jul 16, 2015
@marystern
Copy link

Hi @tito,

I have the same problem on Android 5.1 (ie on_pause() does not get called when it should).

I've just tried this again with current master (commit 0c7cd9e)
and again with the patch from mixx above applied: in both cases this is still broken on Android.

My app is a simple one that uses the camera: it correctly calls out to the Android Camera app, but will not return due to this bug.

Here's a snippet of the logs, and I have logging in my on_pause/on_resume() methods which never get called (on_pause does return True by the way):

----
I/python  (13908): [INFO              ] [XXXXXXXX    ] === App STARTED =======================
I/python  (13908): [INFO              ] [OSC         ] using <thread> for socket
I/python  (13908): [INFO              ] [Base        ] Start application main loop
I/python  (13908): [INFO              ] [Android     ] found 17 joystick
I/python  (13908): [INFO              ] [Android     ] create joystick <0>
I/python  (13908): [INFO              ] [Android     ] discard joystick <0> cause no button
...
I/python  (13908): [INFO              ] [Android     ] create joystick <16>
I/ActivityManager(  472): START u0 {act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.google.android.GoogleCamera/com.android.camera.CaptureActivity (has clip) (has extras)} from uid 10155 on display 0
V/WindowManager(  472): addAppToken: AppWindowToken{3d8ce58c token=Token{25f1babf ActivityRecord{214aa8de u0 com.google.android.GoogleCamera/com.android.camera.CaptureActivity t45}}} to stack=1 task=45 at 1
I/python  (13908): [INFO              ] [Android     ] Must go into sleep mode, check the app
I/python  (13908): [INFO              ] [Android     ] App doesn't support pause mode, stop.
I/python  (13908): [INFO              ] [Base        ] Leaving application in progress...
I/python  (13908): [INFO              ] [XXXXXXXX    ] --- App STOPPED =======================
----

I've been struggling for a while to get the camera on Android working with Kivy (not easy), and this bug is the latest blocker..can you re-open this issue please? Thanks.

@tito
Copy link
Member

tito commented Aug 16, 2015

Please open a new issue, this one for iOS is solved. If possible, give us a snippet to reproduce it.

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

No branches or pull requests

6 participants