Implementa Health 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 health@2.1. health@2.0-impl-2.1, la implementación de transferencia de Health 2.1, vincula estas dos bibliotecas de forma estática. Las bibliotecas vinculadas de forma estática permiten que health@2.0-impl-2.1 realice el mismo trabajo que healthd, como ejecutar healthd_mainloop y realizar sondeos. En init, health@2.1-service registra una implementación de la interfaz IHealth en hwservicemanager. Cuando se actualizan dispositivos con una imagen del proveedor de Android 8.x o 9 y un framework de Android 11, es posible que la imagen del proveedor no proporcione el servicio health@2.1. La programación de baja exige la retrocompatibilidad con imágenes de proveedores anteriores.

Para garantizar la retrocompatibilidad, haz lo siguiente:

  1. healthd registra IHealth en hwservicemanager a pesar de ser un daemon del sistema. IHealth se agrega al manifiesto del sistema con el nombre de instancia "backup".
  2. El framework y storaged se comunican con healthd a través de hwbinder en lugar de binder.
  3. El código del framework y storaged se modificaron para recuperar la instancia "default" si está disponible y, luego, "backup".
    • El código del cliente C++ usa la lógica definida en libhealthhalutils.
    • El código del cliente de Java usa la lógica definida en HealthServiceWrapper.
  4. Después de que IHealth/default esté disponible de forma generalizada y se dejen de usar las imágenes de proveedores de Android 8.1, se podrán dejar de usar IHealth/backup y healthd.

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

BOARD_PERIODIC_CHORES_INTERVAL_* son variables específicas de la placa que se usan para compilar healthd. Como parte de la división de la compilación del sistema/proveedor, no se pueden definir valores específicos de la placa para los módulos del sistema. Estos valores se anulaban en la función healthd_board_init obsoleta.

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

Implementa el servicio de Health 2.1

Para obtener información sobre la implementación del servicio de Health 2.1, consulta 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 se incluye en health@2.0-impl.
  • recuperación La vinculación a libbatterymonitor se incluye en health@2.0-impl. Todas las llamadas a BatteryMonitor se reemplazan por llamadas a la clase de implementación Health.
  • BatteryManager. BatteryManager.queryProperty(int id) era el único cliente de IBatteryPropertiesRegistrar.getProperty. IBatteryPropertiesRegistrar.getProperty fue proporcionado por healthd y se leyó directamente /sys/class/power_supply.

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

  • BatteryService. En Android 9 y versiones posteriores, BatteryService usa HealthServiceWrapper para determinar si se debe usar la instancia del servicio de salud predeterminada de vendor o la instancia del servicio de salud de copia de seguridad de healthd. Luego, BatteryService escucha los eventos de salud a través de IHealth.registerCallback.

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

Cambios en 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.

En el caso de los dispositivos con su propia implementación, es posible que sean 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 kernel

El daemon 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 (se agregó 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 (se agregó en 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 (se agregó en Health 2.1)
  • /sys/class/power_supply/*/type
  • /sys/class/power_supply/*/voltage_max
  • /sys/class/power_supply/*/voltage_now

Cualquier implementación del 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, si el archivo es un vínculo 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, es posible que se necesiten cambios adicionales específicos del proveedor en SELinux, incluso si se usa la implementación predeterminada.

Algunas interfaces del kernel que se usan 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 framework como resultado de la falta de interfaces del kernel, se recomienda realizar un cherry-pick de CL 1398913 antes de compilar el servicio de la HAL de Health 2.1.

Prueba

Android 11 incluye nuevas pruebas de VTS escritas específicamente para la HAL health@2.1. Si un dispositivo declara el HAL health@2.1 en el manifiesto del dispositivo, debe superar las pruebas de VTS correspondientes. Las pruebas se escriben tanto para la instancia predeterminada (para garantizar que el dispositivo implemente el HAL correctamente) como para la instancia de copia de seguridad (para garantizar que healthd siga funcionando correctamente antes de que se quite).

Requisitos de información sobre la batería

El HAL de Health 2.0 establece un conjunto de requisitos en la interfaz de HAL, pero las pruebas de VTS correspondientes son relativamente flexibles en cuanto a su aplicación. En Android 11, se agregaron nuevas pruebas del VTS para aplicar los siguientes requisitos en los dispositivos que se lancen con Android 11 y versiones posteriores:

  • Las unidades de la corriente de batería instantánea y promedio deben ser microamperios (μA).
  • El signo de la corriente de batería instantánea y promedio debe ser correcto. Específicamente:
    • current == 0 cuando el estado de la batería es UNKNOWN
    • current > 0 cuando el estado de la batería es CHARGING
    • La corriente es menor o igual a 0 cuando el estado de la batería es NOT_CHARGING.
    • La corriente es inferior a 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, independientemente de si hay una fuente de alimentación conectada. 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 solo si se desconecta una fuente de alimentación.

Si usas libbatterymonitor en tu implementación y pasas valores desde las interfaces del kernel, asegúrate de que los nodos de sysfs informen los valores correctos:

  • Asegúrate de que la corriente de la batería se informe con el signo y las unidades correctos. Esto incluye los siguientes nodos de sysfs:
    • /sys/class/power_supply/*/current_avg
    • /sys/class/power_supply/*/current_max
    • /sys/class/power_supply/*/current_now
    • Los valores positivos indican la corriente entrante en la batería.
    • Los valores deben estar en microamperios (μA).
  • Asegúrate de que el voltaje de la batería se registre en microvoltios (μV). Esto incluye los siguientes nodos de sysfs:
    • /sys/class/power_supply/*/voltage_max
    • /sys/class/power_supply/*/voltage_now
    • Ten en cuenta que la implementación predeterminada del HAL divide voltage_now entre 1,000 y registra los valores en milivoltios (mV). Consulta @1.0::HealthInfo.

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