Mise en œuvre de Santé 2.1

Dans Android 11, tout le code healthd est refactorisé en libhealthloop et libhealth2impl , puis modifié pour implémenter le health@2.1 HAL. Ces deux bibliothèques sont liées statiquement par health@2.0-impl-2.1 , l'implémentation passthrough de health 2.1. Les bibliothèques liées statiquement permettent à health@2.0-impl-2.1 d'effectuer le même travail que healthd , comme l'exécution healthd_mainloop et l'interrogation. Dans init, le health@2.1-service enregistre une implémentation de l'interface IHealth vers hwservicemanager . Lors de la mise à niveau d'appareils avec une image du fournisseur Android 8.x ou 9 et une infrastructure Android 11, l'image du fournisseur peut ne pas fournir le service health@2.1. La rétrocompatibilité avec les anciennes images des fournisseurs est renforcée par le calendrier de dépréciation .

Pour garantir la compatibilité ascendante :

  1. healthd enregistre IHealth auprès de hwservicemanager bien qu'il s'agisse d'un démon système. IHealth est ajouté au manifeste système, avec le nom d'instance « sauvegarde ».
  2. Le framework et storaged communiquent avec healthd via hwbinder au lieu de binder .
  3. Le code du framework et storaged est modifié pour récupérer l'instance "par défaut" si disponible, puis "sauvegarde".
    • Le code client C++ utilise la logique définie dans libhealthhalutils .
    • Le code client Java utilise la logique définie dans HealthServiceWrapper .
  4. Une fois qu’IHealth/default est largement disponible et que les images du fournisseur Android 8.1 sont obsolètes, IHealth/backup et healthd peuvent être obsolètes. Pour plus de détails, consultez Dépréciation de health@1.0 .

Variables de construction spécifiques à la carte pour healthd

BOARD_PERIODIC_CHORES_INTERVAL_* sont des variables spécifiques à la carte utilisées pour créer healthd . Dans le cadre de la répartition système/fournisseur, les valeurs spécifiques à la carte ne peuvent pas être définies pour les modules système. Ces valeurs étaient remplacées dans la fonction obsolète healthd_board_init .

Dans health@2.1, les fournisseurs peuvent remplacer ces deux valeurs d'intervalle de tâches périodiques dans la structure healthd_config avant de les transmettre au constructeur de la classe d'implémentation Health. La classe d'implémentation de santé doit hériter de android::hardware::health::V2_1::implementation::Health .

Implémentation du service Santé 2.1

Pour plus d'informations sur la mise en œuvre du service Health 2.1, voir hardware/interfaces/health/2.1/README.md .

Clientèle de santé

health@2.x a les clients suivants :

  • chargeur . L'utilisation du code libbatterymonitor et healthd_common est enveloppée dans health@2.0-impl .
  • récupération . Le lien vers libbatterymonitor est enveloppé dans health@2.0-impl . Tous les appels à BatteryMonitor sont remplacés par des appels à la classe d'implémentation Health .
  • Gestionnaire de batterie . BatteryManager.queryProperty(int id) était le seul client de IBatteryPropertiesRegistrar.getProperty . IBatteryPropertiesRegistrar.getProperty a été fourni par healthd et a directement lu /sys/class/power_supply .

    Pour des raisons de sécurité, les applications ne sont pas autorisées à appeler directement Health HAL. Sous Android 9 et versions ultérieures, le service de classeur IBatteryPropertiesRegistrar est fourni par BatteryService au lieu de healthd . BatteryService délègue l’appel au Health HAL pour récupérer les informations demandées.

  • Service de batterie . Sous Android 9 et versions ultérieures, BatteryService utilise HealthServiceWrapper pour déterminer s'il convient d'utiliser l'instance de service de santé par défaut du vendor ou d'utiliser l'instance de service de santé de sauvegarde de healthd . BatteryService écoute ensuite les événements de santé via IHealth.registerCallback .

  • Stocké . Sous Android 9 et versions ultérieures, storaged utilise libhealthhalutils pour déterminer s'il convient d'utiliser l'instance de service de santé par défaut du vendor ou d'utiliser l'instance de service de santé de sauvegarde de healthd . storaged écoute ensuite les événements de santé via IHealth.registerCallback et récupère les informations de stockage.

Modifications de SELinux

Le HAL health@2.1 inclut les modifications SELinux suivantes dans la plate-forme :

  • Ajoute android.hardware.health@2.1-service à file_contexts .

