Sensors Multi-HAL to platforma, która umożliwia działanie interfejsów HAL czujników obok innych interfejsów HAL czujników. Warstwa Sensors Multi-HAL dynamicznie wczytuje podwarstwy HAL czujników przechowywane jako biblioteki dynamiczne w partycji dostawcy i przekazuje im obiekt wywołania zwrotnego, który może obsługiwać publikowanie zdarzeń oraz uzyskiwanie i zwalnianie blokady uśpienia. Pod-HAL czujników to HAL czujników wbudowany w obiekt współdzielony na partycji dostawcy, który jest używany przez platformę multi-HAL. Te podmoduły HAL nie są od siebie zależne ani od kodu multi-HAL, który zawiera główną funkcję procesu.
Sensors Multi-HAL 2.1, dostępny na urządzeniach z Androidem 11 lub nowszym, to kolejna wersja Sensors Multi-HAL 2.0, która obsługuje ładowanie podmodułów HAL, które mogą udostępniać typ czujnika kąta zawiasu. Aby obsługiwać ten typ czujnika, podrzędne HAL-e muszą korzystać z interfejsów API podrzędnych HAL-i zdefiniowanych w nagłówku 2.1 SubHal.
W przypadku urządzeń z Androidem 13 lub nowszym, które korzystają z interfejsu HAL AIDL czujników, możesz użyć warstwy pośredniej multi-HAL, aby włączyć obsługę wielu interfejsów HAL. Szczegółowe informacje o wdrażaniu znajdziesz w artykule Korzystanie z wielu interfejsów HAL czujników z interfejsem AIDL HAL czujników.
Różnica między Sensors Multi-HAL 2 a Sensors HAL 2
Sensors Multi-HAL 2, dostępny na urządzeniach z Androidem 10 lub nowszym, wprowadza kilka abstrakcji na Sensors HAL 2, aby ułatwić interakcję z interfejsami API HAL. Wielokrotny interfejs HAL czujników 2 wprowadza klasę HalProxy, która obsługuje implementację interfejsu HAL czujników 2, oraz interfejs V2_1/SubHal (lub V2_0/SubHal), który umożliwia interakcję HalProxy z podrzędnymi interfejsami HAL.
Interfejs ISensorsSubHal różni się od interfejsu 2.1/ISensors.hal (lub 2.0/ISensors.hal) w tych aspektach:
- Metoda initialize przekazuje
IHalProxyCallbackklasę zamiast dwóch FMQ iISensorsCallback. - Podmoduły HAL muszą implementować funkcję debugowania, która dostarcza informacji na potrzeby debugowania w raportach o błędach.
- Podmoduły HAL muszą implementować funkcję nazwy, aby załadowany podmoduł HAL można było odróżnić od innych podmodułów HAL.
Główna różnica między Sensors Multi-HAL 2 a Sensors HAL 2 polega na funkcjach inicjowania. Zamiast FMQ interfejs IHalProxyCallback
udostępnia 2 metody: jedną do wysyłania zdarzeń z czujników do platformy czujników i jedną do tworzenia blokad wybudzania. W tle warstwa Sensors Multi-HAL zarządza wszystkimi interakcjami z kolejkami FMQ, aby zapewnić terminowe dostarczanie zdarzeń z czujników do wszystkich podwarstw HAL. Zdecydowanie zalecamy, aby podrzędne HAL-e używały metody createScopedWakelock do przekazywania obciążenia związanego z przekroczeniem limitu czasu blokad uśpienia do Sensors Multi-HAL i centralizowania użycia blokad uśpienia w jednej wspólnej blokadzie uśpienia dla całego Sensors Multi-HAL, co minimalizuje wywołania blokowania i odblokowywania.
Sensors Multi-HAL 2 ma też wbudowane funkcje bezpieczeństwa. Obsługuje sytuacje, w których kolejka FMQ czujnika jest pełna lub gdy framework czujnika Androida uruchamia się ponownie i stan czujnika musi zostać zresetowany. Dodatkowo, gdy zdarzenia są wysyłane do klasy HalProxy, ale platforma czujników nie może ich od razu zaakceptować, interfejs Sensors Multi-HAL może przenieść zdarzenia do wątku w tle, aby umożliwić dalszą pracę we wszystkich podinterfejsach HAL podczas oczekiwania na wysłanie zdarzeń.
Kod źródłowy i implementacja referencyjna
Cały kod Multi-HAL czujników jest dostępny w hardware/interfaces/sensors/common/default/2.X/multihal/.
Oto linki do niektórych materiałów.
HalProxy.h: obiektHalProxyjest tworzony przez interfejs HAL czujników i odpowiada za przekazywanie danych z podrzędnych interfejsów HAL do platformy czujników.HalProxy.cpp: implementacjaHalProxyzawiera całą logikę potrzebną do multipleksowania komunikacji między podrzędnymi warstwami HAL a platformą czujników.SubHal.h: interfejsISensorsSubHalokreśla interfejs, którego podrzędne HAL-e muszą przestrzegać, aby były zgodne zHalProxy. Pod-HAL implementuje metodę initialize, dzięki czemu obiektHalProxyCallbackmoże być używany w przypadkupostEventsicreateScopedWakelock.W przypadku implementacji Multi-HAL 2.0 użyj wersji 2.0 pliku
SubHal.h.hardware/interfaces/sensors/common/default/2.X/multihal/tests/: te testy jednostkowe weryfikują implementacjęHalProxy.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/: Ta przykładowa implementacja podrzędnego HAL-u używa fałszywych czujników do generowania fałszywych danych. Przydatne do testowania interakcji wielu podwarstw HAL na urządzeniu.
Implementacja
W tej sekcji opisano, jak wdrożyć interfejs Sensors Multi-HAL w tych sytuacjach:
- Korzystanie z wielu interfejsów HAL czujników z interfejsem AIDL HAL czujników
- Wdrażanie interfejsu HAL czujników w wersji 2.1
- Przenoszenie z wielu interfejsów HAL czujników 2.0 na wiele interfejsów HAL 2.1
- Przenoszenie z Sensors HAL 2.0
- Przenoszenie z Sensors HAL 1.0
- Przenoszenie danych z wielu interfejsów HAL czujników w wersji 1.0
Używanie interfejsu Sensors Multi-HAL z interfejsem Sensors AIDL HAL
Aby umożliwić obsługę wielu HAL w przypadku interfejsu AIDL HAL czujników, zaimportuj moduł warstwy pośredniej AIDL Multi-HAL, który znajduje się w folderze hardware/interfaces/sensors/aidl/default/multihal/. Moduł obsługuje konwersję między typami definicji AIDL i HIDL interfejsu HAL czujników oraz definiuje otokę interfejsu multi-HAL opisanego w artykule Implementowanie interfejsu multi-HAL 2.1 czujników. Warstwa pośrednia AIDL multi-HAL jest zgodna z urządzeniami, które implementują Sensors Multi-HAL 2.1.
Warstwa shim AIDL multi-HAL umożliwia udostępnianie typów czujników śledzenia ruchów głowy i IMU o ograniczonej liczbie osi w AIDL HAL czujników. Aby używać tych typów czujników zdefiniowanych przez interfejs AIDL HAL, ustaw pole type w strukturze SensorInfo w implementacji getSensorsList_2_1(). Jest to bezpieczne, ponieważ pola typu czujnika oparte na liczbach całkowitych w przypadku interfejsów AIDL i HIDL w warstwie HAL czujników nie nakładają się na siebie.
Implementacja Sensors Multi-HAL 2.1
Aby wdrożyć Sensors Multi-HAL 2.1 na nowym urządzeniu, wykonaj te czynności:
- Zaimplementuj interfejs
ISensorsSubHalw sposób opisany wSubHal.h. - Zaimplementuj metodę
sensorsHalGetSubHal_2_1wSubHal.h. Dodaj
cc_library_shared, aby utworzyć nowo wdrożony podsystem HAL. Podczas dodawania miejsca docelowego:- Upewnij się, że element docelowy jest umieszczony w jakimś miejscu na partycji dostawcy urządzenia.
- W pliku konfiguracji znajdującym się w lokalizacji
/vendor/etc/sensors/hals.confdodaj ścieżkę do biblioteki w nowym wierszu. W razie potrzeby utwórz plikhals.conf.
Przykład wpisu
Android.bpdotyczącego tworzenia biblioteki podrzędnej HAL znajdziesz w sekcjihardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp.Usuń wszystkie wpisy
android.hardware.sensorsz plikumanifest.xml, który zawiera listę obsługiwanych na urządzeniu interfejsów HAL.Usuń wszystkie pliki
android.hardware.sensorsiservice.rcz plikudevice.mki dodajandroid.hardware.sensors@2.1-service.multihalorazandroid.hardware.sensors@2.1-service.multihal.rcdoPRODUCT_PACKAGES.
Podczas uruchamiania HalProxy rozpoczyna działanie, wyszukuje nowo wdrożony podsystem HAL i inicjuje go, wywołując sensorsHalGetSubHal_2_1.
Przenoszenie portu z wielu interfejsów HAL czujników 2.0 do wielu interfejsów HAL 2.1
Aby przenieść Multi-HAL z wersji 2.0 do 2.1, zaimplementuj interfejs SubHal i ponownie skompiluj podrzędny HAL.
Oto różnice między interfejsami 2.0 i 2.1 SubHal:
IHalProxyCallbackkorzysta z typów utworzonych w wersji 2.1 specyfikacjiISensors.hal.- Funkcja
initialize()przekazuje nowy obiektIHalProxyCallbackzamiast obiektu z interfejsu 2.0SubHal. - Podrzędne HAL-e muszą implementować
getSensorsList_2_1iinjectSensorData_2_1zamiastgetSensorsListiinjectSensorData, ponieważ te metody korzystają z nowych typów dodanych w wersji 2.1 specyfikacjiISensors.hal. - Podmoduły HAL muszą udostępniać
sensorsHalGetSubHal_2_1zamiastsensorsHalGetSubHal, aby moduł Multi-HAL traktował je jako podmoduły HAL w wersji 2.1.
Port z interfejsu HAL czujników 2.0
Podczas uaktualniania do Sensors Multi-HAL 2.0 z Sensors HAL 2.0 upewnij się, że implementacja HAL spełnia te wymagania.
Inicjowanie HAL
Interfejs HAL czujników 2.0 ma funkcję inicjowania, która umożliwia usłudze czujników przekazywanie kolejek FMQ i dynamicznego wywołania zwrotnego czujnika. W interfejsie Sensors Multi-HAL 2.0 funkcja
initialize() przekazuje pojedyncze wywołanie zwrotne, które musi być używane do publikowania zdarzeń czujnika, uzyskiwania blokad wybudzania i powiadamiania o połączeniach i rozłączeniach czujników dynamicznych.
Przesyłanie zdarzeń z czujników do implementacji Multi-HAL
Zamiast publikować zdarzenia czujnika za pomocą FMQ, podrzędny HAL musi zapisywać zdarzenia czujnika w IHalProxyCallback, gdy są one dostępne.
Zdarzenia WAKE_UP
W interfejsie HAL czujników 2.0 interfejs HAL może zarządzać blokadą uśpienia w ramach swojej implementacji. W interfejsie Sensors Multi-HAL 2.0 podrzędne interfejsy HAL umożliwiają implementacji Multi-HAL zarządzanie blokadami uśpienia i mogą żądać uzyskania blokady uśpienia przez wywołanie funkcji createScopedWakelock.
Zablokowana blokada uśpienia o ograniczonym zakresie musi zostać uzyskana i przekazana do postEvents podczas publikowania zdarzeń wybudzania w implementacji Multi-HAL.
Czujniki dynamiczne
Wymagania dotyczące interfejsu Sensors Multi-HAL 2.0 mówią, że funkcje onDynamicSensorsConnected i onDynamicSensorsDisconnected w IHalProxyCallback muszą być wywoływane za każdym razem, gdy zmieniają się połączenia czujników dynamicznych. Te wywołania zwrotne są dostępne w ramach wskaźnika IHalProxyCallback, który jest udostępniany przez funkcję initialize().
Port z interfejsu HAL czujników 1.0
Podczas uaktualniania z Sensors HAL 1.0 do Sensors Multi-HAL 2.0 upewnij się, że implementacja HAL spełnia te wymagania.
Inicjowanie HAL
Funkcja initialize() musi być obsługiwana, aby można było ustanowić wywołanie zwrotne między podrzędnym HAL-em a implementacją Multi-HAL.
Udostępnianie dostępnych czujników
W przypadku interfejsu Sensors Multi-HAL 2.0 funkcja getSensorsList() musi zwracać tę samą wartość podczas jednego uruchomienia urządzenia, nawet po ponownym uruchomieniu interfejsu HAL czujników. Umożliwia to frameworkowi podejmowanie prób ponownego nawiązania połączeń z czujnikami w przypadku ponownego uruchomienia serwera systemowego. Wartość zwracana przez getSensorsList() może się zmienić po ponownym uruchomieniu urządzenia.
Przesyłanie zdarzeń z czujników do implementacji Multi-HAL
W przypadku Sensors HAL 2.0 podrzędny HAL nie czeka na wywołanie funkcji poll(), ale aktywnie zapisuje zdarzenia czujnika w IHalProxyCallback, gdy tylko są dostępne.
Zdarzenia WAKE_UP
W przypadku interfejsu HAL czujników w wersji 1.0 interfejs HAL może zarządzać blokadą uśpienia w ramach swojej implementacji. W interfejsie Sensors Multi-HAL 2.0 podrzędne interfejsy HAL umożliwiają implementacji Multi-HAL zarządzanie blokadami uśpienia i mogą żądać uzyskania blokady uśpienia przez wywołanie funkcji createScopedWakelock.
Zablokowana blokada uśpienia o ograniczonym zakresie musi zostać uzyskana i przekazana do postEvents podczas publikowania zdarzeń wybudzania w implementacji Multi-HAL.
Czujniki dynamiczne
W komponencie HAL czujników w wersji 1.0 czujniki dynamiczne są zwracane przez funkcję poll().
Wymagania dotyczące interfejsu Sensors Multi-HAL 2.0 mówią, że funkcje onDynamicSensorsConnected i onDynamicSensorsDisconnected w IHalProxyCallback muszą być wywoływane za każdym razem, gdy zmieniają się połączenia czujników dynamicznych. Te wywołania zwrotne są dostępne w ramach wskaźnika IHalProxyCallback, który jest udostępniany przez funkcję initialize().
Port z Sensors Multi-HAL 1.0
Aby przenieść istniejącą implementację z Sensors Multi-HAL 1.0, wykonaj te czynności.
- Sprawdź, czy konfiguracja HAL czujników znajduje się w lokalizacji
/vendor/etc/sensors/hals.conf. Może to obejmować przeniesienie pliku znajdującego się w lokalizacji/system/etc/sensors/hals.conf. - Usuń wszelkie odwołania do
hardware/hardware.hihardware/sensors.h, ponieważ nie są one obsługiwane w przypadku HAL 2.0. - Przenieś podmoduły HAL zgodnie z opisem w sekcji Przenoszenie z modułu HAL czujników w wersji 1.0.
- Ustaw Sensors Multi-HAL 2.0 jako wyznaczony HAL, wykonując kroki 3 i 4 w sekcji Wdrażanie Sensors Multi-HAL 2.0.
Weryfikacja
Uruchamianie VTS
Po zintegrowaniu co najmniej jednego podmodułu HAL z interfejsem Sensors Multi-Hal 2.1 użyj zestawu testów dostawcy (VTS), aby sprawdzić, czy implementacje podmodułu HAL spełniają wszystkie wymagania interfejsu Sensors HAL.
Aby uruchomić tylko testy VTS czujników, gdy VTS jest skonfigurowany na komputerze hosta, wykonaj te polecenia:
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsHalSensorsV2_0Target && \
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsHalSensorsV2_1Target
Jeśli używasz warstwy shim AIDL Multi-HAL, uruchom VtsAidlHalSensorsTargetTest.
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsAidlHalSensorsTargetTest
Przeprowadzanie testów jednostkowych
Testy jednostkowe w HalProxy_test.cpp testują HalProxy za pomocą fałszywych podmodułów HAL, które są tworzone w teście jednostkowym i nie są ładowane dynamicznie. Podczas tworzenia nowego podrzędnego HAL te testy powinny służyć jako wskazówki dotyczące dodawania testów jednostkowych, które weryfikują, czy nowy podrzędny HAL jest prawidłowo zaimplementowany.
Aby uruchomić testy, wpisz te polecenia:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/testsatest
Testowanie za pomocą fałszywych podmodułów HAL
Fałszywe podmoduły HAL to przykładowe implementacje interfejsu ISensorsSubHal.
Podwarstwy HAL udostępniają różne listy czujników. Gdy czujniki są aktywne, okresowo wysyłają automatycznie generowane zdarzenia czujników do HalProxy
na podstawie interwałów określonych w danym żądaniu czujnika.
Fałszywe podmoduły HAL mogą służyć do testowania, jak pełny kod Multi-HAL działa z innymi podmodułami HAL załadowanymi do systemu, oraz do sprawdzania różnych aspektów kodu Multi-HAL czujników.
2 fałszywe podrzędne HAL-e są dostępne pod adresem hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/.
Aby skompilować i przesłać fałszywe podmoduły HAL na urządzenie, wykonaj te czynności:
Uruchom te polecenia, aby utworzyć i przenieść na urządzenie 3 różne fałszywe podwarstwy HAL:
$ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests/mmaadb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.soadb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.soadb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.soZaktualizuj konfigurację HAL czujników w
/vendor/etc/sensors/hals.conf, podając ścieżki do fałszywych podmodułów HAL./vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.soUruchom ponownie
HalProxyi wczytaj nowe podmoduły HAL wymienione w konfiguracji.adb shell stopadb shell start
Debugowanie
Programiści mogą debugować platformę za pomocą polecenia lshal. Aby poprosić o dane wyjściowe debugowania HAL czujników, uruchom to polecenie:
adb rootadb shell lshal debug android.hardware.sensors@2.1::ISensors/default
Informacje o bieżącym stanie HalProxy i jego podmodułów HAL są następnie wyświetlane w terminalu. Poniżej znajdziesz przykład wyniku polecenia dla obiektu HalProxy i fałszywych podmodułów HAL.
Internal values:
Threads are running: true
Wakelock timeout start time: 200 ms ago
Wakelock timeout reset time: 73208 ms ago
Wakelock ref count: 0
# of events on pending write queue: 0
# of non-dynamic sensors across all subhals: 8
# of dynamic sensors across all subhals: 0
SubHals (2):
Name: FakeSubHal-OnChange
Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
Name: FakeSubHal-OnChange
Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
Jeśli liczba podana w przypadku # of events on pending write queue jest duża (1000 lub więcej), oznacza to, że do zapisu w ramach platformy czujników oczekuje wiele zdarzeń. Oznacza to, że usługa czujnika jest zablokowana lub uległa awarii i nie przetwarza zdarzeń z czujnika albo że z podrzędnej warstwy HAL niedawno przesłano dużą partię zdarzeń z czujnika.
Jeśli liczba odwołań do blokady uśpienia jest większa niż 0, oznacza to, że HalProxy uzyskał blokadę uśpienia. Wartość ta powinna być większa od 0 tylko wtedy, gdy celowo wstrzymywane jest wysyłanie wartości ScopedWakelock lub gdy zdarzenia wybudzania zostały wysłane do HalProxy i nie zostały jeszcze przetworzone przez platformę czujników.
Deskryptor pliku przekazywany do metody debugowania interfejsu HalProxy jest przekazywany do każdego podsystemu HAL, więc deweloperzy muszą zaimplementować metodę debugowania w ramach interfejsu ISensorsSubHal.