Wdrażanie Health 2.1

W Androidzie 11 cały kod healthd jest poddawany refaktoryzacji na kod libhealthloop i libhealth2impl, a następnie modyfikowany w celu zaimplementowania interfejsu Health@2.1. Te 2 biblioteki są połączone statycznie za pomocą health@2.0-impl-2.1, czyli implementacji Health 2.1. Biblioteki połączone statycznie umożliwiają health@2.0-impl-2.1 wykonywanie tych samych zadań co healthd, takich jak uruchamianie healthd_mainloop i przeprowadzanie ankiet. W init health@2.1-service rejestruje implementację interfejsu IHealthhwservicemanager. Podczas aktualizacji urządzeń z obrazu dostawcy z Androidem 8.x lub 9 i platformy Android 11 obraz dostawcy może nie udostępniać usługi health@2.1. Zgodność wsteczna ze starymi obrazami dostawców jest wymuszana przez harmonogram wycofywania.

Aby zapewnić zgodność wsteczną:

  1. healthd rejestruje IHealth w hwservicemanager, mimo że jest demonem systemowym. Plik IHealth zostanie dodany do pliku manifestu systemu z nazwą instancji „backup”.
  2. Framework i storaged komunikują się z healthd przez hwbinder zamiast przez binder.
  3. Kod frameworka i storaged został zmieniony, aby pobierać instancję „default”, jeśli jest dostępna, a potem „backup”.
    • Kod klienta C++ korzysta z logiki zdefiniowanej w pliku libhealthhalutils.
    • Kod klienta w języku Java korzysta z logiki zdefiniowanej w pliku HealthServiceWrapper.
  4. Gdy IHealth/domyślne będzie powszechnie dostępne, a obrazy dostawcy Androida 8.1 zostaną wycofane, można wycofać IHealth/domyślne i healthd. Więcej informacji znajdziesz w artykule Wycofanie obsługi interfejsu Health@1.0.

Zmienne kompilacji dotyczące healthd związane z poszczególnymi płytami

BOARD_PERIODIC_CHORES_INTERVAL_* to zmienne specyficzne dla tablicy, używane do tworzenia healthd. W ramach podziału kompilacji systemu/dostawcy nie można definiować wartości specyficznych dla płyty w przypadku modułów systemowych. Te wartości były zastępowane w wycofanej funkcji healthd_board_init.

W Health@2.1 dostawcy mogą zastąpić te 2 okresowe wartości interwałów zadań w strukturze healthd_config przed przekazaniem ich do konstruktora klas implementacji stanu zdrowia. Klasa implementacji kontroli stanu powinna dziedziczyć z android::hardware::health::V2_1::implementation::Health.

Wdrażanie usługi Health 2.1

Informacje o wdrażaniu usługi Health 2.1 znajdziesz w pliku hardware/interfaces/health/2.1/README.md.

Klienci ochrony zdrowia

Health@2.x ma tych klientów:

  • ładowarka. Korzystanie z kodu libbatterymonitorhealthd_common jest zapisane w elementach health@2.0-impl.
  • recovery. Połączenie z usługą libbatterymonitor jest zawartym w health@2.0-impl. Wszystkie wywołania BatteryMonitor są zastępowane wywołaniami klasy implementacji Health.
  • BatteryManager BatteryManager.queryProperty(int id) był jedynym klientem usługi IBatteryPropertiesRegistrar.getProperty. IBatteryPropertiesRegistrar.getProperty został przesłany przez healthd i bezpośrednio odczytany przez /sys/class/power_supply.

    Ze względów bezpieczeństwa aplikacje nie mogą bezpośrednio wywoływać HAL. W Androidzie 9 i nowszych usługa binder IBatteryPropertiesRegistrar jest dostarczana przez BatteryService, a nie healthd. BatteryService przekazuje wywołanie do HALa odpowiedzialnego za zdrowie, aby pobrać żądane informacje.

  • BatteryService. W Androidzie 9 i nowszych BatteryService używa HealthServiceWrapper, aby określić, czy użyć domyślnej instancji usługi zdrowotnej z vendor, czy zapasowej instancji usługi zdrowotnej z healthd. Następnie BatteryService nasłuchuje zdarzeń dotyczących stanu za pomocą IHealth.registerCallback.

  • Storaged. W Androidzie 9 i nowszych storaged używa libhealthhalutils, aby określić, czy użyć domyślnej instancji usługi zdrowotnej z vendor, czy zapasowej instancji usługi zdrowotnej z healthd. storaged następnie nasłuchuje zdarzeń związanych ze stanem za pomocą IHealth.registerCallback i pobiera informacje o magazynie.

