[OnePlus 2 Android Development] sewer56lol:
A Short, Quickly Written Memento About Battery Life

Yes, my definition of short and quickly is different - feel free to read it, it may help you.

I think that nowadays as things are in the modern world with the way that many apps, tools, ROMs and Kernels use lots of buzzwords such as "Battery|Stable|Optimized", people do come to forget why does our battery deplete to say the least.

In all honesty, from the words of someone (i.e. myself) who builds ROMs, there is not much that the ROM can do to optimize the user's battery life that would bear any significant impact on it - unless you pull off some very drastic methods, such as Doze in Marshmallow, something very complex not to necessarily produce by the minds of many but to create the idea, thinking creative and seeing where it could be saved. Doze is brilliant - force everything to sleep on system level if the phone is not physically moving and with screen off apart from the 'important' applications in a whitelist, it's essentially a huge wakelock block and control when your phone is 'truly idle'.

How greatly your battery is depleted so to speak is dependent on the user much more and how he decides to run what he has rather than the ROM itself.

What I'll give now is not a 100% accurate what 100% really happens account but a representation, a simplified parable of sorts that should help people understand things better

Let's say we have a normal casual user who does not control his wakelocks for instance, does not use doze, run amplify, power nap etc. He is your usual device owner, a family relative you have perhaps. He has his google account registered and his entire GApps synced. He also has Facebook running. He leaves his phone idle with WiFi/3G/LTE on, every 10 minutes (for example) Google Services will sync and Facebook will sync every 5 minutes. When his screen is off his processor will wake up from the extremely efficient deep sleep state to typically the lowest frequency available (depends on governor/load) in order to sync up with the accounts as required and go back to sleep. He's mostly okay, sadly he didn't control the frequency of syncing but his system was not that heavy anyway so the impact was not that large. It's very important to note that for Google Services every item you sync is a wakelock, so sync contacts is one, gmail is another, people details another etc.

Alright, now a simillar scenario - here we have a user loaded with apps however, a bunch of social media synced accounts, Instagram, Twitter, Facebook (I swear the official apps are literally the worst when it comes to wakelocks), syncing at different intervals and multiple Google Accounts syncing with full GApps as well as those 'Casual' games with push notifications etc.. Alright, assume the device starts wakes up on GApps wakelocks first, because of so many accounts the CPU time allocated to syncing up the accounts via Google Services is longer, more out of deep sleep - before you know it Facebook starts to sync on it's own wakelock, then Instagram, your odd apps and the GApps again... So what happens here? The device pretty much never goes to the very efficient deep sleep but is always working, even though it is very lightly, what you get is battery drain during 'idle' moments.

The third scenario is another user has a badly written, rogue app - so the device is idle, the app requests its wakelock and the device is out of sleep, the app completes what it wants to do but because it is badly written it never reports back properly or acknowledges it, the CPU is kept on outside of deep sleep because of this. What happens? Device constantly awake and battery drain.

________________________________

Now let's take a look at battery usage from another perspective, hotplugging and frequency scaling as well as governors.

Alright, so from another perspective - the way we run our kernels and the way we configure them affects our phones. I'll use two kernels for comparison for instance in their stock-like configurations. Let's say we have for instance Boeffla Kernel and we have Despair/CyanogenMod Kernel as they come 'out of the box'.

First I'll give my own definiton of 'hotplugging'.

"Hotplugging is the feature to turn unused CPU cores off during periods of low CPU utilization."

So for instance Boeffla kernel is very aggressive on commiting to hotplugging compared to CM/Despair kernel out of the box. And now for example we have a variable constantly switching low to moderate workload. Out of the box, Boeffla will likely switch off the A57 (big) cores when carrying out regular tasks and only switch them on when they are "REALLY" needed, Despair/CM will keep either some of them off or keep them all on on the lowest frequency.

So what are the implications of this? Boeffla will save battery here compared to CM/Despair, but if all of a sudden a larger load comes then Boeffla will have to switch on the cores, leading to a potential microstutter that moment as the 'switch on' is not instant and the load may be too big for the A53 cores. Despair/CM will give a smoother, more responsive experience but less battery, for Boeffla it's the vice versa out of the box with how it handles the loads regarding hotplugging. Well... what do we have here? Compromises that have to be made, with the amount of power multiple kernel devs give and the sheer amount of configurations and tweaks you can make out of a single kernel it's on the user to decide which way they want to tip the scales really.

Now on the other hand we have governors and how you tweak them. For those who don't know a CPU governor in Android controls how the CPU raises and lowers its frequency/Hz in response to the demands the user is placing on their device.

