Implement Health 2.1

In Android 11 wird der gesamte healthd-Code in libhealthloop und libhealth2impl umgeschrieben und dann so geändert, dass die HAL von health@2.1 implementiert wird. Diese beiden Bibliotheken sind statisch über health@2.0-impl-2.1 verknüpft, die Passthrough-Implementierung von Health 2.1. Durch die statisch verknüpften Bibliotheken kann health@2.0-impl-2.1 dieselben Aufgaben wie healthd ausführen, z. B. healthd_mainloop ausführen und abfragen. In init registriert health@2.1-service eine Implementierung der Schnittstelle IHealth bei hwservicemanager. Beim Upgrade von Geräten mit einem Anbieter-Image von Android 8.x oder 9 und einem Android 11-Framework wird der Dienst „health@2.1“ möglicherweise nicht vom Anbieter-Image bereitgestellt. Die Abwärtskompatibilität mit alten Anbieter-Images wird durch den Einstellungszeitplan erzwungen.

So sorgen Sie für Abwärtskompatibilität:

  1. healthd registriert IHealth bei hwservicemanager, obwohl es sich um einen System-Daemon handelt. IHealth wird dem Systemmanifest mit dem Instanznamen „backup“ hinzugefügt.
  2. Das Framework und storaged kommunizieren mit healthd über hwbinder anstelle von binder.
  3. Der Code für „framework“ und storaged wird geändert, um die Instanz „default“ abzurufen, falls verfügbar, und dann „backup“.
    • Der C++-Clientcode verwendet die in libhealthhalutils definierte Logik.
    • Der Java-Clientcode verwendet die in HealthServiceWrapper definierte Logik.
  4. Sobald IHealth/default allgemein verfügbar ist und Android 8.1-Anbieterbilder eingestellt werden, können IHealth/backup und healthd eingestellt werden. Weitere Informationen finden Sie unter Einstellung von „health@1.0“.

Boardspezifische Buildvariablen für healthd

BOARD_PERIODIC_CHORES_INTERVAL_* sind plattformspezifische Variablen, die zum Erstellen von healthd verwendet werden. Im Rahmen der Aufteilung in System- und Anbieterbuilds können für Systemmodule keine plattformspezifischen Werte definiert werden. Diese Werte wurden früher in der veralteten Funktion healthd_board_init überschrieben.

In health@2.1 können Anbieter diese beiden Intervallwerte für regelmäßige Aufgaben im healthd_config-Typ überschreiben, bevor sie an den Konstruktor der Health-Implementierungsklasse übergeben werden. Die Klasse für die Dienstbereitschaftsimplementierung muss von android::hardware::health::V2_1::implementation::Health abgeleitet sein.

Health 2.1-Dienst implementieren

Informationen zur Implementierung des Health 2.1-Dienstes finden Sie unter hardware/interfaces/health/2.1/README.md.

Gesundheitskundschaft

Health@2.x hat die folgenden Clients:

  • Ladegerät Die Verwendung von libbatterymonitor- und healthd_common-Code ist in health@2.0-impl eingehüllt.
  • recovery. Die Verknüpfung mit libbatterymonitor ist in health@2.0-impl verpackt. Alle Aufrufe von BatteryMonitor werden durch Aufrufe der Implementierungsklasse Health ersetzt.
  • BatteryManager BatteryManager.queryProperty(int id) war der einzige Client von IBatteryPropertiesRegistrar.getProperty. IBatteryPropertiesRegistrar.getProperty wurde von healthd bereitgestellt und /sys/class/power_supply wurde direkt gelesen.

    Aus Sicherheitsgründen dürfen Apps die HAL für Gesundheit nicht direkt aufrufen. Unter Android 9 und höher wird der Binderdienst IBatteryPropertiesRegistrar von BatteryService anstelle von healthd bereitgestellt. BatteryService delegiert den Aufruf an die Health HAL, um die angeforderten Informationen abzurufen.

  • BatteryService Unter Android 9 und höher verwendet BatteryService HealthServiceWrapper, um zu bestimmen, ob die Standard-Systemdiagnoseinstanz von vendor oder die Sicherungs-Systemdiagnoseinstanz von healthd verwendet werden soll. BatteryService wartet dann über IHealth.registerCallback auf Gesundheitsereignisse.

  • Storaged Unter Android 9 und höher verwendet storaged libhealthhalutils, um zu ermitteln, ob die Standard-Systemdiagnoseinstanz von vendor oder die Sicherungs-Systemdiagnoseinstanz von healthd verwendet werden soll. Anschließend wartet storaged über IHealth.registerCallback auf Systemereignisse und ruft Speicherinformationen ab.

SELinux-Änderungen

Der HAL für health@2.1 enthält die folgenden SELinux-Änderungen an der Plattform:

  • android.hardware.health@2.1-service wird zu file_contexts hinzugefügt.

Bei Geräten mit eigener Implementierung sind möglicherweise einige SELinux-Änderungen des Anbieters erforderlich. Beispiel:

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

Kernel-Schnittstellen

