Android 11에서는 모든 healthd 코드가 libhealthloop 및 libhealth2impl로 리팩터링된 후 health@2.1 HAL을 구현하도록 수정됩니다. 이 두 라이브러리는 Health 2.1의 패스 스루 구현인 health@2.0-impl-2.1에 의해 정적으로 연결됩니다. 정적으로 연결된 라이브러리를 통해 health@2.0-impl-2.1는 healthd_mainloop 실행 및 폴링과 같은 healthd와 동일한 작업을 할 수 있습니다. init에서 health@2.1-service는 인터페이스 IHealth의 구현을 hwservicemanager에 등록합니다. Android 8.x 또는 9 공급업체 이미지와 Android 11 프레임워크로 기기를 업그레이드할 때 공급업체 이미지는 health@2.1 서비스를 제공하지 않을 수 있습니다. 이전 공급업체 이미지와의 하위 호환성은 지원 중단 일정에 따라 적용됩니다.
이전 버전과의 호환성을 보장하려면 다음 안내를 따르세요.
healthd는 시스템 데몬인 경우에도 IHealth를 hwservicemanager에 등록합니다. IHealth는 시스템 매니페스트에 추가되고 인스턴스 이름은 'backup'입니다.
프레임워크와 storaged는 binder 대신 hwbinder를 통해 healthd와 통신합니다.
프레임워크의 코드 및 storaged가 변경되면 인스턴스의 '기본값'을 가져온 다음(있는 경우) '백업'을 가져옵니다.
C++ 클라이언트 코드는 libhealthhalutils에 정의된 로직을 사용합니다.
자바 클라이언트 코드는 HealthServiceWrapper에 정의된 로직을 사용합니다.
IHealth/default가 널리 사용 가능하고 Android 8.1 공급업체 이미지가 지원 중단된 경우 IHealth/backup 및 healthd는 지원이 중단될 수 있습니다.
healthd의 보드별 빌드 변수
BOARD_PERIODIC_CHORES_INTERVAL_*는 healthd를 빌드하는 데 사용되는 보드별 변수입니다. 보드별 값은 시스템/공급업체 빌드 분할의 일부로, 시스템 모듈에 대해 정의할 수 없습니다. 이러한 값은 과거에는 지원 중단된 함수 healthd_board_init에서 재정의되었습니다.
health@2.1에서는 공급업체가 healthd_config 구조체에서 이 두 가지 주기적 작업의 간격 값을 상태 구현 클래스 생성자에 전달하기 전에 재정의할 수 있습니다. 상태 구현 클래스는 android::hardware::health::V2_1::implementation::Health에서 상속해야 합니다.
충전기libbatterymonitor 및 healthd_common 코드의 사용은 health@2.0-impl로 래핑됩니다.
복구.libbatterymonitor에 대한 연결은 health@2.0-impl로 래핑됩니다. BatteryMonitor에 대한 모든 호출이 Health 구현 클래스의 호출로 대체됩니다.
BatteryManager.BatteryManager.queryProperty(int id)는 IBatteryPropertiesRegistrar.getProperty의 유일한 클라이언트였습니다.
IBatteryPropertiesRegistrar.getProperty는 healthd에서 제공되었으며 /sys/class/power_supply를 직접 읽습니다.
보안 고려 사항으로 인해 앱에서 직접 health HAL을 호출할 수 없습니다. Android 9 이상에서 바인더 서비스 IBatteryPropertiesRegistrar는 healthd 대신 BatteryService에서 제공됩니다. BatteryService는 health HAL에 대한 호출을 위임하여 요청된 정보를 검색합니다.
BatteryService Android 9 이상에서는 BatteryService가 HealthServiceWrapper를 사용하여 vendor의 기본 상태 서비스 인스턴스를 사용할지, 아니면 healthd의 백업 상태 서비스 인스턴스를 사용할지 결정합니다. 그러면 BatteryService가 IHealth.registerCallback을 통해 상태 이벤트를 수신 대기합니다.
Storaged Android 9 이상에서는 storaged가 libhealthhalutils를 사용하여 vendor의 기본 상태 서비스 인스턴스를 사용할지, 아니면 healthd의 백업 상태 서비스 인스턴스를 사용할지 결정합니다. 그러면 storaged가 IHealth.registerCallback을 통해 상태 이벤트를 수신 대기하고 스토리지 정보를 검색합니다.
libbatterymonitor를 사용하는 모든 기기별 health HAL 구현은 상태 구현 클래스 생성자에서 재정의되지 않는 한 기본적으로 이러한 커널 인터페이스에 액세스합니다.
이러한 파일이 없거나 healthd 또는 기본 서비스에서 액세스할 수 없는 경우 (예: 파일이 SELinux 정책이 잘못 구성되어 액세스를 거부하는 공급업체별 폴더의 심볼릭 링크인 경우) 제대로 작동하지 않을 수 있습니다. 따라서 기본 구현을 사용하더라도 추가 공급업체별 SELinux 변경이 필요할 수 있습니다.
Health 2.1에서 사용되는 /sys/class/power_supply/*/capacity_level 및 /sys/class/power_supply/*/time_to_full_now와 같은 일부 커널 인터페이스는 선택사항입니다. 하지만 커널 인터페이스가 누락되었을 때 잘못된 프레임워크 동작이 발생하지 않도록 하려면 상태 HAL 2.1 서비스를 빌드하기 전에 CL 1398913을 선별하는 것이 좋습니다.
테스트
Android 11에는 health@2.1 HAL 전용으로 작성된 새로운 VTS 테스트가 포함되어 있습니다. 기기가 기기 매니페스트에서 health@2.1 HAL을 선언하는 경우 해당하는 VTS 테스트를 통과해야 합니다.
테스트는 기본 인스턴스(기기가 HAL을 올바르게 구현할 수 있도록)와 백업 인스턴스(healthd가 삭제되기 전에 올바르게 계속 작동하도록)에 대해 모두 작성되었습니다.
배터리 정보 요구사항
Health 2.0 HAL은 HAL 인터페이스에 대한 일련의 요구사항을 설명하지만 해당 VTS 테스트는 이러한 적용에 있어 비교적 완화됩니다.
Android 11에는 Android 11 이상을 실행하는 기기에 다음 요구사항을 적용하기 위해 새로운 VTS 테스트가 추가되었습니다.
순간 및 평균 배터리의 전류의 단위는 마이크로암페어(μA)여야 합니다.
순간 및 평균 배터리 전류의 신호는 정확해야 합니다.
구체적으로는 다음과 같습니다.
배터리 상태가 UNKNOWN인 경우 전류 == 0
배터리 상태가 CHARGING인 경우 전류 > 0
배터리 상태가 NOT_CHARGING인 경우 전류 <= 0
배터리 상태가 DISCHARGING인 경우 전류 < 0
배터리 상태가 FULL인 경우 적용되지 않음
배터리 상태는 전원 연결 여부에 상관없이 정확해야 합니다. 구체적으로는 다음과 같습니다.
전원이 연결된 경우에만 배터리 상태가 CHARGING, NOT_CHARGING 또는 FULL 중 하나여야 합니다.
전원 연결이 해제된 경우에만 배터리 상태가 DISCHARGING여야 합니다.
구현에서 libbatterymonitor을 사용하고 커널 인터페이스의 값을 통과하는 경우 sysfs 노드가 올바른 값을 보고하는지 확인합니다.
배터리 전류가 올바른 신호와 단위로 보고되는지 확인합니다. 여기에는 다음 sysfs 노드가 포함됩니다.
/sys/class/power_supply/*/current_avg
/sys/class/power_supply/*/current_max
/sys/class/power_supply/*/current_now
양수 값은 배터리의 수신 전류를 나타냅니다.
값은 마이크로암페어(μA)여야 합니다.
배터리 전압이 마이크로볼트(μV)로 보고되는지 확인합니다. 여기에는 다음 sysfs 노드가 포함됩니다.
/sys/class/power_supply/*/voltage_max
/sys/class/power_supply/*/voltage_now
기본 HAL 구현은 voltage_now를 1,000으로 나누고 값을 밀리볼트(mV)로 보고합니다. @1.0::HealthInfo를 참고하세요.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-07-27(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-07-27(UTC)"],[],[],null,["# Implement Health 2.1\n\n| **Note:** The Health 2.1 HAL is deprecated. It is recommended to [implement the\n| health AIDL HAL](/docs/core/perf/health#aidl-impl) directly, even on devices launching before Android 11. Documentation for implementing Health 2.1 HAL is kept here for reference.\n\nIn Android 11, all `healthd` code is refactored into\n`libhealthloop` and `libhealth2impl`, then modified to implement the health@2.1\nHAL. These two libraries are linked statically by `health@2.0-impl-2.1`,\nthe passthrough implementation of Health 2.1. The statically linked libraries\nenable `health@2.0-impl-2.1` to do the same work as `healthd`, such as running\n`healthd_mainloop` and polling. In init, the `health@2.1-service` registers an\nimplementation of the interface `IHealth` to `hwservicemanager`. When upgrading\ndevices with an Android 8.x or 9\nvendor image and an Android 11 framework,\nthe vendor image might not provide the health@2.1 service. Backward\ncompatibility with old vendor images is enforced by the\n[deprecation schedule](/docs/core/architecture/vintf/fcm#hal-version-deprecation).\n\nTo ensure backwards compatibility:\n\n1. `healthd` registers `IHealth` to `hwservicemanager` despite being a system daemon. `IHealth` is added to the system manifest, with the instance name \"backup\".\n2. The framework and `storaged` communicate with `healthd` through `hwbinder` instead of `binder`.\n3. The code for framework and `storaged` are changed to fetch the instance \"default\" if available, then \"backup\".\n - C++ client code uses the logic defined in `libhealthhalutils`.\n - Java client code uses the logic defined in `HealthServiceWrapper`.\n4. After IHealth/default is widely available and Android 8.1 vendor images are deprecated, IHealth/backup and `healthd` can be deprecated.\n\nBoard-specific build variables for healthd\n------------------------------------------\n\n`BOARD_PERIODIC_CHORES_INTERVAL_*` are board-specific variables used to build\n`healthd`. As part of the system/vendor build split, board-specific values\n**cannot** be defined for system modules. These values used to be overridden\nin the deprecated function `healthd_board_init`.\n\nIn health@2.1, vendors can override\nthese two periodic chores interval values in the `healthd_config` struct before\npassing to the health implementation class constructor. The health\nimplementation class should inherit from\n`android::hardware::health::V2_1::implementation::Health`.\n\nImplement the Health 2.1 service\n--------------------------------\n\nFor information on implementing the Health 2.1 service, see\n[hardware/interfaces/health/2.1/README.md](https://android.googlesource.com/platform/hardware/interfaces/+/android16-release/health/2.1/README.md).\n\nHealth clients\n--------------\n\nhealth@2.x has the following clients:\n\n- **charger.** The use of `libbatterymonitor` and `healthd_common` code is wrapped in `health@2.0-impl`.\n- **recovery.** The linkage to `libbatterymonitor` is wrapped in `health@2.0-impl`. All calls to `BatteryMonitor` are replaced by calls into the `Health` implementation class.\n- **BatteryManager.** `BatteryManager.queryProperty(int id)` was the only\n client of `IBatteryPropertiesRegistrar.getProperty`.\n `IBatteryPropertiesRegistrar.getProperty` was provided by\n `healthd` and directly read `/sys/class/power_supply`.\n\n As a security consideration, apps aren't allowed to call into health HAL\n directly. In Android 9 and higher, the binder\n service `IBatteryPropertiesRegistrar` is provided by `BatteryService`\n instead of `healthd`. `BatteryService` delegates the call to the health HAL\n to retrieve the requested information.\n- **BatteryService.** In Android 9 and higher,\n `BatteryService` uses `HealthServiceWrapper` to determine whether to use the\n *default* health service instance from `vendor` or to use the *backup*\n health service instance from `healthd`. `BatteryService` then listens for\n health events through `IHealth.registerCallback`.\n\n- **Storaged.** In Android 9 and higher,\n `storaged` uses `libhealthhalutils` to determine whether to use the\n *default* health service instance from `vendor` or to use the *backup*\n health service instance from `healthd`. `storaged` then\n listens for health events through `IHealth.registerCallback` and retrieves\n storage information.\n\nSELinux changes\n---------------\n\nThe health@2.1 HAL includes the following SELinux changes in the platform:\n\n- Adds `android.hardware.health@2.1-service` to `file_contexts`.\n\nFor devices with their own implementation, some vendor SELinux changes may be\nnecessary. Example: \n\n # device/\u003cmanufacturer\u003e/\u003cdevice\u003e/sepolicy/vendor/hal_health_default.te\n # Add device specific permissions to hal_health_default domain, especially\n # if it links to board-specific libhealthd or implements storage APIs.\n\nKernel interfaces\n-----------------\n\nThe `healthd` daemon and the default implementation\n`android.hardware.health@2.0-impl-2.1` access the following kernel interfaces to\nretrieve battery information:\n\n- `/sys/class/power_supply/*/capacity_level` (added in Health 2.1)\n- `/sys/class/power_supply/*/capacity`\n- `/sys/class/power_supply/*/charge_counter`\n- `/sys/class/power_supply/*/charge_full`\n- `/sys/class/power_supply/*/charge_full_design` (added in Health 2.1)\n- `/sys/class/power_supply/*/current_avg`\n- `/sys/class/power_supply/*/current_max`\n- `/sys/class/power_supply/*/current_now`\n- `/sys/class/power_supply/*/cycle_count`\n- `/sys/class/power_supply/*/health`\n- `/sys/class/power_supply/*/online`\n- `/sys/class/power_supply/*/present`\n- `/sys/class/power_supply/*/status`\n- `/sys/class/power_supply/*/technology`\n- `/sys/class/power_supply/*/temp`\n- `/sys/class/power_supply/*/time_to_full_now` (added in Health 2.1)\n- `/sys/class/power_supply/*/type`\n- `/sys/class/power_supply/*/voltage_max`\n- `/sys/class/power_supply/*/voltage_now`\n\nAny device-specific health HAL implementation that uses `libbatterymonitor`\naccesses these kernel interfaces by default, unless overridden in the health\nimplementation class constructor.\n\nIf these files are missing or are inaccessible from `healthd` or from the\ndefault service (for example, the file is a symlink to a vendor-specific folder\nthat denies access because of misconfigured SELinux policy), they might not\nfunction correctly. So additional vendor-specific SELinux changes might be\nnecessary even though the default implementation is used.\n\nSome kernel interfaces used in Health 2.1, such as\n`/sys/class/power_supply/*/capacity_level` and\n`/sys/class/power_supply/*/time_to_full_now`, may be optional. However, to\nprevent incorrect framework behaviors resulting from missing kernel interfaces,\nit is recommended to cherry-pick\n[CL 1398913](https://r.android.com/1398913)\nbefore building the Health HAL 2.1 service.\n\nTesting\n-------\n\nAndroid 11 includes new\n[VTS tests](/docs/compatibility/vts)\nwritten specifically for the health@2.1 HAL. If a device declares\nhealth@2.1 HAL in the device manifest, it must pass the corresponding VTS tests.\nTests are written for both the default instance (to ensure that the device\nimplements the HAL correctly) and the backup instance (to ensure that `healthd`\ncontinues to function correctly before it is removed).\n\n### Battery information requirements\n\nThe Health 2.0 HAL states a set of requirements on the HAL interface, but the\ncorresponding VTS tests are relatively relaxed on enforcing them.\nIn Android 11, new VTS tests are added to enforce the\nfollowing requirements on devices launching with Android\n11 and higher:\n\n- The units of intataneous and average battery current must be microamps (μA).\n- The sign of instantaneous and average battery current must be correct. Specifically:\n - current == 0 when battery status is `UNKNOWN`\n - current \\\u003e 0 when battery status is `CHARGING`\n - current \\\u003c= 0 when battery status is `NOT_CHARGING`\n - current \\\u003c 0 when battery status is `DISCHARGING`\n - Not enforced when battery status is `FULL`\n- The battery status must be correct against whether or not a power source is connected. Specifically:\n - battery status must be one of `CHARGING`, `NOT_CHARGING`, or `FULL` if and only if a power source is connected;\n - battery status must be `DISCHARGING` if and only if a power source is disconnected.\n\nIf you use `libbatterymonitor` in your implementation and pass through values\nfrom kernel interfaces, ensure the sysfs nodes are reporting correct values:\n\n- Ensure the battery current is reported with the correct sign and units. This includes the following sysfs nodes:\n - `/sys/class/power_supply/*/current_avg`\n - `/sys/class/power_supply/*/current_max`\n - `/sys/class/power_supply/*/current_now`\n - Positive values indicate incoming current into the battery.\n - Values should be in microamps (μA).\n- Ensure the battery voltage is reported in microvolts (μV). This includes the following sysfs nodes:\n - `/sys/class/power_supply/*/voltage_max`\n - `/sys/class/power_supply/*/voltage_now`\n - Note that the default HAL implementation divides `voltage_now` by 1000 and reports values in millivolts (mV). See [@1.0::HealthInfo](https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/android10-release/health/1.0/types.hal).\n\nFor details, see\n[Linux power supply class](https://www.kernel.org/doc/Documentation/power/power_supply_class.txt)."]]