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

Android app is running while the screen is locked, on Samsung ! #1219

Closed
SDLBugzilla opened this issue Feb 10, 2021 · 0 comments
Closed

Android app is running while the screen is locked, on Samsung ! #1219

SDLBugzilla opened this issue Feb 10, 2021 · 0 comments

Comments

@SDLBugzilla
Copy link
Collaborator

This bug report was migrated from our old Bugzilla tracker.

Reported in version: HG 2.1
Reported for operating system, platform: Android (All), ARM

Comments on the original bug report:

On 2013-11-14 17:07:29 +0000, Sylvain wrote:

Hello,

I saw this bug has been fixed :

Bug 1896 - Android app is running while the screen is locked
https://bugzilla.libsdl.org/show_bug.cgi?id=1896

It actually fixed on my HTC ONE : the apps is paused as expected while the device is locked (black screen), and also it is paused while the mobile is in the locked screen (screen if ON, but before the user has entered its drawing password).

But this seems not to be fixed on the Galaxy Samsun S4 !

While the screen is OFF, the app is paused as expected.

When the user is in the locked screen : the app is running underneath !

Cheers,

Sylvain

On 2013-11-14 19:15:53 +0000, Gabriel Jacobo wrote:

adb logcat please :)

On 2013-11-14 22:15:53 +0000, Sylvain wrote:

As usual no logcat :)

but I will try to get one ...

In the meantimes, I found some interesing stuff :

http://stackoverflow.com/questions/11731285/onresume-being-called-over-and-over-while-phone-screen-is-locked

http://developer.android.com/reference/android/app/Activity.html#onResume%28%29

Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).

On 2013-11-14 22:18:28 +0000, Sylvain wrote:

sorry I looked at the java code which seems correct as it already uses "onWindowFocusChanged".

On 2013-11-17 04:42:24 +0000, Joe LeVeque wrote:

Hey. I'm also developing a game using for Android using SDL and a T-Mobile Galaxy S4, so I thought I'd try to reproduce your bug. I downloaded your Spider Solitare apk (I found your post in the SDL forum http://forums.libsdl.org/viewtopic.php?t=9746), and I was unsuccessful at reproducing the bug. Your instructions on the forum were a bit hard to understand, but here's what I did (I think this is what you were requesting):

  • Start the app.
  • Play a card (I noticed the timer didn't start until I did this)
  • Waited for the screen to turn off - recorded the timer
  • Waited 10 seconds
  • Pressed power button - brought up lockscreen
  • Waited 10 seconds
  • Unlocked phone - recorded timer (same value as previous or 1 second ahead at most).

I tried this a few times, as well as sending your app into the background, and also pressing power to force the screen off, and not once did I notice anything that would lead me to believe the app is not pausing correctly.

As a side note, I found this bug because I have a semi-related issue. My app pauses fine in all instances, and resumes fine after being sent to the background via the Home key, however, if the app is is in the foreground and the power button is pressed (or the screen is allowed to turn off due to inactivity), upon unlocking the screen the device just hangs indefinitely - it can't restore the app, so it never leaves the lockscreen. I noticed your app does not have this issue. May I ask what you are calling to pause/unpause your app?

On 2013-11-17 08:29:07 +0000, Sylvain wrote:

Hello.

I wanted to make this mail to Jonathan privately but it goes somehow public to the mailing list :)

You are right : you have to start the timer by placing one card.

So confirmation about the way to go on/off:

  • you dont need to wait the screen to go off.
  • you dont need to put the app in background.

Pressing the hold button is enough (the on/off button).

At least this is what was reported by Samsung, and what I see on another S4.
The S4 I saw, has a "drawing password". Did you have it ? could you double check with this ? The timer was increasing while behing the "password lock" or behing.

Here's what I am using for Background/Foreground :

  • Flagging that we go to background (event SDL_WINDOW_EVENT_FOCUS_LOCUS) or to foreground (event SDL_WINDOW_EVENT_FOCUS_GAIN)
  • Then, while in background : forbid any creation/update of textures, and any call to RenderPresent.
  • Also in the Java Code : I put an "SDLActivity.mSingleton.finish()" after the call "SDLActivity.nativeInit()" so that the app exit when it ends.

On 2013-11-17 18:12:22 +0000, Joe LeVeque wrote:

On my previous test, I did not have a lockscreen password set. I assume by a "drawing" password you mean the kind where you have to trace a pattern across a grid of dots, so I set one up and tried again. As before, I could not reproduce the bug. I appears as though your game pauses/resumes properly.

One thing to note: I am running Cyanogenmod 10.2 on my phone, NOT the stock Samsung GS4 firmware. I wonder if your bug only occurs with the proprietary Samsung firmware. If this is the case, it would appear to be a bug in their firmware, not SDL, as Cyanogenmod is closer to stock Android than the Samsung crap firmware is.

So, I assume you meant you're using SDL_WINDOWEVENT_FOCUS_GAINED and SDL_WINDOWEVENT_FOCUS_LOST events to pause/resume your app. I was under the assumption we should use the SDL_APP* events (SDL_APP_WILLENTERBACKGROUND, SDL_APP_WILLENTERFOREGROUND, etc), which are what I'm using. This makes more sense to me anyway, because my app is cross-platform, and using the FOCUS_GAINED/LOST events would cause the game to pause on desktop platforms as well (which may or may not be desired behavior - undesired in my case). You may want to try keying off the SDL_APP* events and try it on a stock GS4 to see if the issue persists.

On 2013-11-17 18:24:08 +0000, Sylvain wrote:

Yes I meant SDL_WINDOWEVENT_FOCUS_GAINED and SDL_WINDOWEVENT_FOCUS_LOST.

Ok, good to know it's probably the samsung firmware. I will try to get a logcat of this issue.

On 2013-11-17 18:28:01 +0000, Sylvain wrote:

Yes, maybe I should rely on only SDL_APP_WILLENTERBACKGROUND or SDL_APP_WILLENTERFOREGROUND.

On 2013-11-29 10:39:46 +0000, Sylvain wrote:

Hello,

So this is indeed a bug in my application :)
I used to rely on SDL_WINDOWEVENT_FOCUS_GAINED to resynchronize my internal "current time".

