Implementar Salud 2.1

En Android 11, todo el código healthd se refactoriza en libhealthloop y libhealth2impl y luego se modifica para implementar Health@2.1 HAL. Estas dos bibliotecas están vinculadas estáticamente mediante health@2.0-impl-2.1 , la implementación de transferencia de Health 2.1. Las bibliotecas vinculadas estáticamente permiten que health@2.0-impl-2.1 haga el mismo trabajo que healthd , como ejecutar healthd_mainloop y realizar sondeos. En inicio, el health@2.1-service registra una implementación de la interfaz IHealth para hwservicemanager . Al actualizar dispositivos con una imagen de proveedor de Android 8.x o 9 y un marco de trabajo de Android 11, es posible que la imagen de proveedor no proporcione el servicio health@2.1. La compatibilidad con versiones anteriores de imágenes de proveedores anteriores se aplica mediante el programa de desuso .

Para garantizar la compatibilidad con versiones anteriores:

  1. healthd registra IHealth en hwservicemanager a pesar de ser un demonio del sistema. IHealth se agrega al manifiesto del sistema, con el nombre de instancia "copia de seguridad".
  2. El marco y storaged se comunican con healthd a través de hwbinder en lugar de binder .
  3. El código para el marco y storaged se cambian para recuperar la instancia "predeterminada" si está disponible, luego "copia de seguridad".
    • El código del cliente C++ utiliza la lógica definida en libhealthhalutils .
    • El código del cliente Java utiliza la lógica definida en HealthServiceWrapper .
  4. Una vez que IHealth/default esté ampliamente disponible y las imágenes de proveedores de Android 8.1 queden obsoletas, IHealth/backup y healthd podrán quedar obsoletas. Para obtener más detalles, consulte Desuso de health@1.0 .

Variables de construcción específicas de la placa para Healthd

BOARD_PERIODIC_CHORES_INTERVAL_* son variables específicas del tablero que se utilizan para crear healthd . Como parte de la división de compilación del sistema/proveedor, no se pueden definir valores específicos de la placa para los módulos del sistema. Estos valores solían ser anulados en la función obsoleta healthd_board_init .

En health@2.1, los proveedores pueden anular estos dos valores de intervalo de tareas periódicas en la estructura healthd_config antes de pasar al constructor de la clase de implementación de salud. La clase de implementación de salud debe heredar de android::hardware::health::V2_1::implementation::Health .

Implementar el servicio Salud 2.1

Para obtener información sobre la implementación del servicio Health 2.1, consulte hardware/interfaces/health/2.1/README.md .

Clientes de salud

health@2.x tiene los siguientes clientes:

  • cargador. El uso del código libbatterymonitor y healthd_common está incluido en health@2.0-impl .
  • recuperación. El enlace a libbatterymonitor está incluido en health@2.0-impl . Todas las llamadas a BatteryMonitor se reemplazan por llamadas a la clase de implementación Health .
  • Administrador de batería. BatteryManager.queryProperty(int id) era el único cliente de IBatteryPropertiesRegistrar.getProperty . IBatteryPropertiesRegistrar.getProperty fue proporcionado por healthd y leído directamente /sys/class/power_supply .

    Como consideración de seguridad, las aplicaciones no pueden llamar directamente a HAL de salud. En Android 9 y versiones posteriores, BatteryService proporciona el servicio de carpeta IBatteryPropertiesRegistrar en lugar de healthd . BatteryService delega la llamada al HAL de salud para recuperar la información solicitada.

  • Servicio de batería. En Android 9 y versiones posteriores, BatteryService usa HealthServiceWrapper para determinar si se usa la instancia del servicio de salud predeterminado del vendor o la instancia del servicio de salud de respaldo de healthd . Luego, BatteryService escucha los eventos de salud a través de IHealth.registerCallback .

  • Almacenado. En Android 9 y versiones posteriores, storaged usa libhealthhalutils para determinar si se usa la instancia del servicio de salud predeterminado del vendor o la instancia del servicio de salud de respaldo de healthd . storaged luego escucha eventos de salud a través de IHealth.registerCallback y recupera información de almacenamiento.

Cambios en SELinux

Health@2.1 HAL incluye los siguientes cambios de SELinux en la plataforma:

  • Agrega android.hardware.health@2.1-service a file_contexts .

