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. APowerEntity
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 specifiedPowerEntity
.
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 inpower_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.
Use 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.
Choose 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);