Zmiany w SELinux

Interfejs HAL health@2.1 zawiera te zmiany w SELinux na platformie:

  • Dodaje android.hardware.health@2.1-service do file_contexts.

W przypadku urządzeń z własną implementacją mogą być konieczne pewne zmiany dostawcy w SELinux. Przykład:

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

Interfejsy jądra systemu

Demon healthd i domyślna implementacja android.hardware.health@2.0-impl-2.1 mają dostęp do tych interfejsów jądra, aby pobierać informacje o baterii:

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

Każda implementacja HAL dotycząca konkretnego urządzenia, która korzysta z interfejsu libbatterymonitor, domyślnie uzyskuje dostęp do tych interfejsów jądra, chyba że zostanie zastąpiona w konstruktorze klas implementacji stanu.

Jeśli nie ma tych plików lub są one niedostępne z poziomu healthd lub usługi domyślnej (np. plik jest linkiem symbolicznym do folderu konkretnego dostawcy, który odmawia dostępu z powodu błędnie skonfigurowanej zasady SELinux), mogą one nie działać prawidłowo. Dlatego nawet przy użyciu domyślnej implementacji mogą być konieczne dodatkowe zmiany SELinux specyficzne dla danego dostawcy.

Niektóre interfejsy jądra używane w Health 2.1, takie jak /sys/class/power_supply/*/capacity_level/sys/class/power_supply/*/time_to_full_now, mogą być opcjonalne. Aby jednak zapobiec nieprawidłowemu działaniu frameworku spowodowanemu przez brakujące interfejsy jądra, przed utworzeniem usługi Health HAL 2.1 zalecamy wybranie tylko tych zmian, które są potrzebne z CL 1398913.

Testowanie

Android 11 zawiera nowe testy VTS napisane specjalnie pod kątem Health@2.1 HAL. Jeśli w manifeście urządzenia jest zadeklarowany interfejs HAL health@2.1, urządzenie musi przejść odpowiednie testy VTS. Testy są pisane zarówno dla wystąpienia domyślnego (aby upewnić się, że urządzenie prawidłowo implementuje interfejs HAL), jak i dla wystąpienia zapasowego (aby upewnić się, że healthd nadal działa prawidłowo przed usunięciem).

Wymagania dotyczące informacji o baterii

Interfejs HAL Health 2.0 określa zestaw wymagań dotyczących interfejsu HAL, ale odpowiednie testy VTS są stosunkowo łagodne w swoim działaniu. W Androidzie 11 dodaliśmy nowe testy VTS, aby egzekwować te wymagania na urządzeniach z Androidem 11 i nowszym:

  • Jednostki chwilowego i średniego prądu baterii muszą być podawane w mikroamperach (μA).
  • Symbol chwilowego i średniego prądu baterii musi być prawidłowy. W szczególności:
    • bieżący == 0, gdy stan baterii to UNKNOWN
    • prąd: > 0, gdy stan baterii to CHARGING
    • current <= 0, gdy stan baterii to NOT_CHARGING
    • current < 0, gdy stan baterii to DISCHARGING
    • Nieegzekwowana, gdy stan baterii to FULL
  • Stan baterii musi być zgodny z tym, czy źródło zasilania jest podłączone. W szczególności:
    • stan baterii musi być CHARGING, NOT_CHARGING lub FULL, jeśli i tylko jeśli jest podłączone źródło zasilania;
    • Stan baterii musi być DISCHARGING, jeśli i tylko jeśli źródło zasilania jest odłączone.

Jeśli w swojej implementacji używasz interfejsu libbatterymonitor i przekazujesz wartości z interfejsów jądra, upewnij się, że węzły sysfs podają prawidłowe wartości:

  • Upewnij się, że poziom naładowania baterii jest podawany z prawidłowym oznaczeniem i odpowiednimi jednostkami. Obejmuje to te węzły sysfs:
    • /sys/class/power_supply/*/current_avg
    • /sys/class/power_supply/*/current_max
    • /sys/class/power_supply/*/current_now
    • Wartości dodatnie wskazują na napływający prąd do baterii.
    • Wartości powinny być podawane w mikroamperach (μA).
  • Sprawdź, czy napięcie baterii jest podane w mikrowoltach (μV). Dotyczy to tych węzłów sysfs:
    • /sys/class/power_supply/*/voltage_max
    • /sys/class/power_supply/*/voltage_now
    • Pamiętaj, że domyślna implementacja HAL dzieli wartość voltage_now przez 1000 i podaje wartości w miliwoltach (mV). Zobacz @1.0::HealthInfo.

Więcej informacji znajdziesz na stronie klasa zasilacza Linux.