So alright, the user has a few to select from, he can either choose a passive governor or a more active, high scaling governor. Let's say we use the classic 'battery killer' performance governor that locks the CPU at max frequency, and while at it we turn off all thermal limits - then we create the next GTX 480 that kills your battery as fast as can be killed or someone who picks the classic powersave governor which keeps it at the lowest frequency.

Now, we have many and many governors out there, many governors which are tweaks of other governors and... how do we decide how the frequency should be scaled to ensure smoothness at different loads? How do we keep the CPU at the lowest possible frequency that is still sufficient to keep things smooth at a certain load? Certain apps will be smooth at different frequencies even if they endure the same loads - do you see what it comes to being here? The governor choice is also the user's choice primarily unless they choose to run the default governor. How they want the CPU utilized based on loads.

So where does my ROM/the ROM I run fit into this?

Well, the battery difference a ROM itself would make is there, it is present but it is also equally well negligible compared to what the user can do. For ROMs of closed source firmware we can try to modify them for higher efficiency, but we can't do magic - we can't (properly) rewrite the code. We can preoptimize the already cooked apps e.g. Zipalign and include scripts (such as the script by Slaid480 OxySlim has which zipaligns new non zipaligned apps on boot) and mods which change the default settings the ROM runs on. We can't do much. I repeat. Compared to the user we can't do much. Now for instance I am running TruePNG on all extracted system apps in batch - that will compress them more efficiently (but not more complex) making them faster to load on the device, the difference will be not visible to the user, it will be so low it will be pretty much negligible, a few more MBs free in memory and unnoticeably faster loads. You can also have tweaks like scrolling cache, then comes the tradeoff on whether it's even necessary on the device or whether the memory is not better used for the apps etc.

Alright, now where the ROM sits. For instance I removed the OnePlus Logging services from the ROM to negligibly improve performance and slimsize the ROM, the performance impact of the app as mentioned is negligible and it doesn't impact deep sleep, but say the user uses his phone normally scrolls around etc. and the app is working, if the app is removed then the overall load will be negligibly lower, that may cause the kernel's governor in the very rare occasion to scale just one frequency lower for the time, it is a bettery saving. These occasions will happen very rarely, after all that app was probably 0.05-0.2% of usage in that scenario of just scrolling around in the system. Yes, it does translate into improved battery life, but in a very, very minor fashion - not as the huge far as people take it for.

For over 98% of your battery it's not up to the ROM to decide how fast it depletes but the user, kernel, the apps etc. This is what YOU have control over, not the ROM.

Android ROMs are more like Linux distros, one distro does not make your PC magically faster, it just gives you a different base to run all you want on, from your apps, programs to the way you theme things. It's a shame Android isn't as modular as Unixlike systems, for instance a unified kernel.

OxySlim is like the Openbox window manager compared to LXDE which is a broader desktop environment using this window manager. OxySlim is like trying to strip what makes LXDE, LXDE and make it more like Openbox itself, make OxygenOS more close to barebones AOSP while keeping OxygenOS functionality and implementing nice stuff.

So please... Don't say that X ROM improved my battery performance by 30%, or Y ROM made it deplete by twice as fast. That one ROM is completely terrible on battery and the other isn't.

Of course, if you clean flash and you have a constant wakelock keeping your phone 100% of time awake having not touched the ROM at all and not entering Deep Sleep for instance then go tell the dev something in his ROM is broken, that is pretty rare though.

THIS IS MOST OF WHAT BATTERY LIFE ON ANDROID IS ABOUT,

A ROM DOESN'T MAGICALLY IMPROVE YOUR BATTERY BY HORDES, UNLESS SOMETHING WAS INITIALLY BROKEN

(like Snapdragon 810 power management *cough*).

I hope this helps.

- Sewer

Edit

To sum this up in other words. Battery is all about tradeoffs and compromises, you may choose to run your device very passively and get long battery life or go more aggressive and get really fast, snappy performance.

Currently as I have my device configured I'd get around 6-6.5hrs SOT on (IMO) moderate loads (well except when I go on rounds 120+ on impoppable) over 2 days such as playing BTD5 on my phones. I keep my sync wakelocks delayed to run every hour 20 mins.

What I run on my phone is the sweet spot on apparent performance (snappyness and responsiveness) for myself and my preferences however for you it may be different.

I can go more lenient and I have before, I have on different settings hit over 7.5h SOT on browsing the web, Reddit, Tapatalk and some moderate gaming with highly delayed wakelocks (I kept my sync operations delayed via Amplify to sync every 2 hours) and a stuttery-ish system (doesn't stutter but not perfectly smooth).

If I were to go nuts and try to absolutely max out battery with a micro-stuttery system, a very passive governor and hugely, in hours delayed all wakeloks I could probably get just over 9h on light-moderate loads.
​