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

Cross-platform consistency for ApplicationHandler::suspended/resumed() #3779

Open
daxpedda opened this issue Jul 8, 2024 · 5 comments
Open

Comments

@daxpedda
Copy link
Member

daxpedda commented Jul 8, 2024

Unfortunately the behavior between Android, iOS and Web doesn't match exactly, so this will require some research and figuring out exactly how we want to expose this to the user.

Web

Web currently implements this via pagehide and pageshow. Which for suspended() means the application is being navigated away from and is being stored in the B/F Cache and for resumed() means that the page has been restored.

Its important to note that between suspended() and restored() no user code can be executed and getting restored() isn't actually promised.

There is also the Page Lifecycle API, currently only implemented in Chrome, which lets us also detect if the application was frozen by the browser.

iOS

@madsmtm please feel free to work out this section and correct me.

applicationDidEnterBackground could be used to detect when iOS is telling the application to stop doing anything. This doesn't mean that any code execution will be suspended immediately but "probably soon".

This however is currently not implemented correctly and instead iOS will call ApplicationHandler::suspended() when the application is running in the background via applicationWillResignActive, which should probably be WindowEvent::Focused(false) instead.

Presumably its also guaranteed that the application will be woken up before being actually closed (?).

Android

@MarijnS95 your input would be greatly appreciated here.

Android does currently not implement ApplicationHandler::suspended/resumed()

@MarijnS95
Copy link
Member

MarijnS95 commented Jul 10, 2024

@daxpedda just in case; you want context after #3765, i.e. knowing that we moved surface lifetime away from the suspended() and resumed() events that Android was previously relying on?

From the look and sound of it you'll want onStop() and onStart() from the activity lifecycle: https://developer.android.com/guide/components/activities/activity-lifecycle

Note that there are are differences between these and onPause()/onResume().

These lifecycle events are already available in winit:

MainEvent::Start => {
// XXX: how to forward this state to applications?
warn!("TODO: forward onStart notification to application");
},
MainEvent::Resume { .. } => {
debug!("App Resumed - is running");
self.running = true;
},
MainEvent::SaveState { .. } => {
// XXX: how to forward this state to applications?
// XXX: also how do we expose state restoration to apps?
warn!("TODO: forward saveState notification to application");
},
MainEvent::Pause => {
debug!("App Paused - stopped running");
self.running = false;
},
MainEvent::Stop => {
// XXX: how to forward this state to applications?
warn!("TODO: forward onStop notification to application");
},

@daxpedda
Copy link
Member Author

From the documentation I can't seem to be able to definitely say that all code execution is halted after onStop, it seems more similar to iOS in that regard, that execution will stop "soon". Am I getting this right?

Note that there are are differences between these and onPause()/onResume().

Seems similar to iOS's applicationWillResignActive, which should be delegated to WindowEvent::Focused(false).

These lifecycle events are already available in winit: ...

Would you like to make a PR implementing those events?
I can offer actually reviewing it and testing it locally.

@MarijnS95
Copy link
Member

MarijnS95 commented Jul 10, 2024

Android doesn't have a concept of this "code stop" that other platforms seem to have. As we have a separate thread where we create our own looper, and configure how often it should wake via - for example - ControlFlow::{Poll, Wait}, the loop can keep running after both these events and producing code flow.

These lifecycle events more so tell you what is going on with the visible portion and user interaction of your app. However, I won't be surprised if Android has mechanisms in place to kill or throttle long-running app processes if no Activitys are visible for some time, and it doesn't have background "threads" that show a persistent notification of sorts. But for now you can minimize an Android app and observe that logging keeps going inside an event loop (rely on debug/verbose logging inside the android-activity crate to see this too).


Seems similar to iOS's applicationWillResignActive, which should be delegated to WindowEvent::Focused(false).

Android also has (un)focused events to make things extra complicated :/

These don't seem to be keyed off of the native surface though, confusingly.


Opened a PR at #3786 but my time is pretty much up so I'll leave documentation for some other time.

What's worse, we seem to be having some weird hypothetical self.running bool that is keyed off onResume/onSuspend while the app is still visible to block RedrawRequested etc?

@kchibisov
Copy link
Member

kchibisov commented Jul 10, 2024

If the application is simple hidden, but still running the Occluded event should be used instead, because it indicats that the window is hidden, but not paused. Resume/Suspended should really happen only if the application is not running at all.

@MarijnS95
Copy link
Member

This is where Android recommends you to save/restore state like the other platforms, though, but you're right that it seems weird.

@MarijnS95 MarijnS95 added C - needs discussion Direction must be ironed out C - nominated Nominated for discussion in the next meeting labels Aug 11, 2024
@MarijnS95 MarijnS95 removed C - needs discussion Direction must be ironed out C - nominated Nominated for discussion in the next meeting labels Aug 23, 2024
@daxpedda daxpedda added C - needs discussion Direction must be ironed out and removed C - needs discussion Direction must be ironed out labels Aug 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants