[BetterBatteryStats] chamonix:
Some thoughts on wakelocks and wakeups

I have been reading a lot about revoking apps the permission to hold wakelocks or to get rid of those lately so I thought it's time to tune in.

First you should know that if you feel that this is too much details for you to know, you do not understand what I am taking about or not interested in going to that level of detail you should also not use any tool that changes permissions or impacts wakelocks or alarms in any way: not knowing what you do or not understanding the implications will harm your phone, potentially render it unstable and probably drain more battery than saving any.

I will start with the basics and then go on with descibing how those mechanisms play together and finally what could happen when you change one of those behaviors.

Basic terms

Alarms

Alarms is a mechanism for an app to get called asynchronously at a certain point in time. There are different types of alarms that will either only trigger if the phone is already awake of cause a wakeup. There are also different precisions depending on whether you need a great precision or if you let android decide on the time so that it can potentially bundle multiple alarm triggers into one single wakeup.

Wakeups

A wakeups is caused by an alarm of the type RTC_WAKEUP. A sign of a poorly designed app would be to use the wrong type of alarm (wakeup) to do stuff that is only relevant when the screen is on (e.g. refreshing a widget).

Wakelock

There are two kinds of wakelocks: kernel wakelocks and partial wakelocks. Partial wakelocks are specific to android where kernel wakelocks are unspecific and part of any linux kernel. Partial wakelocks are internally implemented by holding a kernel wakelock.

In android you need partial wakelocks when there is a piece of code (a block, a thread) that shall not be interrupted by the phone going to sleep. Examles for the kind of sequence that shall not be interrupted are either blocks that are implemented in such a way that they guarantee consistency by running through or blocks that use expensive resources like data and that you want to finish.

How they play together

Examples of partial wakelocks

Let's start with a example from BBS (yes BBS holds wakelocks). On certain events (boot, unplug, screen off/on) BBS saves so called references: a reference is a full description of the full relevant state of your phone at a point in time. References can then be compared to get a picture of what happened between two references.

In order to make sure that a reference is consistent it is critical that the process of saving does not get interrupted. While you are using the phone that will not be the case anyway (as the screen being on and you using it is also holding a wakelock) but think about that has to happen when your phone is off and you unplug it from the charger: the phone may get to sleep before that critical sequence is finished, causing an inconsistency: that is where a wakelocks comes in handy.

Another example would be if you are downloading something (e.g. from google play) and your screen times out. If your download has been started while you were using your phone you want it to finish before your phone goes to sleep. Not holding a wakelock while downloading may cause the download to get interrupted, the file to get truncated any you have used battery for nothing and will need to start all over again.

Examples of wakeups

When an app needs to do something at a certain time (e.g. polling) it will use an RTC_WAKEUP to trigger the sequence that may, e.g. open a connection and retrieve some data. As the wakeups may be triggered while the phone is asleep and the screen staying off it will not take long for your phone to get back to sleep, possibly before the connecting and polling was finished. To avoid that a wakelock need to be held until the connection and the follwoing action were finished.

What may happen

Revoking the permission to hold wakelocks or preventing an app to do so is the worst that you can do: you will end up with a higher drain due to connections being established and data transfers being started before the phone goes back to sleep and voids the result.

Even worse: consider the following sequence that would happen at a wakeup:

Phone wakes up (RTC_WAKEUP)

Hold wakelock

Connect

Do transfer

Program next alarm

Release wakelock

Guess what happens if you prevent the app to hold a wakelok and let's way the sequence get interrupted in the middle of the transfer?

So we are doomed?

No we are not. Finding wakelocks (especially long runners and frequent occurences) as well as frequent wakeups are signs that something is not right. Knwoing this there are different things we can do about it:

Decide to drop the app as the cost is too high for the benefit

Try to change the symptoms by changing the app's settings

Use tools to prevent certain wakeups if we are not interested in getting updates while the phone is off (Facebook would be one of those)

Contact the dev and help him solve unwanted effects

What you should never ever do is try suppressing the symptoms instead of removing the cause (that is in fact what you do when you prevent an app to hold wakelocks and this is a very very very bad idea).