Implementando Salud 2.1

En Android 11, todo el código de healthd se refactoriza en libhealthloop y libhealth2impl y, luego, se modifica para implementar la HAL de salud@2.1. Estas dos bibliotecas están vinculadas estáticamente por health@2.0-impl-2.1 , la implementación de paso de health 2.1. Las bibliotecas enlazadas estáticamente permiten que health@2.0-impl-2.1 haga el mismo trabajo que healthd , como ejecutar healthd_mainloop y sondear. En init, 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 del proveedor no proporcione el servicio health@2.1. El cronograma de obsolescencia impone la compatibilidad con versiones anteriores de imágenes de proveedores antiguos.

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 el healthd storaged través de hwbinder en lugar de binder .
  3. El código para el marco y el storaged se cambian para obtener la instancia "predeterminada" si está disponible, luego "copia de seguridad".
    • El código de cliente de C++ usa la lógica definida en libhealthhalutils .
    • El código de cliente de Java utiliza la lógica definida en HealthServiceWrapper .
  4. Después de que IHealth/default esté ampliamente disponible y las imágenes del proveedor de Android 8.1 estén en desuso, IHealth/backup y healthd pueden quedar en desuso. Para obtener más detalles, consulte Deprecating health@1.0 .

Variables de compilación específicas de la placa para la salud

BOARD_PERIODIC_CHORES_INTERVAL_* son variables específicas de la placa que se utilizan para generar healthd . Como parte de la división de compilación del sistema/proveedor, los valores específicos de la placa no se pueden definir para los módulos del sistema. Estos valores solían anularse en la función en desuso 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 clase de implementación de salud. La clase de implementación de salud debe heredar de android::hardware::health::V2_1::implementation::Health .

Implementación del 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á envuelto 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 lo proporcionó healthd y leyó 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, IBatteryPropertiesRegistrar proporciona el servicio de enlace BatteryService en lugar de healthd . BatteryService delega la llamada a la HAL de estado para recuperar la información solicitada.

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

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

Cambios de SELinux

El HAL health@2.1 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, pueden ser necesarios algunos cambios de SELinux del proveedor. 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 salud 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 use 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 faltan estos archivos 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 de SELinux mal configurada), es posible que no funcionen correctamente. Por lo tanto, pueden ser necesarios cambios adicionales de SELinux específicos del proveedor aunque se utilice la implementación predeterminada.

Algunas interfaces de 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 de marco incorrectos como resultado de la falta de interfaces del kernel, se recomienda seleccionar CL 1398913 antes de compilar el servicio HAL 2.1 de salud.

Pruebas

Android 11 incluye nuevas pruebas VTS escritas específicamente para health@2.1 HAL. Si un dispositivo declara health@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 que se elimine).

Requisitos de información de la batería

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

  • Las unidades de corriente de batería instantánea y promedio deben ser microamperios (μA).
  • El signo de corriente de batería instantánea y media 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 está DISCHARGING
    • No se aplica cuando el estado de la batería es FULL
  • El estado de la batería debe ser correcto con respecto a si una fuente de alimentación está 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 estar DISCHARGING si y solo si se desconecta una fuente de alimentación.

Si usa libbatterymonitor en su implementación y pasa los valores de 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 en la batería.
    • Los valores deben estar en microamperios (μA).
  • Asegúrese de que el voltaje de la batería se indique 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:: Información de salud .

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