Para dispositivos con su propia implementación, es posible que sean necesarios algunos cambios de proveedor en SELinux. Ejemplo:

# 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.

Interfaces del núcleo

El demonio healthd y la implementación predeterminada android.hardware.health@2.0-impl-2.1 acceden a las siguientes interfaces del kernel para recuperar información de la batería:

  • /sys/class/power_supply/*/capacity_level (agregado en 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 (agregado en Salud 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 (agregado en Salud 2.1)
  • /sys/class/power_supply/*/type
  • /sys/class/power_supply/*/voltage_max
  • /sys/class/power_supply/*/voltage_now

Cualquier implementación HAL de salud específica del dispositivo que utilice libbatterymonitor accede a estas interfaces del kernel de forma predeterminada, a menos que se anule en el constructor de la clase de implementación de salud.

Si estos archivos faltan o no se puede acceder a ellos desde healthd o desde el servicio predeterminado (por ejemplo, el archivo es un enlace simbólico a una carpeta específica del proveedor que deniega el acceso debido a una política SELinux mal configurada), es posible que no funcionen correctamente. Por lo tanto, podrían ser necesarios cambios adicionales de SELinux específicos del proveedor aunque se utilice la implementación predeterminada.

Algunas interfaces del kernel utilizadas en Health 2.1, como /sys/class/power_supply/*/capacity_level y /sys/class/power_supply/*/time_to_full_now , pueden ser opcionales. Sin embargo, para evitar comportamientos incorrectos del marco resultantes de la falta de interfaces del kernel, se recomienda seleccionar CL 1398913 antes de crear el servicio Health HAL 2.1.

Pruebas

Android 11 incluye nuevas pruebas VTS escritas específicamente para Health@2.1 HAL. Si un dispositivo declara salud@2.1 HAL en el manifiesto del dispositivo, debe pasar las pruebas VTS correspondientes. Las pruebas se escriben tanto para la instancia predeterminada (para garantizar que el dispositivo implemente HAL correctamente) como para la instancia de respaldo (para garantizar que healthd continúe funcionando correctamente antes de eliminarlo).

Requisitos de información de la batería

Health 2.0 HAL establece un conjunto de requisitos en la interfaz HAL, pero las pruebas VTS correspondientes son relativamente relajadas a la hora de aplicarlos. En Android 11, se agregan nuevas pruebas VTS para hacer cumplir los siguientes requisitos en dispositivos que se inician con Android 11 y versiones posteriores:

  • Las unidades de corriente instantánea y media de la batería deben ser microamperios (μA).
  • El signo de la corriente instantánea y media de la batería debe ser correcto. Específicamente:
    • actual == 0 cuando el estado de la batería es UNKNOWN
    • corriente > 0 cuando el estado de la batería es CHARGING
    • actual <= 0 cuando el estado de la batería es NOT_CHARGING
    • corriente < 0 cuando el estado de la batería es DISCHARGING
    • No se aplica cuando el estado de la batería es FULL
  • El estado de la batería debe ser correcto en función de si hay una fuente de alimentación conectada o no. Específicamente:
    • el estado de la batería debe ser CHARGING , NOT_CHARGING o FULL si y solo si hay una fuente de alimentación conectada;
    • El estado de la batería debe ser DISCHARGING si y sólo si se desconecta una fuente de alimentación.

Si utiliza libbatterymonitor en su implementación y pasa valores desde las interfaces del kernel, asegúrese de que los nodos sysfs informen los valores correctos:

  • Asegúrese de que la corriente de la batería se informe con el signo y las unidades correctos. Esto incluye los siguientes nodos sysfs:
    • /sys/class/power_supply/*/current_avg
    • /sys/class/power_supply/*/current_max
    • /sys/class/power_supply/*/current_now
    • Los valores positivos indican corriente entrante a la batería.
    • Los valores deben estar en microamperios (μA).
  • Asegúrese de que el voltaje de la batería se informe en microvoltios (μV). Esto incluye los siguientes nodos sysfs:
    • /sys/class/power_supply/*/voltage_max
    • /sys/class/power_supply/*/voltage_now
    • Tenga en cuenta que la implementación HAL predeterminada divide voltage_now por 1000 e informa los valores en milivoltios (mV). Consulte @1.0::HealthInfo .

Para obtener más información, consulte Clase de fuente de alimentación de Linux .