Occasionaly, there is 10 ms between SDL_APP_WILLENTERFOREGROUND and SDL_WINDOWEVENT_FOCUS_GAINED, which is enough for my application to process the mainloop with an old time reference and then virtually try to catch up a wrong time gap.

Most of the time, this delay is < 1ms and so it were looking fine.

Otherwise I noticed on Android that SDL_APP_WILLENTERBACKGROUND and SDL_APP_DIDENTERBACKGROUND were actually recieved when the application is entering in the foreground.

(SDL_WINDOWEVENT_FOCUS_LOST is correctly recieved before application is in background)

thanks,
Sylvain

On 2013-11-29 13:07:25 +0000, Gabriel Jacobo wrote:

The order of events should be fixed here: https://hg.libsdl.org/SDL/rev/3b0346b37e0f

Thanks!

On 2013-11-29 14:25:51 +0000, Sylvain wrote:

By the way, I use the default configuration : BLOCK_ON_PAUSE.

Now WILL_ENTER_BG and DID_ENTER_BG arrives when entering to BG, so this is correct.
(Maybe the DID_ENTER_BG should never arrive ? and be posted after blocking the evenloop? but I dont use it anyway)

but foreground happens sometimes lately (here 16 ms ! with SDL_GetTicks())

V/SDL ( 6417): Window size:1920x1080
V/SDL ( 6417): onWindowFocusChanged(): true
V/SDL ( 6417): nativeResume()
E/void make_app()( 6417): SDL _is_foreground 670715
********** 400 times those lines ! ******
E/void make_app()( 6417): SDL _is_foreground 670723
I/SensorManager( 6417): protected boolean registerListenerImpl(SensorEventListener .....
E/void app()( 6417): SDL _is_foreground 670731
E/int app::pollEvent()( 6417): SDL_APP_WILLENTERFOREGROUND at t=670731
E/int app::pollEvent()( 6417): SDL_APP_DIDENTERFOREGROUND at t=670731
E/int app::pollEvent()( 6417): SDL_WINDOWEVENT_FOCUS_GAINED at t=670731

I guess FOREGROUND events should be sent before signaling the Resume Semaphore !
So they are already in the buffer of events (?) when the app can run.

thanks

On 2013-12-02 18:55:07 +0000, Sylvain wrote:

Hello,

Sorry to show up again, but I would like re-open the issue !
At least, to discuss this.

I believe the commit
https://hg.libsdl.org/SDL/rev/3b0346b37e0f introduces a new small random delay between the app been unlocked for running ("SDL_SemPost(Android_ResumeSem)"), and the event informing the app that it has been waked-up (SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND)).

Since this is a multi-thread issue, there can no delay (as before) or a big delay.

Here's an example. I believe, lots of apps use this simplified "event loop" :

while (1)
{
// process all events
while (SDL_pollevent(&event) != -1)
{
process_the_event(&event)
}

// compute, time, rendering ...
main_process();

}

Before:
We always had the following sequence :

main_process()
event SDL_APP_DIDENTERBACKGROUND
event SDL_APP_WILLENTERFOREGROUND
main_process()

Currently, because of the delay, we can also have this case :

main_process()
event SDL_APP_DIDENTERBACKGROUND
// SDL_SemPost(Android_ResumeSem)
main_process() // N times !
event SDL_APP_WILLENTERFOREGROUND
main_process()

I use the SDL_APP_WILLENTERFOREGROUND to resynchronize my application : therefore, the "main_process()" sees no time gap because of the background/foreground. So the time seems elapse continuously.

Of course, user application can handle this by remembering to be in "background" state. But I believe this is better to make this as transparent as possible to the user application.

... I just mean to replace :

(!SDL_SemValue(Android_ResumeSem) SDL_SemPost(Android_ResumeSem);
SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);

by :

SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
(!SDL_SemValue(Android_ResumeSem) SDL_SemPost(Android_ResumeSem);

Thanks,

Sylvain

On 2013-12-02 19:07:52 +0000, Gabriel Jacobo wrote:

I'm not saying the order should be as is, AFAIK we can change it without repercussions...ironically we can pretty much do this because you don't need any of the "post resume" messages actually.

You can probably achieve what you want by just waiting for SDL_APP_DIDENTERBACKGROUND. When that event comes in, you know the next SDL_PollEvent will block itself, so you just measure the time before calling SDL_PollEvent and after, you get the time the app was paused, no multithreading issues to worry about.

Or you could just take the time at the start of each frame :)

All the SDL_APP_* events are there to make things similar to the way the iOS backend works, but as you can probably notice there's lots of redundant stuff.

On 2013-12-02 20:09:29 +0000, Sylvain wrote:

I dont use frames as a time reference, because there are many devices which have low/high cpu, different timings, and I want reproductably.

I am not very familiar with the IOS port. I use it, but never read deep into it.
Though, I read that "applicationWillEnterForeground" would be called before application gets active. IMHO, I think this is not the case currently for Android port : SDL_WILLENTERFOREGROUND is sent whereas the app is already active.

Yes, I will probably patch anyway my application to make a weaker assumption on this event.

On 2013-12-03 14:43:18 +0000, Sylvain wrote:

Sorry for being picky, (maybe you'll get some usefull information) :

You can probably achieve what you want by just waiting for SDL_APP_DIDENTERBACKGROUND.
When that event comes in, you know the next SDL_PollEvent will block itself,

This is not correct. Even after SDL_APP_DIDENTERBACKGROUND, you can have a few calls to PollEvent (with no event received) before being actually blocked by the semaphore inside SDL_PollEvent.

A Solution would be to insert this event by the application thread when it gets the semaphore.
Another Solution would be to make SDL_PollEvent auto-block when just after it decodes SDL_APP_DIDENTERBACKGROUND (but difficult to unlock then).

so you just measure the time before calling SDL_PollEvent and after,
you get the time the app was paused, no multithreading issues to worry about.

Then it gets more difficult to detect the "after". (I mean to detect the first call to SDL_PollEvent when being back in foreground).
So far, I can only make it work with a "timeout".

On 2013-12-03 15:10:35 +0000, Gabriel Jacobo wrote:

Ok, you win :)

https://hg.libsdl.org/SDL/rev/a5270cef21a7

On 2013-12-03 15:16:20 +0000, Sylvain wrote:

Hey,

I dont mean to force a modification. I just bring some information and maybe spot a bug!

(I have already added some robustess on my code anyway as you suggested).

Thanks!

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

1 participant