Clone wiki

YAAB / How it works

Well, there are several 3rd party apps for controlling screen brightness available in Play store. They all use the same technic of changing actual brightness of the screen, maybe with minor differences. Therefore they all, including YAAB, have the same shortcomings.

There are two official ways of changing current brightness of the screen:

  1. launch activity and set WindowManager.LayoutParams.screenBrightness value for the root view
  2. add a view to the screen with LayoutParams.TYPE_SYSTEM_OVERLAY flag set, update its layout with correct brightness value when needed

First way in our case would require starting an activity each time we want to adjust current brightness. Activity would be transparent so user not to get annoyed. Anyway, it would be activity, so current foreground activity would get paused and then resumed. So, if the user is typing a message in email client at the moment, he'd see "draft saved" toast just without any obvious reason. Other apps can react in their own different way. Who want this on their devices? Guess no one.

Second way is a bit better, nothing blinks since the view is present on the screen all the time, activities do not get paused occasionally. But is this case the application must be granted SYSTEM_ALERT_WINDOW permission. And once the view closed the system brings back previous brightness level. We'll get back to this notice later.

So, how auto brightness applications are implemented. They all have some kind of settings activity that is interacting with the user displaying preferences and accepting commands. And they have a background service which is listening to the light sensor changes. When the service notices some updates of the ambient light it decides what to do: update current brightness, save it for future, run a timer to schedule delayed update, etc. It depends on the developer. YAAB starts timer in this case. In next few seconds it will actively gather updates, calculate average value and compare it to corresponding current screen brightness level. If the difference is bigger than threshold the brightness will be changed. Looks pretty simple so far.

Ok, how it works in real life. A user finds the app on the market, says "wow, just what I needed to read in darkness!". He installs the app, plays with settings, and let's assume he finds himself satisfied and lefts the app running on the device. Later, maybe at night, the user decides to browse web or read a book in a dark room, and after few minutes he sees jumpy changes of brightness. What's wrong?

One thing is wrong. Web browser consumes more and more memory while the user opens more pages and Android starts killing background services to obtain more resources. In this mode services will be killed and started automatically from time to time. Once brightness app service is killed, the system removes from the screen all the views the service has created. Thus "once the view closed the system brings back previous brightness level" is so important for this kind of application. Screen blinks, user is not happy.

What else can developers do? Well, background service can promote itself to "Perceptible" state, by calling startForeground API method. It shows notification icon in the notification area and tells the system that the service is doing something the user is aware of at the moment. The system will not cycle such service, but if killing of all background services will not free enough memory - perceptible service will also get killed. And the worst part - it will not get started again. YAAB has an option whether to use perceptible state when the screen if ON or not. The user can choose what brings him less discomfort.

Ok, let's create one more background service, let it run in background and resurrect the first service if it will get killed being in perceptible state. Good idea, but another service will mean few more megabytes of memory consumed by the application.

Also there are several applications like ebook readers or games that eager to control brightness for themselves. And it is a good idea to let them do it. But it will not happen while auto brightness application is operating.

Any conclusions? Yes. Auto brightness function must not be implemented in application. It must be a part of the system which will never get killed unexpectedly. That is why all brightness control applications suck. YAAB just sucks less :)