1*4d7e907cSAndroid Build Coastguard Worker# Implementing Health 2.1 HAL 2*4d7e907cSAndroid Build Coastguard Worker 3*4d7e907cSAndroid Build Coastguard Worker1. Install common binderized service. The binderized service `dlopen()`s 4*4d7e907cSAndroid Build Coastguard Worker passthrough implementations on the device, so there is no need to write 5*4d7e907cSAndroid Build Coastguard Worker your own. 6*4d7e907cSAndroid Build Coastguard Worker 7*4d7e907cSAndroid Build Coastguard Worker ```mk 8*4d7e907cSAndroid Build Coastguard Worker # Install default binderized implementation to vendor. 9*4d7e907cSAndroid Build Coastguard Worker PRODUCT_PACKAGES += [email protected] 10*4d7e907cSAndroid Build Coastguard Worker ``` 11*4d7e907cSAndroid Build Coastguard Worker 12*4d7e907cSAndroid Build Coastguard Worker1. Delete existing VINTF manifest entry. Search for `android.hardware.health` in 13*4d7e907cSAndroid Build Coastguard Worker your device manifest, and delete the whole `<hal>` entry for older versions 14*4d7e907cSAndroid Build Coastguard Worker of the HAL. Instead, when `[email protected]` is installed, 15*4d7e907cSAndroid Build Coastguard Worker a VINTF manifest fragment is installed to `/vendor/etc/vintf`, so there is 16*4d7e907cSAndroid Build Coastguard Worker no need to manually specify it in your device manifest. See 17*4d7e907cSAndroid Build Coastguard Worker [Manifest fragments](https://source.android.com/devices/architecture/vintf/objects#manifest-fragments) 18*4d7e907cSAndroid Build Coastguard Worker for details. 19*4d7e907cSAndroid Build Coastguard Worker 20*4d7e907cSAndroid Build Coastguard Worker1. Install the proper passthrough implemetation. 21*4d7e907cSAndroid Build Coastguard Worker 22*4d7e907cSAndroid Build Coastguard Worker 1. If you want to use default implementation: 23*4d7e907cSAndroid Build Coastguard Worker 24*4d7e907cSAndroid Build Coastguard Worker ```mk 25*4d7e907cSAndroid Build Coastguard Worker # Install default passthrough implementation to vendor. 26*4d7e907cSAndroid Build Coastguard Worker PRODUCT_PACKAGES += [email protected] 27*4d7e907cSAndroid Build Coastguard Worker 28*4d7e907cSAndroid Build Coastguard Worker # For non-A/B devices, install default passthrough implementation to recovery. 29*4d7e907cSAndroid Build Coastguard Worker PRODUCT_PACKAGES += [email protected] 30*4d7e907cSAndroid Build Coastguard Worker ``` 31*4d7e907cSAndroid Build Coastguard Worker 32*4d7e907cSAndroid Build Coastguard Worker You are done. Otherwise, go to the next step. 33*4d7e907cSAndroid Build Coastguard Worker 34*4d7e907cSAndroid Build Coastguard Worker 1. If you want to write your own implementation, 35*4d7e907cSAndroid Build Coastguard Worker 36*4d7e907cSAndroid Build Coastguard Worker 1. Copy skeleton implementation from the [appendix](#impl). 37*4d7e907cSAndroid Build Coastguard Worker 38*4d7e907cSAndroid Build Coastguard Worker 1. Modify the implementation to suit your needs. 39*4d7e907cSAndroid Build Coastguard Worker 40*4d7e907cSAndroid Build Coastguard Worker * If you have a board or device specific `libhealthd`, see 41*4d7e907cSAndroid Build Coastguard Worker [Upgrading with a customized libhealthd](#update-from-1-0). 42*4d7e907cSAndroid Build Coastguard Worker * If you are upgrading from 1.0 health HAL, see 43*4d7e907cSAndroid Build Coastguard Worker [Upgrading from Health HAL 1.0](#update-from-1-0). 44*4d7e907cSAndroid Build Coastguard Worker * If you are upgrading from a customized 2.0 health HAL 45*4d7e907cSAndroid Build Coastguard Worker implementation, See 46*4d7e907cSAndroid Build Coastguard Worker [Upgrading from Health HAL 2.0](#update-from-2-0). 47*4d7e907cSAndroid Build Coastguard Worker 48*4d7e907cSAndroid Build Coastguard Worker 1. [Install the implementation](#install). 49*4d7e907cSAndroid Build Coastguard Worker 50*4d7e907cSAndroid Build Coastguard Worker 1. [Update necessary SELinux permissions](#selinux). 51*4d7e907cSAndroid Build Coastguard Worker 52*4d7e907cSAndroid Build Coastguard Worker 1. [Fix `/charger` symlink](#charger-symlink). 53*4d7e907cSAndroid Build Coastguard Worker 54*4d7e907cSAndroid Build Coastguard Worker# Upgrading with a customized libhealthd or from Health HAL 1.0 {#update-from-1-0} 55*4d7e907cSAndroid Build Coastguard Worker 56*4d7e907cSAndroid Build Coastguard Worker`libhealthd` contains two functions: `healthd_board_init()` and 57*4d7e907cSAndroid Build Coastguard Worker`healthd_board_battery_update()`. Similarly, Health HAL 1.0 contains `init()` 58*4d7e907cSAndroid Build Coastguard Workerand `update()`, with an additional `energyCounter()` function. 59*4d7e907cSAndroid Build Coastguard Worker 60*4d7e907cSAndroid Build Coastguard Worker* `healthd_board_init()` / `@1.0::IHealth.init()` should be called before 61*4d7e907cSAndroid Build Coastguard Worker passing the `healthd_config` struct to your `HealthImpl` class. See 62*4d7e907cSAndroid Build Coastguard Worker `HIDL_FETCH_IHealth` in [`HealthImpl.cpp`](#health_impl_cpp). 63*4d7e907cSAndroid Build Coastguard Worker 64*4d7e907cSAndroid Build Coastguard Worker* `healthd_board_battery_update()` / `@1.0::IHealth.update()` should be called 65*4d7e907cSAndroid Build Coastguard Worker in `HealthImpl::UpdateHealthInfo()`. Example: 66*4d7e907cSAndroid Build Coastguard Worker 67*4d7e907cSAndroid Build Coastguard Worker ```c++ 68*4d7e907cSAndroid Build Coastguard Worker void HealthImpl::UpdateHealthInfo(HealthInfo* health_info) { 69*4d7e907cSAndroid Build Coastguard Worker struct BatteryProperties props; 70*4d7e907cSAndroid Build Coastguard Worker convertFromHealthInfo(health_info->legacy.legacy, &props); 71*4d7e907cSAndroid Build Coastguard Worker healthd_board_battery_update(&props); 72*4d7e907cSAndroid Build Coastguard Worker convertToHealthInfo(&props, health_info->legacy.legacy); 73*4d7e907cSAndroid Build Coastguard Worker } 74*4d7e907cSAndroid Build Coastguard Worker ``` 75*4d7e907cSAndroid Build Coastguard Worker For efficiency, you should move code in `healthd_board_battery_update` to 76*4d7e907cSAndroid Build Coastguard Worker `HealthImpl::UpdateHealthInfo` and modify `health_info` directly to avoid 77*4d7e907cSAndroid Build Coastguard Worker conversion to `BatteryProperties`. 78*4d7e907cSAndroid Build Coastguard Worker 79*4d7e907cSAndroid Build Coastguard Worker* Code for `@1.0::IHealth.energyCounter()` should be moved to 80*4d7e907cSAndroid Build Coastguard Worker `HealthImpl::getEnergyCounter()`. Example: 81*4d7e907cSAndroid Build Coastguard Worker 82*4d7e907cSAndroid Build Coastguard Worker ```c++ 83*4d7e907cSAndroid Build Coastguard Worker Return<void> Health::getEnergyCounter(getEnergyCounter_cb _hidl_cb) { 84*4d7e907cSAndroid Build Coastguard Worker int64_t energy = /* ... */; 85*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Result::SUCCESS, energy); 86*4d7e907cSAndroid Build Coastguard Worker return Void(); 87*4d7e907cSAndroid Build Coastguard Worker } 88*4d7e907cSAndroid Build Coastguard Worker ``` 89*4d7e907cSAndroid Build Coastguard Worker 90*4d7e907cSAndroid Build Coastguard Worker# Upgrading from Health HAL 2.0 {#update-from-2-0} 91*4d7e907cSAndroid Build Coastguard Worker 92*4d7e907cSAndroid Build Coastguard Worker* If you have implemented `healthd_board_init()` and/or 93*4d7e907cSAndroid Build Coastguard Worker `healthd_board_battery_update()` (instead of using `libhealthd.default`), 94*4d7e907cSAndroid Build Coastguard Worker see [the section above](#update-from-1-0) 95*4d7e907cSAndroid Build Coastguard Worker for instructions to convert them. 96*4d7e907cSAndroid Build Coastguard Worker 97*4d7e907cSAndroid Build Coastguard Worker* If you have implemented `get_storage_info()` and/or `get_disk_stats()` 98*4d7e907cSAndroid Build Coastguard Worker (instead of using libhealthstoragedefault), implement `HealthImpl::getDiskStats` 99*4d7e907cSAndroid Build Coastguard Worker and/or `HealthImpl::getStorageInfo` directly. There is no need to override 100*4d7e907cSAndroid Build Coastguard Worker `HealthImpl::getHealthInfo` or `HealthImpl::getHealthInfo_2_1` because they call 101*4d7e907cSAndroid Build Coastguard Worker `getDiskStats` and `getStorageInfo` to retrieve storage information. 102*4d7e907cSAndroid Build Coastguard Worker 103*4d7e907cSAndroid Build Coastguard Worker# Install the implementation {#install} 104*4d7e907cSAndroid Build Coastguard Worker 105*4d7e907cSAndroid Build Coastguard WorkerIn `device.mk`: 106*4d7e907cSAndroid Build Coastguard Worker 107*4d7e907cSAndroid Build Coastguard Worker```mk 108*4d7e907cSAndroid Build Coastguard Worker# Install the passthrough implementation to vendor. 109*4d7e907cSAndroid Build Coastguard WorkerPRODUCT_PACKAGES += [email protected]<device> 110*4d7e907cSAndroid Build Coastguard Worker 111*4d7e907cSAndroid Build Coastguard Worker# For non-A/B devices, also install the passthrough implementation to recovery. 112*4d7e907cSAndroid Build Coastguard WorkerPRODUCT_PACKAGES += [email protected]<device>.recovery 113*4d7e907cSAndroid Build Coastguard Worker``` 114*4d7e907cSAndroid Build Coastguard Worker 115*4d7e907cSAndroid Build Coastguard Worker# Update necessary SELinux permissions {#selinux} 116*4d7e907cSAndroid Build Coastguard Worker 117*4d7e907cSAndroid Build Coastguard WorkerFor example (replace `<device>` with the device name): 118*4d7e907cSAndroid Build Coastguard Worker``` 119*4d7e907cSAndroid Build Coastguard Worker# device/<manufacturer>/<device>/sepolicy/vendor/hal_health_default.te 120*4d7e907cSAndroid Build Coastguard Worker# Add device specific permissions to hal_health_default domain, especially 121*4d7e907cSAndroid Build Coastguard Worker# if a device-specific libhealthd is used and/or device-specific storage related 122*4d7e907cSAndroid Build Coastguard Worker# APIs are implemented. 123*4d7e907cSAndroid Build Coastguard Worker``` 124*4d7e907cSAndroid Build Coastguard Worker 125*4d7e907cSAndroid Build Coastguard Worker# Fix `/charger` symlink {#charger-symlink} 126*4d7e907cSAndroid Build Coastguard WorkerIf you are using `/charger` in your `init.rc` scripts, it is recommended 127*4d7e907cSAndroid Build Coastguard Worker(required for devices running in Android R) that the path is changed to 128*4d7e907cSAndroid Build Coastguard Worker`/system/bin/charger` instead. 129*4d7e907cSAndroid Build Coastguard Worker 130*4d7e907cSAndroid Build Coastguard WorkerSearch for `service charger` in your device configuration directory to see if 131*4d7e907cSAndroid Build Coastguard Workerthis change applies to your device. Below is an example of how the script should 132*4d7e907cSAndroid Build Coastguard Workerlook like: 133*4d7e907cSAndroid Build Coastguard Worker 134*4d7e907cSAndroid Build Coastguard Worker``` 135*4d7e907cSAndroid Build Coastguard Workerservice charger /system/bin/charger 136*4d7e907cSAndroid Build Coastguard Worker class charger 137*4d7e907cSAndroid Build Coastguard Worker user system 138*4d7e907cSAndroid Build Coastguard Worker group system wakelock input 139*4d7e907cSAndroid Build Coastguard Worker capabilities SYS_BOOT 140*4d7e907cSAndroid Build Coastguard Worker file /dev/kmsg w 141*4d7e907cSAndroid Build Coastguard Worker file /sys/fs/pstore/console-ramoops-0 r 142*4d7e907cSAndroid Build Coastguard Worker file /sys/fs/pstore/console-ramoops r 143*4d7e907cSAndroid Build Coastguard Worker file /proc/last_kmsg r 144*4d7e907cSAndroid Build Coastguard Worker``` 145*4d7e907cSAndroid Build Coastguard Worker 146*4d7e907cSAndroid Build Coastguard Worker# Appendix: sample code for the implementation {#impl} 147*4d7e907cSAndroid Build Coastguard Worker 148*4d7e907cSAndroid Build Coastguard Worker## `device/<manufacturer>/<device>/health/Android.bp` {#android_bp} 149*4d7e907cSAndroid Build Coastguard Worker 150*4d7e907cSAndroid Build Coastguard Worker```bp 151*4d7e907cSAndroid Build Coastguard Workercc_library_shared { 152*4d7e907cSAndroid Build Coastguard Worker name: "[email protected]<device>", 153*4d7e907cSAndroid Build Coastguard Worker stem: "[email protected]<device>", 154*4d7e907cSAndroid Build Coastguard Worker 155*4d7e907cSAndroid Build Coastguard Worker // Install to vendor and recovery. 156*4d7e907cSAndroid Build Coastguard Worker proprietary: true, 157*4d7e907cSAndroid Build Coastguard Worker recovery_available: true, 158*4d7e907cSAndroid Build Coastguard Worker 159*4d7e907cSAndroid Build Coastguard Worker relative_install_path: "hw", 160*4d7e907cSAndroid Build Coastguard Worker 161*4d7e907cSAndroid Build Coastguard Worker shared_libs: [ 162*4d7e907cSAndroid Build Coastguard Worker "libbase", 163*4d7e907cSAndroid Build Coastguard Worker "libcutils", 164*4d7e907cSAndroid Build Coastguard Worker "libhidlbase", 165*4d7e907cSAndroid Build Coastguard Worker "liblog", 166*4d7e907cSAndroid Build Coastguard Worker "libutils", 167*4d7e907cSAndroid Build Coastguard Worker "[email protected]", 168*4d7e907cSAndroid Build Coastguard Worker "[email protected]", 169*4d7e907cSAndroid Build Coastguard Worker ], 170*4d7e907cSAndroid Build Coastguard Worker 171*4d7e907cSAndroid Build Coastguard Worker static_libs: [ 172*4d7e907cSAndroid Build Coastguard Worker "[email protected]", 173*4d7e907cSAndroid Build Coastguard Worker "libbatterymonitor", 174*4d7e907cSAndroid Build Coastguard Worker "libhealthloop", 175*4d7e907cSAndroid Build Coastguard Worker "libhealth2impl", 176*4d7e907cSAndroid Build Coastguard Worker // "libhealthd.<device>" 177*4d7e907cSAndroid Build Coastguard Worker ], 178*4d7e907cSAndroid Build Coastguard Worker 179*4d7e907cSAndroid Build Coastguard Worker srcs: [ 180*4d7e907cSAndroid Build Coastguard Worker "HealthImpl.cpp", 181*4d7e907cSAndroid Build Coastguard Worker ], 182*4d7e907cSAndroid Build Coastguard Worker 183*4d7e907cSAndroid Build Coastguard Worker // No vintf_fragments because both -impl and -service should have been 184*4d7e907cSAndroid Build Coastguard Worker // installed. 185*4d7e907cSAndroid Build Coastguard Worker} 186*4d7e907cSAndroid Build Coastguard Worker``` 187*4d7e907cSAndroid Build Coastguard Worker 188*4d7e907cSAndroid Build Coastguard Worker## `device/<manufacturer>/<device>/health/HealthImpl.cpp` {#health_impl_cpp} 189*4d7e907cSAndroid Build Coastguard Worker 190*4d7e907cSAndroid Build Coastguard Worker```c++ 191*4d7e907cSAndroid Build Coastguard Worker#include <memory> 192*4d7e907cSAndroid Build Coastguard Worker#include <string_view> 193*4d7e907cSAndroid Build Coastguard Worker 194*4d7e907cSAndroid Build Coastguard Worker#include <health/utils.h> 195*4d7e907cSAndroid Build Coastguard Worker#include <health2impl/Health.h> 196*4d7e907cSAndroid Build Coastguard Worker#include <hidl/Status.h> 197*4d7e907cSAndroid Build Coastguard Worker 198*4d7e907cSAndroid Build Coastguard Workerusing ::android::sp; 199*4d7e907cSAndroid Build Coastguard Workerusing ::android::hardware::Return; 200*4d7e907cSAndroid Build Coastguard Workerusing ::android::hardware::Void; 201*4d7e907cSAndroid Build Coastguard Workerusing ::android::hardware::health::InitHealthdConfig; 202*4d7e907cSAndroid Build Coastguard Workerusing ::android::hardware::health::V2_1::IHealth; 203*4d7e907cSAndroid Build Coastguard Workerusing ::android::hidl::base::V1_0::IBase; 204*4d7e907cSAndroid Build Coastguard Worker 205*4d7e907cSAndroid Build Coastguard Workerusing namespace std::literals; 206*4d7e907cSAndroid Build Coastguard Worker 207*4d7e907cSAndroid Build Coastguard Workernamespace android { 208*4d7e907cSAndroid Build Coastguard Workernamespace hardware { 209*4d7e907cSAndroid Build Coastguard Workernamespace health { 210*4d7e907cSAndroid Build Coastguard Workernamespace V2_1 { 211*4d7e907cSAndroid Build Coastguard Workernamespace implementation { 212*4d7e907cSAndroid Build Coastguard Worker 213*4d7e907cSAndroid Build Coastguard Worker// android::hardware::health::V2_1::implementation::Health implements most 214*4d7e907cSAndroid Build Coastguard Worker// defaults. Uncomment functions that you need to override. 215*4d7e907cSAndroid Build Coastguard Workerclass HealthImpl : public Health { 216*4d7e907cSAndroid Build Coastguard Worker public: 217*4d7e907cSAndroid Build Coastguard Worker HealthImpl(std::unique_ptr<healthd_config>&& config) 218*4d7e907cSAndroid Build Coastguard Worker : Health(std::move(config)) {} 219*4d7e907cSAndroid Build Coastguard Worker 220*4d7e907cSAndroid Build Coastguard Worker // A subclass can override this if these information should be retrieved 221*4d7e907cSAndroid Build Coastguard Worker // differently. 222*4d7e907cSAndroid Build Coastguard Worker // Return<void> getChargeCounter(getChargeCounter_cb _hidl_cb) override; 223*4d7e907cSAndroid Build Coastguard Worker // Return<void> getCurrentNow(getCurrentNow_cb _hidl_cb) override; 224*4d7e907cSAndroid Build Coastguard Worker // Return<void> getCurrentAverage(getCurrentAverage_cb _hidl_cb) override; 225*4d7e907cSAndroid Build Coastguard Worker // Return<void> getCapacity(getCapacity_cb _hidl_cb) override; 226*4d7e907cSAndroid Build Coastguard Worker // Return<void> getEnergyCounter(getEnergyCounter_cb _hidl_cb) override; 227*4d7e907cSAndroid Build Coastguard Worker // Return<void> getChargeStatus(getChargeStatus_cb _hidl_cb) override; 228*4d7e907cSAndroid Build Coastguard Worker // Return<void> getStorageInfo(getStorageInfo_cb _hidl_cb) override; 229*4d7e907cSAndroid Build Coastguard Worker // Return<void> getDiskStats(getDiskStats_cb _hidl_cb) override; 230*4d7e907cSAndroid Build Coastguard Worker // Return<void> getHealthInfo(getHealthInfo_cb _hidl_cb) override; 231*4d7e907cSAndroid Build Coastguard Worker 232*4d7e907cSAndroid Build Coastguard Worker // Functions introduced in Health HAL 2.1. 233*4d7e907cSAndroid Build Coastguard Worker // Return<void> getHealthConfig(getHealthConfig_cb _hidl_cb) override; 234*4d7e907cSAndroid Build Coastguard Worker // Return<void> getHealthInfo_2_1(getHealthInfo_2_1_cb _hidl_cb) override; 235*4d7e907cSAndroid Build Coastguard Worker // Return<void> shouldKeepScreenOn(shouldKeepScreenOn_cb _hidl_cb) override; 236*4d7e907cSAndroid Build Coastguard Worker 237*4d7e907cSAndroid Build Coastguard Worker protected: 238*4d7e907cSAndroid Build Coastguard Worker // A subclass can override this to modify any health info object before 239*4d7e907cSAndroid Build Coastguard Worker // returning to clients. This is similar to healthd_board_battery_update(). 240*4d7e907cSAndroid Build Coastguard Worker // By default, it does nothing. 241*4d7e907cSAndroid Build Coastguard Worker // void UpdateHealthInfo(HealthInfo* health_info) override; 242*4d7e907cSAndroid Build Coastguard Worker}; 243*4d7e907cSAndroid Build Coastguard Worker 244*4d7e907cSAndroid Build Coastguard Worker} // namespace implementation 245*4d7e907cSAndroid Build Coastguard Worker} // namespace V2_1 246*4d7e907cSAndroid Build Coastguard Worker} // namespace health 247*4d7e907cSAndroid Build Coastguard Worker} // namespace hardware 248*4d7e907cSAndroid Build Coastguard Worker} // namespace android 249*4d7e907cSAndroid Build Coastguard Worker 250*4d7e907cSAndroid Build Coastguard Workerextern "C" IHealth* HIDL_FETCH_IHealth(const char* instance) { 251*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::health::V2_1::implementation::HealthImpl; 252*4d7e907cSAndroid Build Coastguard Worker if (instance != "default"sv) { 253*4d7e907cSAndroid Build Coastguard Worker return nullptr; 254*4d7e907cSAndroid Build Coastguard Worker } 255*4d7e907cSAndroid Build Coastguard Worker auto config = std::make_unique<healthd_config>(); 256*4d7e907cSAndroid Build Coastguard Worker InitHealthdConfig(config.get()); 257*4d7e907cSAndroid Build Coastguard Worker 258*4d7e907cSAndroid Build Coastguard Worker // healthd_board_init(config.get()); 259*4d7e907cSAndroid Build Coastguard Worker 260*4d7e907cSAndroid Build Coastguard Worker return new HealthImpl(std::move(config)); 261*4d7e907cSAndroid Build Coastguard Worker} 262*4d7e907cSAndroid Build Coastguard Worker``` 263