Pour les appareils dotés de leur propre implémentation, certaines modifications SELinux du fournisseur peuvent être nécessaires. Exemple:

# 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 du noyau

Le démon healthd et l'implémentation par défaut android.hardware.health@2.0-impl-2.1 accèdent aux interfaces du noyau suivantes pour récupérer les informations sur la batterie :

  • /sys/class/power_supply/*/capacity_level (ajouté dans 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 (ajouté dans 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 (ajouté dans Health 2.1)
  • /sys/class/power_supply/*/type
  • /sys/class/power_supply/*/voltage_max
  • /sys/class/power_supply/*/voltage_now

Toute implémentation HAL d'intégrité spécifique à un périphérique qui utilise libbatterymonitor accède à ces interfaces du noyau par défaut, à moins qu'elle ne soit remplacée dans le constructeur de la classe d'implémentation d'intégrité.

Si ces fichiers sont manquants ou inaccessibles depuis healthd ou depuis le service par défaut (par exemple, le fichier est un lien symbolique vers un dossier spécifique au fournisseur qui refuse l'accès en raison d'une politique SELinux mal configurée), ils peuvent ne pas fonctionner correctement. Par conséquent, des modifications SELinux supplémentaires spécifiques au fournisseur peuvent être nécessaires même si l'implémentation par défaut est utilisée.

Certaines interfaces du noyau utilisées dans Health 2.1, telles que /sys/class/power_supply/*/capacity_level et /sys/class/power_supply/*/time_to_full_now , peuvent être facultatives. Cependant, pour éviter des comportements incorrects du framework résultant d'interfaces de noyau manquantes, il est recommandé de sélectionner CL 1398913 avant de créer le service d'intégrité HAL 2.1.

Essai

Android 11 inclut de nouveaux tests VTS écrits spécifiquement pour le HAL health@2.1. Si un appareil déclare health@2.1 HAL dans le manifeste de l’appareil, il doit réussir les tests VTS correspondants. Les tests sont écrits à la fois pour l'instance par défaut (pour garantir que le périphérique implémente correctement le HAL) et pour l'instance de sauvegarde (pour garantir que healthd continue de fonctionner correctement avant d'être supprimé).

Exigences en matière d'informations sur la batterie

Le HAL Health 2.0 énonce un ensemble d'exigences sur l'interface HAL, mais les tests VTS correspondants sont relativement souples quant à leur application. Dans Android 11, de nouveaux tests VTS sont ajoutés pour appliquer les exigences suivantes sur les appareils lancés avec Android 11 et versions ultérieures :

  • Les unités de courant interne et moyen de la batterie doivent être des microampères (μA).
  • Le signe du courant instantané et moyen de la batterie doit être correct. Spécifiquement:
    • courant == 0 lorsque l'état de la batterie est UNKNOWN
    • courant > 0 lorsque l'état de la batterie est CHARGING
    • courant <= 0 lorsque l'état de la batterie est NOT_CHARGING
    • courant < 0 lorsque l'état de la batterie est DISCHARGING
    • Non appliqué lorsque l'état de la batterie est FULL
  • L'état de la batterie doit être correct, qu'une source d'alimentation soit connectée ou non. Spécifiquement:
    • l'état de la batterie doit être CHARGING , NOT_CHARGING ou FULL si et seulement si une source d'alimentation est connectée ;
    • l’état de la batterie doit être DISCHARGING si et seulement si une source d’alimentation est déconnectée.

Si vous utilisez libbatterymonitor dans votre implémentation et transmettez les valeurs des interfaces du noyau, assurez-vous que les nœuds sysfs signalent des valeurs correctes :

  • Assurez-vous que le courant de la batterie est signalé avec le signe et les unités corrects. Cela inclut les nœuds sysfs suivants :
    • /sys/class/power_supply/*/current_avg
    • /sys/class/power_supply/*/current_max
    • /sys/class/power_supply/*/current_now
    • Les valeurs positives indiquent le courant entrant dans la batterie.
    • Les valeurs doivent être en microampères (μA).
  • Assurez-vous que la tension de la batterie est indiquée en microvolts (μV). Cela inclut les nœuds sysfs suivants :
    • /sys/class/power_supply/*/voltage_max
    • /sys/class/power_supply/*/voltage_now
    • Notez que l'implémentation par défaut de HAL divise voltage_now par 1 000 et rapporte les valeurs en millivolts (mV). Voir @1.0::HealthInfo .

Pour plus de détails, consultez Classe d'alimentation Linux .