11

This is apparently semi-documented behavior, if comments from Dianne Hackborn on a G+ post constitute "documented": https://plus.google.com/+AndroidDevelopers/posts/94jCkmG4jff but foreground services associated with a notification icon should be allowed to keep a wake lock during doze mode.

It seems this is not valid when you have a top-activity in addition to the foreground service.

I have create a minimal implementation which demonstrates this: https://github.com/petrnalevka/dozetest/blob/master/src/com/urbandroid/doze/DozeService.java

The problem can be reproduced on
Android M, MRA58K Nexus 5 and MRA58N Nexus 6

My foreground service has an associated notification and I hold a partial wake lock. Unfortunately Doze mode takes over and my wake lock is broken. I was only able to prevent this by an opt-out from battery optimization or leaving the top activity.

I believe this is a bug in Android as there is no reason why foreground services should keep the wake lock but not if they have an activity on top.

I'm putting this issue on SO even I have already reported this on Androdi issue tracker here https://code.google.com/p/android/issues/detail?id=193802 in order to find workarounds as this is a crutial feature in order to not need the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS which apparently only mean REQUEST_REMOVAL_FROM_PLAYSTORE_BY_GOOGLE at the moment.

Here is how I was able to reproduce the issue using adb thanks to hints from +Dianne Hackborn:

It seems that when I keep an Activity in the foreground while having also the foreground service running my app is recognized by the Power manager as:

PARTIAL_WAKE_LOCK              'Doze lock' DISABLED (uid=10112, pid=24649, ws=null)  
Proc # 0: fore  F/A/TS trm: 0 24649:com.urbandroid.doze/u0a112 (top-activity)  

If I press home and leave the activity I get into the state:

PARTIAL_WAKE_LOCK              'Doze lock' (uid=10112, pid=24649, ws=null)  
Proc # 4: prcp  F/S/SF trm: 0 24649:com.urbandroid.doze/u0a112 (fg-service)  
Petr Nalevka
  • 1,579
  • 1
  • 10
  • 18
  • Since you have a service running, there may be some broadcasts you can monitor to determine when the screen is going off, in which case you can use `startActivity()` to bring up the home screen (i.e., move yourself to the background). I don't know if `ACTION_SCREEN_OFF` is the right broadcast to listen to or not. – CommonsWare Nov 14 '15 at 14:39
  • Many thanks I was thinking a similar direction. Home screen is a good candidate with the standard intent to bring it up. Will test this and report back – Petr Nalevka Nov 14 '15 at 19:17
  • I tried to call an intent for the home screen onScreenOff and intent to bring my activity back onScreenOn and based on adb tests it seems to be working well. Surprisingly it does not look too odd on Nexus 5, the launcher just blinks in quickly when screen is put ON. I will do real doze mode tests now as they will require few hours..I'm just affraid whether this will be reliable enough in practice. – Petr Nalevka Nov 14 '15 at 19:45
  • More findings on this. I'm still unable to do reliable workarounds for the issue and in the process I found out that even BroadcastReceiver.onReceive() can break the lock even a foreground service is running. This makes any workarounds for the issue quite challenging. I will check if also non-foreground services suffer this issue. Unfortunately this issue hasn't been fixed in the 6.0.1 update and I afraid it won't get fixed any time soon as my reporte on the Android bug tracker still did not even get an owner: https://code.google.com/p/android/issues/detail?id=193802 – Petr Nalevka Dec 14 '15 at 10:59
  • @PetrNalevka "my app is recognized by the Power manager as" How do you check that state ? any links on furtrher info on that as I need to test my app status as well.. – Ahmed Sep 16 '16 at 05:48

1 Answers1

10

This is an answer by Dianne Hackborn posted under https://plus.google.com/+AndroidDevelopers/posts/94jCkmG4jff. Still we can brainstorm more workarounds here as separating the processes may not always be straightforward.

Dianne Hackborn: +Petr Nalevka Sorry yes this does seem like a bug in the platform. I will look into getting it fixed when possible.

Your work-around is in the right direction, but please don't do that kind of thing with moving your state in screen on/off. Well, it is okay to move to the back and do that when the screen turns off... however, it is very wrong to force yourself to the front when the screen turns on, because it could be turning on for other reasons (to launch camera, voice interaction, etc). This is actually probably something the platform should be better at protecting itself against.

What I would suggest is listening for doze mode to start, and just putting your activity to the back in that case. You can do that by listening for the broadcast http://developer.android.com/reference/android/os/PowerManager.html#ACTION_DEVICE_IDLE_MODE_CHANGED and sending yourself to the back when you see that device idle is true. I would suggest just not worrying about trying to get yourself back to the foreground -- in the case where the user actually hasn't been using their device for a long time and this happens, coming back to it and being in home shouldn't be a surprise.

EDIT (by Dianne Hackborn): Actually, another solution -- have your foreground service run in a different process than the activity. From what I can see, this will work fine. I would be interesting in seeing if you get the desired behavior there.

Also this is actually our recommended practice for this situation -- if you have a long-running foreground service, it should be in a separate process from the activity, so it doesn't force all of the memory associated with the activity to be kept around. (This is also why this bug got through, all of our apps use this pattern.)

Petr Nalevka
  • 1,579
  • 1
  • 10
  • 18
  • Does foreground service in separate process prevent both Doze and App Standby, because in my case when have foreground service in other process and call "adb shell dumpsys deviceidle force-idle" my partialWakeLock and WifiLock got released. – Domen Jakofčič Jan 16 '17 at 21:02