Android has a tool called ‘Battery’ in the Settings app which shows an estimate of the battery usage of the most power-consuming apps on the device. This allows an end user to look at this page to quickly identify which applications are having the largest impact on their phone’s battery life. Since many phones barely last a day on a full charge, consumers have become very conscious of apps that impact the longevity of their battery.

In fact, there is even a button to uninstall the app directly from the details page, which is a scary feature for developers and PMs. You never want your users to consider deleting your app to improve their battery life. You need to do what you can to keep your app off this screen. How does Android calculate this number?


Source: My Phone

Delving into the Android code

Thanks to the open-source Android project, we can take a peek at the public-facing tool to see what goes into the application battery consumption calculation.

An app’s consumption depends on the hardware resources it uses, how long it uses them for, how often they’re used, and how hard they’re pushed. Most hardware components in a smartphone don’t just sit there consuming power – modern chipsets have very advanced power management technologies that put hardware resources into low power states when not in use.

Much of the calculation boils down to <How long did you use it for> * <Hardware power consumption per unit of time> to approximate a specific app’s battery usage (measured in mAh). We can look at the Android source code to get the exact formulas for all of the hardware resources that go into the formula.

Total_Power_Consumed (mAh) = Bluetooth_mAh + WiFi_mAh + GPS_mAh + CPU_mAh + Sensors_mAh + Modem_mAh+ Wakelock_mAh + Camera_mAh + Flashlight_mAh

Source: https://github.com/android/platform_frameworks_base/blob/master/core/java/com/android/internal/os/BatterySipper.java#L169

Formula Component Breakdown

Here is a breakdown of the nine components that go into the overall application battery consumption totals. You can look at the source code by following the link to the Git repository and searching for the variable names listed below. We have included the root formula source code that is responsible for the mAh consumption calculation for each of these components.

mobileRadioPowerMah

What it represents: Mobile Radio (aka Modem)

Source: MobileRadioPowerCalculator.java

// We are tracking when the radio is up, so can use the active time to determine power use.
app.mobileRadioPowerMah = (app.mobileActive * mPowerRadioOn) / (1000*60*60);

// We are not tracking when the radio is up, so must approximate power use
// based on the number of packets.
app.mobileRadioPowerMah = (app.mobileRxPackets + app.mobileTxPackets)
             * app.getMobilePowerPerPacket(rawRealtimeUs, statsType);

usagePowerMah

What it represents: Bluetooth

Source: BluetoothPowerCalculator.java

app.powerMah = ((idleTimeMs * mIdleMa) + (rxTimeMs * mRxMa) + (txTimeMs * mTxMa))  / (1000*60*60);

wifiPowerMah

What it represents: Wifi

Source: WifiPowerCalculator.java

app.powerDrainMah = ((idleTimeMs * mIdleCurrentMa) + (txTimeMs * mTxCurrentMa) + (rxTimeMs * mRxCurrentMa)) / (1000*60*60);

gpsPowerMah

What it represents: GPS

Source: SensorPowerCalculator.java

app.gpsPowerMah = (app.gpsTimeMs * mGpsPowerOn) / (1000*60*60);

sensorPowerMah

What it represents: Sensors

Source: SensorPowerCalculator.java

foreach (sensor)
     app.sensorPowerMah += (sensorTime * s.getPower()) / (1000*60*60);

wakeLockPowerMah

What it represents: Wakelock

“Wakelock” is a mechanism of power management service in Android OS, which can be used to keep CPU awake (Partial wakelock) and keep the screen on (Full wakelock). [source]

Source: WakelockPowerCalculator.java

// Only care about partial wake locks since full wake locks are canceled when the user turns the screen off.
app.wakeLockPowerMah = (app.wakeLockTimeMs * mPowerWakelock) / (1000*60*60);

cameraPowerMah

What it represents: Camera

Source: CameraPowerCalculator.java

app.cameraPowerMah = (totalTime * mCameraPowerOnAvg) / (1000*60*60);

flashlightPowerMah

What it represents: Flashlight

Source: FlashlightPowerCalculator.java

app.flashlightPowerMah = (totalTime * mFlashlightPowerOnAvg) / (1000*60*60);

cpuPowerMah

What it represents: CPU

Source: CpuPowerCalculator.java

While most of these elements are fairly straightforward, power consumption by the CPU is a little bit more complex.

All modern chipsets support dynamic voltage and frequency scaling in the CPU. This allows the hardware to be throttled while not in use and powered to full in short bursts while in demand by the operating system or applications. Running the CPU at full power would drain a battery extremely quickly so this kind of technology is indispensable to enable modern smartphones to run apps and still last a day on a single charge. The different performance levels the chip can operate at can be called ‘speed steps,’ which is just an abstract term for the varying frequency and voltage levels that the cores within the cluster can operate at.


Source: arm.com

Modern smartphone CPUs are no longer ‘simple’ single-core designs. The ARM big.LITTLE concept, which has been at the forefront of many high and mid-range Android smartphone chipsets for the past year or two, allows for multiple ‘clusters’ of CPU cores. Each cluster can consist of two or more identical cores, and sit alongside other clusters made up of completely different cores. Instead of a simple single or multi-core processor, you now have multiple clusters of ARM cores at the heart of the chipset.

Typically, a smartphone chip will have a high power cluster, used for CPU intensive tasks like gaming, and a low-power cluster, which use capable but relatively power-sipping CPU cores for less intensive tasks. The clusters are connected together using ultra-fast cache interconnects and can be turned on and off as the workload changes (source).

All of this is taken into consideration while calculating CPU power usage. The algorithm first checks how long the app spent using each CPU cluster at every speed step and aggregates the total overall time. For each cluster, it will then check the amount of time spent at each speed step. It then builds a ratio of time spent at each step over the total overall time. Once it has the ratios, it then takes into account the average power consumption rate at each step and produces a total approximation of the mAh consumed. To summarize, more cores, higher frequencies, and longer usage has a direct impact on your app’s battery consumption.

Wrapping Up

By understanding what goes into the battery consumption calculation, you can fine-tune your app to make sure it stays out of the list in the Android Battery app. In our next post in this series, we’ll show just how critical battery consumption is to the average smartphone user and how your apps performance can affect not only user retention but also ratings and downloads.