Der healthd-Daemon und die Standardimplementierung android.hardware.health@2.0-impl-2.1 greifen auf die folgenden Kernel-Schnittstellen zu, um Akkuinformationen abzurufen:

  • /sys/class/power_supply/*/capacity_level (in Google Fit 2.1 hinzugefügt)
  • /sys/class/power_supply/*/capacity
  • /sys/class/power_supply/*/charge_counter
  • /sys/class/power_supply/*/charge_full
  • /sys/class/power_supply/*/charge_full_design (in Health 2.1 hinzugefügt)
  • /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 (in Google Fit 2.1 hinzugefügt)
  • /sys/class/power_supply/*/type
  • /sys/class/power_supply/*/voltage_max
  • /sys/class/power_supply/*/voltage_now

Jede gerätespezifische HAL-Implementierung für den Gesundheitsstatus, die libbatterymonitor verwendet, greift standardmäßig auf diese Kernel-Schnittstellen zu, sofern dies nicht im Konstruktor der Health-Implementierungsklasse überschrieben wird.

Wenn diese Dateien fehlen oder über healthd oder den Standarddienst nicht zugänglich sind (z. B. ist die Datei ein Symlink zu einem anbieterspezifischen Ordner, der den Zugriff aufgrund einer falsch konfigurierten SELinux-Richtlinie verweigert), funktionieren sie möglicherweise nicht richtig. Daher sind möglicherweise zusätzliche anbieterspezifische SELinux-Änderungen erforderlich, auch wenn die Standardimplementierung verwendet wird.

Einige in Health 2.1 verwendete Kernel-Schnittstellen wie /sys/class/power_supply/*/capacity_level und /sys/class/power_supply/*/time_to_full_now sind möglicherweise optional. Um jedoch falsches Framework-Verhalten aufgrund fehlender Kernel-Schnittstellen zu vermeiden, wird empfohlen, CL 1398913 auszuwählen, bevor Sie den Health HAL 2.1-Dienst erstellen.

Testen

Android 11 enthält neue VTS-Tests, die speziell für die HAL von health@2.1 entwickelt wurden. Wenn ein Gerät im Gerätemanifest die HAL „health@2.1“ deklariert, muss es die entsprechenden VTS-Tests bestehen. Tests werden sowohl für die Standardinstanz als auch für die Sicherungsinstanz geschrieben, um sicherzustellen, dass das Gerät den HAL korrekt implementiert. So wird sichergestellt, dass healthd vor dem Entfernen weiterhin korrekt funktioniert.

Anforderungen an Akkuinformationen

Die Health 2.0 HAL enthält eine Reihe von Anforderungen an die HAL-Schnittstelle, die entsprechenden VTS-Tests sind jedoch relativ locker bei der Durchsetzung dieser Anforderungen. In Android 11 wurden neue VTS-Tests hinzugefügt, um die folgenden Anforderungen auf Geräten durchzusetzen, die mit Android 11 und höher auf den Markt gebracht werden:

  • Die Einheiten für den momentanen und den durchschnittlichen Akkustrom müssen Mikroampere (μA) sein.
  • Das Vorzeichen des momentanen und durchschnittlichen Akkustroms muss korrekt sein. Im Detail:
    • current == 0, wenn der Akkustand UNKNOWN ist
    • current > 0, wenn der Akkustatus CHARGING ist
    • current <= 0, wenn der Akkustand NOT_CHARGING ist
    • current < 0, wenn der Akkustand DISCHARGING ist
    • Nicht erzwungen, wenn der Akkustand FULL ist
  • Der Akkustatus muss korrekt sein, unabhängig davon, ob eine Stromquelle angeschlossen ist. Im Detail:
    • Der Akkustatus muss CHARGING, NOT_CHARGING oder FULL sein, wenn und nur wenn eine Stromquelle angeschlossen ist.
    • Der Akkustatus muss DISCHARGING sein, wenn die Stromversorgung getrennt ist.

Wenn Sie libbatterymonitor in Ihrer Implementierung verwenden und Werte von Kernel-Schnittstellen weitergeben, achten Sie darauf, dass die sysfs-Knoten die richtigen Werte melden:

  • Achten Sie darauf, dass der Akkustrom mit dem richtigen Vorzeichen und den richtigen Einheiten angegeben wird. Dazu gehören die folgenden Sysfs-Knoten:
    • /sys/class/power_supply/*/current_avg
    • /sys/class/power_supply/*/current_max
    • /sys/class/power_supply/*/current_now
    • Positive Werte geben den Strom an, der in den Akku fließt.
    • Die Werte sollten in Mikroampere (μA) angegeben werden.
  • Die Batteriespannung muss in Mikrovolt (μV) angegeben werden. Dazu gehören die folgenden sysfs-Knoten:
    • /sys/class/power_supply/*/voltage_max
    • /sys/class/power_supply/*/voltage_now
    • Beachten Sie, dass die Standard-HAL-Implementierung voltage_now durch 1.000 teilt und Werte in Millivolt (mV) anzeigt. Siehe @1.0::HealthInfo.

Weitere Informationen finden Sie unter Linux-Netzteilklasse.