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:
- healthdregisters- IHealthto- hwservicemanagerdespite 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 of- IBatteryPropertiesRegistrar.getProperty.- IBatteryPropertiesRegistrar.getPropertywas provided by- healthdand 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 by- BatteryServiceinstead of- healthd.- BatteryServicedelegates the call to the health HAL to retrieve the requested information.
- BatteryService. In Android 9 and higher, - BatteryServiceuses- HealthServiceWrapperto determine whether to use the default health service instance from- vendoror to use the backup health service instance from- healthd.- BatteryServicethen listens for health events through- IHealth.registerCallback.
- Storaged. In Android 9 and higher, - storageduses- libhealthhalutilsto determine whether to use the default health service instance from- vendoror to use the backup health service instance from- healthd.- storagedthen listens for health events through- IHealth.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.