Hardware Safety and Thermal Runaway
Lithium-ion batteries hold extreme energy density. This physical reality makes them highly volatile. Charging too fast or getting too hot risks thermal runaway and catastrophic fire. Hardware engineers design systems to measure power flow and strictly enforce safety limits. A modern smartphone relies on two dedicated hardware chips to handle this responsibility.
The following flowchart illustrates the hardware layout of a smartphone power system. It clarifies the distinct roles of the fuel gauge and the power management chip. Notice how the gauge only measures data while the controller actually routes the power.
The flowchart highlights the separation between measuring and managing. Dedicated drivers allow the kernel to talk to these physical chips. The fuel gauge driver constantly reads values from hardware registers over the I2C bus. It reports accurate numbers like an 84 percent capacity or a 32 degree temperature. Inside the kernel, the charger driver handles safety enforcement. If the gauge reports the battery temperature exceeding 45 degrees, this driver instantly throttles the charging current.
Here is a conceptual driver snippet showing how a driver manages charge current based on temperature. It demonstrates hardware logic operating completely independently of the Android OS. Expect to see plain C code reading a sensor and configuring the power controller.
int current_temp = fuel_gauge_get_temp();
if (current_temp > 450) {
pmic_set_charge_current(500);
} else {
pmic_set_charge_current(3000);
}
This snippet reveals a crucial reality. The kernel driver handles these safety limits directly because waiting for a Java service to react is too slow. Physical safety of the device belongs strictly to the hardware layer. This raises an immediate question. How does the Android OS know about this data if the kernel manages it independently?
The Power Supply Class Abstraction
Hardware chips differ wildly across phone models. If the Android framework had to understand the specific I2C registers for every unique fuel gauge, the codebase would become unmaintainable. We need a standard way to represent battery data regardless of the underlying physical chip. The Linux kernel solves this problem with the power supply class abstraction.
The power supply class provides a unified interface in the sysfs filesystem. Kernel drivers translate their specific hardware readings into standard text files under a common directory. User space processes can then read these files to get battery health without caring which company manufactured the gauge.
You can inspect these files directly using the shell. The following commands list the registered power supplies and read the current capacity. Expect to see plain text numbers returned directly from the kernel.
adb shell ls /sys/class/power_supply/
adb shell cat /sys/class/power_supply/battery/capacity
Common Mistake: Engineers often assume these sysfs nodes force the hardware to take a new measurement. Reading the file only returns the latest data already cached by the driver.
The kernel standardizes power data into text files perfectly. Now that the data exists in the filesystem, it must find a way to the status bar. How does the user interface know when to update?
Bridging Kernel Data to the UI
User space cannot constantly poll the kernel for battery updates. Continuous polling prevents the processor from entering deep sleep and drains the battery rapidly. The system requires an event-driven mechanism to read the sysfs nodes only when the physical state changes. Android uses the native Health HAL and a Java service called BatteryService to bridge this gap.
When the fuel gauge driver registers a significant change, the kernel triggers a uevent. The Health HAL listens for these events and reads the updated sysfs nodes immediately. This hardware abstraction layer then passes the standardized data up to BatteryService. Finally, BatteryService broadcasts an intent called ACTION_BATTERY_CHANGED to the rest of the operating system. System UI receives this broadcast and redraws the battery icon.
The following sequence diagram shows this exact flow of battery data from the kernel driver up to the UI. It visualizes the boundary where hardware polling becomes an OS event broadcast. Notice how the Health HAL acts as the translator between raw sysfs nodes and the Java framework.
The entire path from physical voltage to a drawn icon relies on clear boundaries. Hardware components monitor the physical chemistry. The kernel normalizes that data into standard sysfs files. Native HALs translate kernel events into Java callbacks. BatteryService ultimately notifies the rest of the system.
This event-driven model keeps the system efficient while awake. But what happens when the screen turns off and Android tries to conserve power? That introduces an entirely new set of power management rules.