In Android 11, all healthd code is refactored into
libhealthloop and libhealth2impl, then modified to implement the health@2.1
HAL. These two libraries are linked statically by health@2.0-impl-2.1,
the passthrough implementation of Health 2.1. The statically linked libraries
enable health@2.0-impl-2.1 to do the same work as healthd, such as running
healthd_mainloop and polling. In init, the health@2.1-service registers an
implementation of the interface IHealth to hwservicemanager. When upgrading
devices with an Android 8.x or 9
vendor image and an Android 11 framework,
the vendor image might not provide the health@2.1 service. Backward
compatibility with old vendor images is enforced by the
deprecation schedule.
To ensure backwards compatibility:
healthdregistersIHealthtohwservicemanagerdespite being a system daemon.IHealthis added to the system manifest, with the instance name "backup".- The framework and
storagedcommunicate withhealthdthroughhwbinderinstead ofbinder. - The code for framework and
storagedare changed to fetch the instance "default" if available, then "backup".- C++ client code uses the logic defined in
libhealthhalutils. - Java client code uses the logic defined in
HealthServiceWrapper.
- C++ client code uses the logic defined in
- After IHealth/default is widely available and Android 8.1 vendor images are
deprecated, IHealth/backup and
healthdcan be deprecated.
Board-specific build variables for healthd
BOARD_PERIODIC_CHORES_INTERVAL_* are board-specific variables used to build
healthd. As part of the system/vendor build split, board-specific values
cannot be defined for system modules. These values used to be overridden
in the deprecated function healthd_board_init.
In health@2.1, vendors can override
these two periodic chores interval values in the healthd_config struct before
passing to the health implementation class constructor. The health
implementation class should inherit from
android::hardware::health::V2_1::implementation::Health.
Implement the Health 2.1 service
For information on implementing the Health 2.1 service, see hardware/interfaces/health/2.1/README.md.
Health clients
health@2.x has the following clients:
- charger. The use of
libbatterymonitorandhealthd_commoncode is wrapped inhealth@2.0-impl. - recovery. The linkage to
libbatterymonitoris wrapped inhealth@2.0-impl. All calls toBatteryMonitorare replaced by calls into theHealthimplementation class. BatteryManager.
BatteryManager.queryProperty(int id)was the only client ofIBatteryPropertiesRegistrar.getProperty.IBatteryPropertiesRegistrar.getPropertywas provided byhealthdand directly read/sys/class/power_supply.As a security consideration, apps aren't allowed to call into health HAL directly. In Android 9 and higher, the binder service
IBatteryPropertiesRegistraris provided byBatteryServiceinstead ofhealthd.BatteryServicedelegates the call to the health HAL to retrieve the requested information.BatteryService. In Android 9 and higher,
BatteryServiceusesHealthServiceWrapperto determine whether to use the default health service instance fromvendoror to use the backup health service instance fromhealthd.BatteryServicethen listens for health events throughIHealth.registerCallback.Storaged. In Android 9 and higher,
storageduseslibhealthhalutilsto determine whether to use the default health service instance fromvendoror to use the backup health service instance fromhealthd.storagedthen listens for health events throughIHealth.registerCallbackand retrieves storage information.
SELinux changes
The health@2.1 HAL includes the following SELinux changes in the platform:
- Adds
android.hardware.health@2.1-servicetofile_contexts.
For devices with their own implementation, some vendor SELinux changes may be necessary. Example:
# device/<manufacturer>/<device>/sepolicy/vendor/hal_health_default.te
# Add device specific permissions to hal_health_default domain, especially
# if it links to board-specific libhealthd or implements storage APIs.
Kernel interfaces
The healthd daemon and the default implementation
android.hardware.health@2.0-impl-2.1 access the following kernel interfaces to
retrieve battery information:
/sys/class/power_supply/*/capacity_level(added in Health 2.1)/sys/class/power_supply/*/capacity/sys/class/power_supply/*/charge_counter/sys/class/power_supply/*/charge_full/sys/class/power_supply/*/charge_full_design(added in Health 2.1)/sys/class/power_supply/*/current_avg/sys/class/power_supply/*/current_max/sys/class/power_supply/*/current_now/sys/class/power_supply/*/cycle_count/sys/class/power_supply/*/health/sys/class/power_supply/*/online/sys/class/power_supply/*/present/sys/class/power_supply/*/status/sys/class/power_supply/*/technology/sys/class/power_supply/*/temp/sys/class/power_supply/*/time_to_full_now(added in Health 2.1)/sys/class/power_supply/*/type/sys/class/power_supply/*/voltage_max/sys/class/power_supply/*/voltage_now
Any device-specific health HAL implementation that uses libbatterymonitor
accesses these kernel interfaces by default, unless overridden in the health
implementation class constructor.
If these files are missing or are inaccessible from healthd or from the
default service (for example, the file is a symlink to a vendor-specific folder
that denies access because of misconfigured SELinux policy), they might not
function correctly. So additional vendor-specific SELinux changes might be
necessary even though the default implementation is used.
Some kernel interfaces used in Health 2.1, such as
/sys/class/power_supply/*/capacity_level and
/sys/class/power_supply/*/time_to_full_now, may be optional. However, to
prevent incorrect framework behaviors resulting from missing kernel interfaces,
it is recommended to cherry-pick
CL 1398913
before building the Health HAL 2.1 service.
Testing
Android 11 includes new
VTS tests
written specifically for the health@2.1 HAL. If a device declares
health@2.1 HAL in the device manifest, it must pass the corresponding VTS tests.
Tests are written for both the default instance (to ensure that the device
implements the HAL correctly) and the backup instance (to ensure that healthd
continues to function correctly before it is removed).
Battery information requirements
The Health 2.0 HAL states a set of requirements on the HAL interface, but the corresponding VTS tests are relatively relaxed on enforcing them. In Android 11, new VTS tests are added to enforce the following requirements on devices launching with Android 11 and higher:
- The units of intataneous and average battery current must be microamps (μA).
- The sign of instantaneous and average battery current must be correct.
Specifically:
- current == 0 when battery status is
UNKNOWN - current > 0 when battery status is
CHARGING - current <= 0 when battery status is
NOT_CHARGING - current < 0 when battery status is
DISCHARGING - Not enforced when battery status is
FULL
- current == 0 when battery status is
- The battery status must be correct against whether or not a power source is
connected. Specifically:
- battery status must be one of
CHARGING,NOT_CHARGING, orFULLif and only if a power source is connected; - battery status must be
DISCHARGINGif and only if a power source is disconnected.
- battery status must be one of
If you use libbatterymonitor in your implementation and pass through values
from kernel interfaces, ensure the sysfs nodes are reporting correct values:
- Ensure the battery current is reported with the correct sign and units. This
includes the following sysfs nodes:
/sys/class/power_supply/*/current_avg/sys/class/power_supply/*/current_max/sys/class/power_supply/*/current_now- Positive values indicate incoming current into the battery.
- Values should be in microamps (μA).
- Ensure the battery voltage is reported in microvolts (μV). This includes the
following sysfs nodes:
/sys/class/power_supply/*/voltage_max/sys/class/power_supply/*/voltage_now- Note that the default HAL implementation divides
voltage_nowby 1000 and reports values in millivolts (mV). See @1.0::HealthInfo.
For details, see Linux power supply class.