Power Stats HAL

Device subsystem power is often measured and recorded in a lab environment for various steady-state conditions, such as when the screen is on, or the device is in an idle power state. This works for subsystems with a constant power draw, or under conditions that are easily measured in lab environments, but not for certain use cases, such as when a screen displays a video.

IPower.hal 1.0 provides an interface for passing power hints and reporting cumulative data on subsystem sleep-state metrics. In Android 10 and higher, the cumulative statistics-reporting function resides in the IPowerStats.hal power-stat collection APIs, and provides a way to retrieve on-device energy-usage data. This replaces the cumulative stats-gathering portion of the IPower.hal interface, for a clearer separation of functionality.

The IPowerStats service readings aren’t periodic. They occur at key moments, such as when there's a 1% battery drop. Readings are less frequent when the battery drain is low, and more frequent when it’s high. Data may be sent back to servers, and may be used in bug reports for analysis and triage. This supports ongoing efforts to decrease power consumption and increase battery life.

IPower.hal and IPowerStats.hal

Both the IPower.hal and IPowerStats.hal interfaces are available on Android 10, but the IPower.hal stats collection functionality is only available from the IPowerStats.hal interface. The IPowerStats.hal functionality includes APIs to acquire and use data collected from on-device power measurements for supported devices:

  • Performs rail-level energy measurements for both low frequency (getRailInfo) and high-frequency (streamEnergyData) clients, and reports accumulated energy since boot.
  • Reports information related to each supported PowerEntity for which data is available. A PowerEntity is a platform subsystem, peripheral, or power domain that impacts total device-power consumption.
  • Reports the set of power entity states (getPowerEntityStateInfo) for which the specified entities provide residency data, then reports the accumulated data for each specified PowerEntity.

The IPowerStats.hal APIs are used by the following clients:

  • Statsd, to collect per-rail power consumption metrics.
  • Perfetto, to correlate power consumption with CPU activity.
  • Batterystats, to improve battery attribution by using measured data rather than estimating the battery consumption from predefined constants in power_profile.xml.

With Android 10 and higher, a device manufacturer may choose between the IPower.hal and the IPowerStats.hal functions, but all clients must fall back to IPower.hal if IPowerStats.hal isn’t implemented .

IPowerStats.hal implementation options

Only the IPower.hal functions are available on Android 7 through Android 9. Devices that have been upgraded to Android 10 must have a hardware power-monitoring subsystem, or other means available to monitor and record power statistics. Some SoCs gather power-usage statistics for you, or you may obtain power-entity state residency information through software. Power-monitoring hardware is only necessary to support getRailInfo(), getEnergyData(), and streamEnergyData().

If you implement IPowerStats.hal without power-monitoring hardware, getRailInfo(), getEnergyData(), and streamEnergyData() return NOT_SUPPORTED. Similarly, getPowerEntityInfo(), getPowerEntityStateInfo(), and getPowerEntityStateResidencyData()may also return NOT_SUPPORTED if it isn’t intended to be used.

Examples of data returned by the rail-monitoring APIs include

  • The power rail for the display consumed X µW.
  • The power rail for the modem consumed Y µW.

Examples of data returned by the subsystem sleep-state APIs include

  • The modem was asleep for X ms.
  • The SoC was in the power-collapse state for Y ms.
  • The GPU was in the suspend state for Z ms.

Using a hardware power-monitoring subsystem

If your device design has a hardware power-monitoring subsystem, implement IPowerStats.hal by creating a single sysfs node from which PowerStats.hal can parse data, or by making a collection of ioctl-type system calls.

You must implement your kernel driver in a way that prevents accumulator overflow. The algorithm used depends on your unique hardware power-monitoring subsystem design, which must provide both instantaneous and average bus voltage and current measurements. The kernel driver must capture this data in a manner that doesn’t clear the energy accumulators, and it must maintain the accumulated energy data for each subrail since boot, in the form of a 64-bit variable that gets incremented with the energy reading from each accumulator query.

Stats for a given component (or optionally, multiple components) must be in a single node. While this isn’t a conventional use of sysfs (which normally limits each node to a single value), it ensures all data is consistent.

Design guidance

  • Keep latency low (1 msec, maximum) when reading from the sysfs node or making system calls.
  • Ensure that supporting stats functionality doesn’t measurably increase the power drain:
    • Don't increase access point (AP) and/or subsystem wakeups to track parameters such as the time spent in sleep mode.
    • Transfer stats between the apps processor and firmware opportunistically with other traffic when possible.
  • If necessary, the subsystem may use the following driver functions:
    • Internally caching data to avoid latency/wakeups at the expense of slightly stale data.
    • Performing extrapolation when the subsystem is asleep, to provide updated sleep-time without waking the subsystem.

Choosing components, subsystems, and stats

When choosing which components or subsystems from which to gather IPowerStats.hal data, select anything on the device that consumes significant current (5 mA or more), or that supports multiple power-consumption modes, such as the following:

  • Individual SoC subsystems.
  • Subsystems partially or completely outside of the SoC, such as WiFi, the image processor, or the security processor.
  • Peripherals such as high-power LEDs and cameras.
  • Power domains that use different modes (such as the power domain for the SoC as a whole).

Customization

This optional feature is amenable to customization. Design use cases and customize your use:

  • Decide which rails to measure, and how frequently to measure them.
  • Decide when to read the data, and how to interpret it.
  • Decide what action to take and when to take it, based on your data.

Validation

VTS tests ensure Android requirements are met. The comments in IPowerStats.hal are used for verifying that a device is in compliance.

For example, if you call getRailInfo() and it returns nothing, the VTS test fails, because you didn't receive information about the monitored rails, or a returned status of SUCCESS. Similarly, if you received rail info, but it was accompanied by a NON_SUPPORTED or FILE_SYSTEM_ERROR response, that’s also a failure. The VTS verifies the device manufacturer specification is adhered to in the HAL file, using the requirements in the IPower.hal and IPowerStats.hal comments. An example of comments used in VTS testing is shown below:

/**
* Rail information:
* Reports information related to the rails being monitored.
*
* @return rails Information about monitored rails.
* @return status SUCCESS on success or NOT_SUPPORTED if
* feature is not enabled or FILESYSTEM_ERROR on filesystem nodes
* access error.
*/
getRailInfo()
generates(vec<e;RailInfo>e; rails, Status status);