Multi-HAL czujników to platforma, która umożliwia uruchamianie interfejsów HAL czujników obok innych interfejsów HAL czujników. Interfejs Sensors Multi-HAL wczytuje dynamicznie podinterfejsy czujników przechowywane jako dynamiczne biblioteki w partycji dostawcy i przekazuje im obiekt wywołania zwrotnego, który może obsługiwać publikowanie zdarzeń oraz uzyskiwanie i zwalnianie blokady aktywacji. Podsystem HAL czujników to interfejs HAL czujników wbudowany w wspólny obiekt w partycji dostawcy, który jest używany przez wielopoziomową platformę HAL. Te podrzędne HAL-e nie zależą od siebie nawzajem ani od kodu wielopoziomowego HAL, który zawiera główną funkcję procesu.
Interfejs Sensors Multi-HAL 2.1, dostępny na urządzeniach z Androidem 11 lub nowszym, to wersja interfejsu Sensors Multi-HAL 2.0, która obsługuje wczytywanie podinterfejsów HAL, które mogą udostępniać typ czujnika kąt zawiasu. Aby obsługiwać ten typ czujnika, podsystemy HAL muszą używać interfejsów API podsystemów HAL zdefiniowanych w nagłówku 2.1 SubHal.
W przypadku urządzeń z Androidem 13 lub nowszym, które korzystają z interfejsu HAL sterownika czujników AIDL, możesz użyć warstwy shim dla wielu interfejsów HAL, aby umożliwić obsługę wielu interfejsów HAL. Szczegółowe informacje o wdrożeniu znajdziesz w artykule Korzystanie z Sensors Multi-HAL z Sensors AIDL HAL.
Różnica między interfejsem Sensors Multi-HAL 2 a interfejsem Sensors HAL 2
Interfejs Sensors Multi-HAL 2, dostępny na urządzeniach z Androidem 10 lub nowszym, wprowadza kilka abstrakcji na poziomie interfejsu Sensors HAL 2, aby ułatwić interakcję z interfejsami HAL. Interfejs Sensors Multi-HAL 2 wprowadza klasę HalProxy, która obsługuje implementację interfejsu Sensors HAL 2 oraz interfejs V2_1/SubHal
(lub V2_0/SubHal
), aby umożliwić HalProxy
interakcję z podrzędnymi interfejsami HAL.
Interfejs ISensorsSubHal
różni się od interfejsu 2.1/ISensors.hal
(lub 2.0/ISensors.hal
) w następujący sposób:
- Metoda initialize przekazuje klasę
IHalProxyCallback
zamiast 2 obiektów FMQ iISensorsCallback
. - Podsystemy HAL muszą implementować funkcję debugowania, aby dostarczać informacje o debugowaniu w raportach o błędach.
- Podsystemy HAL muszą implementować funkcję nazwy, aby można było odróżnić wczytywany podsystem HAL od innych podsystemów HAL.
Główna różnica między interfejsem Sensors Multi-HAL 2 a interfejsem Sensors HAL 2 dotyczy funkcji inicjowania. Zamiast interfejsu FMQ interfejs IHalProxyCallback
udostępnia 2 metody: jedną do publikowania zdarzeń czujnika w ramach frameworku czujników i jedną do tworzenia blokad aktywacji. W podstawie interfejsu SensorsMulti-HAL są zarządzane wszystkie interakcje z interfejsami FMQ, aby zapewnić terminowe dostarczanie zdarzeń czujników do wszystkich interfejsów podrzędnych. Zdecydowanie zalecamy, aby interfejsy HAL podrzędnych używały metody createScopedWakelock
, aby przekazać obciążenie związane z czasową blokadą na potrzeby blokady w ramach interfejsu HAL czujników. Zalecamy też scentralizowanie korzystania z blokady w ramach interfejsu HAL czujników, co minimalizuje wywołania blokady i odblokowania.
Sensory Multi-HAL 2 mają też wbudowane funkcje bezpieczeństwa. Obsługuje ona sytuacje, w których kolejka FMQ czujnika jest pełna lub w których framework czujnika Androida jest ponownie uruchamiany i konieczne jest zresetowanie stanu czujnika. Dodatkowo, gdy zdarzenia są publikowane w klasie HalProxy
, ale framework czujnika nie może ich od razu zaakceptować, czujniki Multi-HAL mogą przenieść te zdarzenia do wątku w tle, aby umożliwić kontynuowanie pracy we wszystkich podrzędnych interfejsach HAL, dopóki nie zostaną opublikowane.
Kod źródłowy i implementacja referencyjna
Kod wieloplatformowy HAL dla wszystkich czujników jest dostępny w hardware/interfaces/sensors/common/default/2.X/multihal/
.
Oto kilka wskazówek dotyczących przydatnych materiałów.
HalProxy.h
: obiektHalProxy
jest tworzony przez wieloplatformowy interfejs API czujników i przekazuje dane z interfejsów podrzędnych do interfejsu sensora.HalProxy.cpp
: ImplementacjaHalProxy
zawiera całą logikę potrzebną do multipleksowania komunikacji między podsystemami HAL i ramką czujnika.SubHal.h
: InterfejsISensorsSubHal
definiuje interfejs, którego muszą przestrzegać podsystemy HAL, aby być zgodne z interfejsemHalProxy
. Sub-HAL implementuje metodę initialize, aby obiektHalProxyCallback
można było używać w przypadkupostEvents
icreateScopedWakelock
.W przypadku implementacji Multi-HAL 2.0 używaj wersji 2.0
SubHal.h
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/
: te testy jednostkowe sprawdzają implementacjęHalProxy
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: w tym przykładzie implementacji podsystemu HAL używa fałszywych czujników do generowania fałszywych danych. Przydatne do testowania interakcji wielu podsystemów HAL na urządzeniu.
Implementacja
Z tej sekcji dowiesz się, jak zaimplementować interfejs Multi-HAL czujników w tych sytuacjach:
- Korzystanie z wieloznaczników HAL czujników z obsługą AIDL HAL
- Wdrażanie interfejsu wielopoziomowego Sensors HAL 2.1
- Przenoszenie z interfejsu Sensors Multi-HAL 2.0 do Multi-HAL 2.1
- Przenoszenie z Sensors HAL 2.0
- Przenoszenie z Sensors HAL 1.0
- Przenoszenie z Sensors Multi-HAL 1.0
Używanie interfejsu HAL dla czujników w wersji wieloplatformowej z interfejsem HAL dla czujników w wersji AIDL
Aby umożliwić obsługę wielu HAL-i za pomocą interfejsu Sensors AIDL HAL, zaimportuj moduł AIDL Multi-HAL shim layer, który znajduje się w folderze hardware/interfaces/sensors/aidl/default/multihal/. Moduł obsługuje konwersję między typami definicji HAL czujników AIDL i HIDL oraz definiuje opakowanie dla interfejsu wielowarstwowego HAL opisanego w artykule Implementing Sensors Multi-HAL 2.1 (w języku angielskim). Warstwę shimu wielopoziomowego AIDL można stosować na urządzeniach, które implementują interfejs Sensors Multi-HAL 2.1.
Warstwę shimu wielopoziomowego AIDL można wykorzystać do udostępnienia sterownika śledzenia ruchów głowy i typów czujników IMU o ograniczonej liczbie osi w interfejsie AIDL HAL. 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 obsługiwane przez liczby całkowite w HAL czujników AIDL i HIDL się nie pokrywają.
Wdrożenie interfejsu Sensors Multi-HAL 2.1
Aby wdrożyć interfejs Sensors Multi-HAL 2.1 na nowym urządzeniu, wykonaj te czynności:
- Zaimplementuj interfejs
ISensorsSubHal
zgodnie z opisem w dokumentacjiSubHal.h
. - Zaimplementuj metodę
sensorsHalGetSubHal_2_1
wSubHal.h
. Dodaj cel
cc_library_shared
, aby utworzyć nowo wdrożony podsystem HAL. Podczas dodawania celu:- Upewnij się, że docelowy element jest przesyłany do jakiegoś miejsca na partycji dostawcy na urządzeniu.
- W pliku konfiguracji znajdującym się w katalogu
/vendor/etc/sensors/hals.conf
dodaj ścieżkę do biblioteki w nowym wierszu. W razie potrzeby utwórz plikhals.conf
.
Przykładowy wpis
Android.bp
służący do tworzenia biblioteki podrzędnej HAL znajdziesz whardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp
.Usuń wszystkie wpisy
android.hardware.sensors
z plikumanifest.xml
, który zawiera listę obsługiwanych interfejsów HAL na urządzeniu.Usuń wszystkie pliki usługi
android.hardware.sensors
i plikiservice.rc
z plikudevice.mk
, a potem dodaj plikiandroid.hardware.sensors@2.1-service.multihal
iandroid.hardware.sensors@2.1-service.multihal.rc
do plikuPRODUCT_PACKAGES
.
Podczas uruchamiania HalProxy
szuka nowo zaimplementowanego podsystemu HAL i inicjalizuje go, wywołując sensorsHalGetSubHal_2_1
.
Przenoszenie z Sensors Multi-HAL 2.0 do Multi-HAL 2.1
Aby przenieść się z Multi-HAL 2.0 do Multi-HAL 2.1, zaimplementuj interfejs SubHal
i skompiluj ponownie sub-HAL.
Oto różnice między interfejsami SubHal
w wersjach 2.0 i 2.1:
IHalProxyCallback
używa typów utworzonych w wersji 2.1 specyfikacjiISensors.hal
.- Funkcja
initialize()
przekazuje nową zmiennąIHalProxyCallback
zamiast zmiennej z interfejsuSubHal
w wersji 2.0. - Podsystemy HAL muszą implementować metody
getSensorsList_2_1
iinjectSensorData_2_1
zamiastgetSensorsList
iinjectSensorData
, ponieważ te metody używają nowych typów dodanych w wersji 2.1 specyfikacjiISensors.hal
. - Aby Multi-HAL traktował je jako podzbiory HAL w wersji 2.1, muszą one udostępniać interfejs
sensorsHalGetSubHal_2_1
, a niesensorsHalGetSubHal
.
Przenoszenie z Sensors HAL 2.0
Podczas przejścia z wersji Sensors HAL 2.0 na wersję 2.0 interfejsu HAL dla czujników upewnij się, że implementacja interfejsu HAL spełnia te wymagania.
Inicjowanie HAL
Interfejs HAL czujników 2.0 zawiera funkcję inicjowania, która umożliwia usłudze czujnika przekazywanie informacji o FMQ i dynamicznym wywołaniu zwrotnym czujnika. W interfejsie Sensors Multi-HAL 2.0 funkcja initialize()
przekazuje pojedynczy wywoływany przez użytkownika kod, który musi być użyty do publikowania zdarzeń czujnika, uzyskiwania blokad aktywacji i powiadamiania o dynamicznych połączeniach i rozłączeniach czujnika.
Przesyłanie zdarzeń czujnika do implementacji Multi-HAL
Zamiast publikować zdarzenia czujnika za pomocą FMQ, podsystem HAL musi zapisywać zdarzenia czujnika w IHalProxyCallback
, gdy są dostępne.
Zdarzenia WAKE_UP
W interfejsie HAL czujników 2.0 interfejs HAL może zarządzać blokadą aktywacji w ramach swojej implementacji. W Sensors Multi-HAL 2.0 interfejsy podrzędne umożliwiają zarządzanie blokadami uśpienia przez implementację Multi-HAL i możliwość żądania blokady uśpienia przez wywołanie interfejsu createScopedWakelock
.
Podczas publikowania zdarzeń aktywacji w implementacji Multi-HAL należy uzyskać i przekazać do postEvents
zablokowany blokadę aktywacji.
Czujniki dynamiczne
Interfejs Sensors Multi-HAL 2.0 wymaga, aby funkcje onDynamicSensorsConnected
i onDynamicSensorsDisconnected
w IHalProxyCallback
były wywoływane za każdym razem, gdy zmieniają się dynamiczne połączenia czujników. Te wywołania zwrotne są dostępne w ramach wskaźnika IHalProxyCallback
, który jest udostępniany przez funkcję initialize()
.
Port z Sensors HAL 1.0
Podczas przejścia z wersji Sensors HAL1.0 na wersję Sensors Multi-HAL 2.0 sprawdź, czy implementacja HAL spełnia te wymagania.
Inicjowanie HAL
Aby ustanowić wywołanie zwrotne między implementacją sub-HAL a implementacją Multi-HAL, musi być obsługiwana funkcja initialize()
.
Wyświetlanie dostępnych czujników
W Sensors Multi-HAL 2.0 funkcja getSensorsList()
musi zwracać tę samą wartość podczas uruchamiania urządzenia, nawet po ponownym uruchomieniu interfejsu HAL czujników. Dzięki temu framework może spróbować ponownie połączyć się z czujnikiem, jeśli serwer systemowy zostanie ponownie uruchomiony. Wartość zwracana przez getSensorsList()
może się zmienić po ponownym uruchomieniu urządzenia.
Przesyłanie zdarzeń czujnika do implementacji Multi-HAL
W Sensors HAL 2.0 zamiast czekać na wywołanie funkcji poll()
podrzędny interfejs HAL musi aktywnie zapisywać zdarzenia czujnika do IHalProxyCallback
, gdy tylko są dostępne.
Zdarzenia WAKE_UP
W interfejsie HAL czujników w wersji 1.0 interfejs HAL może zarządzać blokadą aktywacji w ramach swojej implementacji. W ramach interfejsu Sensors Multi-HAL 2.0 interfejsy podrzędne umożliwiają zarządzanie blokadami uśpienia i proszenie o uzyskanie blokady uśpienia przez wywołanie interfejsu createScopedWakelock
.
Podczas publikowania zdarzeń aktywacji w implementacji Multi-HAL należy uzyskać i przekazać do postEvents
zablokowany blokadę aktywacji.
Czujniki dynamiczne
W Sensors HAL 1.0 dynamiczne czujniki są zwracane za pomocą funkcji poll()
.
Interfejs Sensors Multi-HAL 2.0 wymaga, aby funkcje onDynamicSensorsConnected
i onDynamicSensorsDisconnected
w IHalProxyCallback
były wywoływane za każdym razem, gdy zmieniają się dynamiczne połączenia czujników. Te wywołania zwrotne są dostępne w ramach wskaźnika IHalProxyCallback
, który jest udostępniany przez funkcję initialize()
.
Przenoszenie z Sensors Multi-HAL 1.0
Aby przenieść istniejące rozwiązanie z Sensors Multi-HAL 1.0, wykonaj te czynności.
- Upewnij się, że konfiguracja HAL czujników znajduje się w pliku
/vendor/etc/sensors/hals.conf
. Może to obejmować przeniesienie pliku znajdującego się w folderze/system/etc/sensors/hals.conf
. - Usuń wszystkie odwołania do funkcji
hardware/hardware.h
ihardware/sensors.h
, ponieważ nie są one obsługiwane w HAL 2.0. - Przenoś podsystemy HAL zgodnie z opisem w artykule Przenoszenie z Sensors HAL 1.0.
- Aby ustawić interfejs Sensors Multi-HAL 2.0 jako domyślny, wykonaj kroki 3 i 4 w sekcji Wdrażanie interfejsu Sensors Multi-HAL 2.0.
Weryfikacja
Uruchamianie VTS
Po zintegrowaniu co najmniej 1 interfejsu HAL z Sensors Multi-HAL 2.1 użyj pakietu testów dostawcy (VTS), aby sprawdzić, czy implementacje interfejsów HAL spełniają wszystkie wymagania interfejsu HAL Sensors.
Aby uruchomić tylko testy VTS czujników po skonfigurowaniu VTS 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 dla AIDL Multi-HAL, uruchom VtsAidlHalSensorsTargetTest
.
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsAidlHalSensorsTargetTest
Uruchamianie testów jednostkowych
Testy jednostkowe w HalProxy_test.cpp
test HalProxy
korzystają z fałszywych podsystemów HAL, które są tworzone w teście jednostkowym i nie są ładowane dynamicznie. Podczas tworzenia nowego podsystemu HAL te testy powinny służyć jako wskazówka, jak dodawać testy jednostkowe, które weryfikują, czy nowy podsystem HAL jest prawidłowo zaimplementowany.
Aby uruchomić testy, wykonaj te polecenia:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
Testowanie z fałszywymi podsystemami HAL
Fałszywe podinterfejsy HAL to fikcyjne implementacje interfejsu ISensorsSubHal
.
Podsystemy HAL udostępniają różne listy czujników. Po aktywowaniu czujniki okresowo publikują automatycznie wygenerowane zdarzenia czujnika w usłudze HalProxy
w interwałach określonych w danym żądaniu czujnika.
Za pomocą fałszywych podsystemów HAL można testować, jak działa pełny kod Multi-HAL z innymi podsystemami HAL załadowanymi w systemie, oraz sprawdzać różne aspekty kodu Multi-HAL czujników.
Na stronie hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
są dostępne 2 fałszywe sub-HAL.
Aby utworzyć i przekazać fałszywe podsystemy HAL na urządzenie, wykonaj te czynności:
Aby utworzyć i przesłać na urządzenie 3 różne fałszywe podsystemy HAL, uruchom te polecenia:
$ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests/
mma
adb 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.so
adb 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.so
adb 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.so
Zaktualizuj konfigurację HAL czujników w pliku
/vendor/etc/sensors/hals.conf
, podając ścieżki do fałszywych pod-HAL-i./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.so
Uruchom ponownie
HalProxy
i załaduj nowe podsystemy HAL wymienione w konfiguracji.adb shell stop
adb shell start
Debugowanie
Programiści mogą debugować framework za pomocą polecenia lshal
. Aby uzyskać dane debugowania interfejsu HAL czujników, uruchom to polecenie:
adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default
Informacje o bieżącym stanie HalProxy
i jego podsystemów HAL są następnie wysyłane do terminala. Poniżej znajduje się przykład danych wyjściowych polecenia dotyczącego obiektu HalProxy
i fałszywych podsystemó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 frameworku czujników oczekuje wiele zdarzeń. To oznacza, że usługa czujnika jest zablokowana lub uległa awarii i nie przetwarza zdarzeń czujnika albo że z poziomu podrzędnego HAL niedawno opublikowano dużą partię zdarzeń czujnika.
Jeśli liczba odwołań do blokady uśpienia jest większa niż 0
, oznacza to, że HalProxy
uzyskała blokadę uśpienia. Wartość ta powinna być większa niż 0
tylko wtedy, gdy ScopedWakelock
jest celowo wstrzymywany lub gdy zdarzenia aktywacji zostały wysłane do HalProxy
i nie zostały przetworzone przez interfejs sensora.
Deskryptor pliku przekazany metodzie debugowania w HalProxy
jest przekazywany do każdego podinterfejsu HAL, więc deweloperzy muszą zaimplementować metodę debugowania w ramach interfejsu ISensorsSubHal
.