Platforma HAL Sensors Multi-HAL umożliwia działanie terminali HAL czujników razem z innymi HAL. Multi-HAL Sensors dynamicznie wczytuje pod-HAL czujników zapisane jako biblioteki dynamiczne na partycji dostawcy i przekazuje im obiekt wywołania zwrotnego, który może obsługiwać zdarzenia publikowania oraz pobierać i zwalniać blokadę uśpienia. Podrzędna lista HAL czujników to takich, które są wbudowane we wspólny obiekt w partycji dostawcy i są używane przez platformę wieloskładnikową HAL. Te podrzędne części HAL nie zależą od siebie ani od kodu z wieloma HAL, który zawiera główną funkcję procesu.
Czujniki Multi-HAL 2.1, dostępne na urządzeniach z Androidem 11 lub nowszym, to iteracja funkcji Sensors Multi-HAL 2.0, która obsługuje wczytywanie podrzędnych interfejsów podrzędnych HAL, które mogą ujawniać typ kąta zawiasu. Aby obsługiwać ten typ czujnika, podrzędne interfejsy HAL muszą używać interfejsów API subHAL określonych w nagłówku SubHal 2.1.
W przypadku urządzeń z Androidem 13 lub nowszym, które korzystają z interfejsu HAL Sensors AIDL, możesz użyć warstwy z podkładką HAL, aby umożliwić obsługę wielu HAL. Szczegóły implementacji znajdziesz w artykule na temat używania czujników Multi-HAL z czujnikami AIDL HAL.
Różnica między czujnikami Multi-HAL 2 a czujnikami HAL 2
Czujniki Multi-HAL 2, dostępne na urządzeniach z Androidem 10 lub nowszym, dodają kilka abstrakcji oprócz interfejsu Sensors HAL
2, aby ułatwić interakcję z interfejsami HAL API. Interfejs Sensors Multi-HAL 2 wprowadza klasę HalProxy do obsługi implementacji interfejsu Sensors HAL 2 oraz interfejs V2_1/SubHal
(lub V2_0/SubHal
), który umożliwia usłudze HalProxy
interakcję z pod-HAL.
Interfejs ISensorsSubHal
różni się od interfejsu 2.1/ISensors.hal
(lub 2.0/ISensors.hal
) pod kilkoma względami:
- Metoda inicjowania przekazuje klasę
IHalProxyCallback
zamiast dwóch FMQ iISensorsCallback
. - Sub-HAL muszą implementować funkcję debugowania, która umożliwia dodawanie informacji na potrzeby debugowania w raportach o błędach.
- Sub-HAL musi implementować funkcję nazwy, która umożliwia odróżnienie wczytanej części podrzędnej od innych podrzędnych elementów HAL.
Główna różnica między czujnikami Multi-HAL 2 i HAL 2 czujnika występuje w funkcjach inicjowania. Zamiast udostępniać sygnały FMQ interfejs IHalProxyCallback
udostępnia 2 metody: jedną do publikowania zdarzeń z czujnika w ramce czujników, a drugą do tworzenia blokad uśpienia. Pod jej działaniem czujniki Multi-HAL zarządzają wszystkimi interakcjami z FMQ, aby na czas dostarczać zdarzenia czujnika do wszystkich podrzędnych kont HAL. Zdecydowanie zalecamy, aby podrzędne bloki uśpienia używały metody createScopedWakelock
do przekazywania obciążenia czasowego wygaszania blokad uśpienia do interfejsu Sensors Multi-HAL i scentralizowania użycia tej funkcji na potrzeby jednej wspólnej blokady uśpienia dla całej platformy Sensors Multi-HAL, co minimalizuje ryzyko blokowania i odblokowywania połączeń.
Czujniki Multi-HAL 2 mają też wbudowane funkcje bezpieczeństwa. Obsługuje sytuacje, w których czujnik FMQ jest pełny lub gdy platforma czujnika Androida uruchamia się ponownie i trzeba zresetować stan czujnika. Poza tym, gdy zdarzenia są publikowane w klasie HalProxy
, ale platforma czujnika nie może natychmiast zaakceptować zdarzeń, interfejs Sensors Multi-HAL może przenieść te zdarzenia do wątku w tle, aby umożliwić kontynuację pracy między wszystkimi podrzędnymi produktami HAL podczas oczekiwania na opublikowanie zdarzeń.
Implementacja kodu źródłowego i referencyjnego
Kod HAL wszystkich czujników jest dostępny w regionie hardware/interfaces/sensors/common/default/2.X/multihal/
.
Oto kilka linków do materiałów.
HalProxy.h
: obiektHalProxy
jest tworzony przez Sensors Multi-HAL i obsługuje przesyłanie danych z podrzędnych list HAL do platformy czujnika.HalProxy.cpp
: implementacjaHalProxy
zawiera wszystkie funkcje logiczne niezbędne do Multipleksowania komunikacji między podrzędnymi półkami HAL a platformą czujnika.SubHal.h
: InterfejsISensorsSubHal
określa interfejs, który musi być używany przez podrzędne listy HAL, aby były zgodne zHalProxy
. Sub-HAL implementuje metodę inicjowania, dzięki czemu obiektHalProxyCallback
może być używany na potrzebypostEvents
icreateScopedWakelock
.W przypadku implementacji z wieloma HAL 2.0 użyj 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 tej przykładowej implementacji kodu sub-HAL wykorzystuje się fałszywe czujniki do generowania fałszywych danych. Ta opcja jest przydatna do sprawdzania, jak różne części podrzędne HAL współdziałają na urządzeniu.
Implementacja
W tej sekcji opisujemy, jak wdrożyć wiele czujników HAL czujniki w tych sytuacjach:
- Korzystanie z czujników Multi-HAL z czujnikami AIDL HAL
- Stosowanie czujników w formacie Multi-HAL 2.1
- Przenoszenie z Sensors Multi-HAL 2.0 na Multi-HAL 2.1
- Przenoszenie z poziomu Sensors HAL 2.0
- Przenoszenie z poziomu Sensors HAL 1.0
- Przenoszenie z sensorów Multi-HAL 1.0
Używaj czujników Multi-HAL z czujnikami AIDL HAL
Aby umożliwić obsługę wielu HAL za pomocą interfejsu Sensors AIDL HAL, zaimportuj moduł warstwy podkładowej AIDL, który znajduje się w lokalizacji hardware/interfaces/sensors/aidl/default/multihal/. Moduł obsługuje konwersję między typami definicji HAL czujników AIDL i HIDL i definiuje kod z interfejsu multi-HAL opisany w artykule Implementowanie czujników Multi-HAL 2.1. Warstwa podkładkowa AIDL Multi-HAL jest zgodna z urządzeniami, które obsługują czujniki Multi-HAL 2.1.
Warstwa podkładkowa AIDL Multi-HAL pozwala pokazać głowę trackera oraz typy czujników IMU o ograniczonych osiach w interfejsie Sensors 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 HAL czujników AIDL i HIDL z obsługą liczb całkowitych nie nakładają się na siebie.
Zastosuj czujniki Multi-HAL 2.1
Aby wdrożyć Sensors Multi-HAL 2.1 na nowym urządzeniu, wykonaj te czynności:
- Zaimplementuj interfejs
ISensorsSubHal
w sposób opisany wSubHal.h
. - Zaimplementuj metodę
sensorsHalGetSubHal_2_1
wSubHal.h
. Dodaj cel
cc_library_shared
, aby utworzyć nowo wdrożoną podrzędną listę klientów (HAL). Podczas dodawania środowiska docelowego:- Upewnij się, że środowisko docelowe jest przeniesione do partycji producenta urządzenia.
- W pliku konfiguracji znajdującym się pod adresem
/vendor/etc/sensors/hals.conf
dodaj w nowym wierszu ścieżkę do biblioteki. W razie potrzeby utwórz plikhals.conf
.
Przykładowy wpis
Android.bp
dotyczący tworzenia biblioteki niższego poziomu HAL znajdziesz tutaj:hardware/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 licencji HAL na urządzeniu.Usuń wszystkie usługi
android.hardware.sensors
i plikiservice.rc
z plikudevice.mk
oraz dodajandroid.hardware.sensors@2.1-service.multihal
iandroid.hardware.sensors@2.1-service.multihal.rc
doPRODUCT_PACKAGES
.
Podczas uruchamiania HalProxy
szuka nowo wdrożonej podrzędnej HAL i inicjuje ją, wywołując funkcję sensorsHalGetSubHal_2_1
.
Port z Czujników Multi-HAL 2.0 na Multi-HAL 2.1
Aby przenieść dane z Multi-HAL 2.0 na Multi-HAL 2.1, zaimplementuj interfejs SubHal
i ponownie skompiluj subdomenę HAL.
Różnice między interfejsami SubHal
w wersjach 2.0 i 2.1:
IHalProxyCallback
korzysta z typów utworzonych w wersji 2.1 specyfikacjiISensors.hal
.- Funkcja
initialize()
przekazuje nowy obiektIHalProxyCallback
zamiast tego z interfejsuSubHal
2.0 - Sub-HAL muszą implementować
getSensorsList_2_1
iinjectSensorData_2_1
zamiastgetSensorsList
iinjectSensorData
, ponieważ te metody korzystają z nowych typów dodanych w wersji 2.1 specyfikacjiISensors.hal
. - Sub-HAL musi udostępniać elementowi
sensorsHalGetSubHal_2_1
, a niesensorsHalGetSubHal
, aby mogły traktować je jako Sub-HAL w wersji 2.1.
Port z Czujnika HAL 2.0
Jeśli przechodzisz z Sensors HAL 2.0 na Sensors Multi-HAL 2.0, upewnij się, że implementacja HAL spełnia poniższe wymagania.
Inicjowanie HAL
HAL 2.0 czujnika ma funkcję inicjowania, która umożliwia usłudze czujnika przekazywanie sygnałów FMQ i dynamiczne wywołanie zwrotne czujnika. W systemie Sensors Multi-HAL 2.0 funkcja initialize()
przekazuje jedno wywołanie zwrotne, które jest używane do wysyłania zdarzeń z czujnika, uzyskiwania blokad uśpienia oraz powiadamiania o dynamicznym podłączeniu i rozłączeniu czujników.
Publikuj zdarzenia z czujników w implementacji Multi-HAL
Zamiast publikować zdarzenia z czujnika za pomocą FMQ, pod-HAL musi zapisywać zdarzenia czujnika w IHalProxyCallback
, gdy są one dostępne.
Zdarzenia WAKE_UP
W przypadku interfejsu Sensors HAL 2.0 HAL może zarządzać blokadą uśpienia w ramach implementacji. W Sensors Multi-HAL 2.0 podrzędne listy HAL umożliwiają wdrożeniu Multi-HAL zarządzanie blokadami uśpienia i mogą żądać uzyskania blokady uśpienia przez wywołanie createScopedWakelock
.
Podczas publikowania zdarzeń wybudzenia do implementacji wielu HAL należy uzyskać blokadę uśpienia o zakresie zablokowanym i przekazać ją do postEvents
.
Czujniki dynamiczne
Czujniki Multi-HAL 2.0 wymagają wywoływania onDynamicSensorsConnected
i onDynamicSensorsDisconnected
w IHalProxyCallback
przy każdej zmianie połączeń z czujnikami dynamicznymi. Te wywołania zwrotne są dostępne jako część wskaźnika IHalProxyCallback
udostępnianego przez funkcję initialize()
.
Port z Czujnika HAL 1.0
Jeśli przechodzisz z Sensors HAL 1.0 na Sensors Multi-HAL 2.0, upewnij się, że implementacja HAL spełnia poniższe wymagania.
Inicjowanie HAL
Do ustanowienia wywołania zwrotnego między sub-HAL a implementacją Multi-HAL musi być obsługiwana funkcja initialize()
.
Udostępnij dostępne czujniki
W przypadku Sensors Multi-HAL 2.0 funkcja getSensorsList()
musi zwracać tę samą wartość podczas jednego uruchomienia urządzenia, nawet w przypadku ponownego uruchomienia HAL czujników. Dzięki temu platforma może spróbować ponownie nawiązać połączenia z czujnikiem po ponownym uruchomieniu serwera systemu. Wartość zwrócona przez funkcję getSensorsList()
może się zmienić po ponownym uruchomieniu urządzenia.
Publikuj zdarzenia z czujników w implementacji Multi-HAL
W HAL 2.0 Sensors HAL 2.0 nie trzeba czekać na wywołanie funkcji poll()
, ale podrzędna HAL musi aktywnie zapisywać zdarzenia czujnika w IHalProxyCallback
, gdy tylko są dostępne.
Zdarzenia WAKE_UP
W przypadku interfejsu Sensors HAL 1.0 HAL może zarządzać blokadą uśpienia w celu jej implementacji. W Sensors Multi-HAL 2.0 podrzędne listy HAL umożliwiają wdrożeniu Multi-HAL zarządzanie blokadami uśpienia i mogą żądać uzyskania blokady uśpienia przez wywołanie createScopedWakelock
.
Podczas publikowania zdarzeń wybudzenia do implementacji wielu HAL należy uzyskać blokadę uśpienia o zakresie zablokowanym i przekazać ją do postEvents
.
Czujniki dynamiczne
W HAL 1.0 czujniki dynamiczne są zwracane przez funkcję poll()
.
Czujniki Multi-HAL 2.0 wymagają wywoływania onDynamicSensorsConnected
i onDynamicSensorsDisconnected
w IHalProxyCallback
przy każdej zmianie połączeń z czujnikami dynamicznymi. Te wywołania zwrotne są dostępne jako część wskaźnika IHalProxyCallback
udostępnianego przez funkcję initialize()
.
Port z Czujnika 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
/vendor/etc/sensors/hals.conf
. Może to oznaczać przeniesienie pliku znajdującego się pod adresem/system/etc/sensors/hals.conf
. - Usuń wszelkie odwołania do
hardware/hardware.h
ihardware/sensors.h
, ponieważ nie są one obsługiwane przez HAL 2.0. - Sub-HAL portów zgodnie z opisem w sekcji Przenoszenie z Sensors Hal 1.0.
- Jako wyznaczoną HAL ustaw Sensors Multi-HAL 2.0, wykonując kroki 3 i 4 z sekcji Implementing Sensors Mutli-HAL 2.0 (Implementowanie czujników z komponentami HAL 2.0).
Weryfikacja
Uruchom VTS
Gdy zintegrujesz co najmniej jedną podrzędną część HAL z urządzeniem Sensors Multi-Hal 2.1, użyj pakietu Vendor Test Suite (VTS), aby mieć pewność, że implementacje podrzędne HAL spełniają wszystkie wymagania określone w interfejsie Sensors HAL.
Aby uruchomić tylko testy VTS czujników po skonfigurowaniu VTS na hoście, 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 podkładowej 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 ramach testu HalProxy_test.cpp
HalProxy
z wykorzystaniem fałszywych podrzędnych list HAL, które są tworzone w teście jednostkowym i nie są ładowane dynamicznie. Podczas tworzenia nowej podrzędnej HAL testy te powinny służyć za wskazówkę przy dodawaniu testów jednostkowych sprawdzających, czy nowa wersja podrzędna HAL została 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 wykorzystaniem fałszywych sub-HAL
Fałszywe sub-HAL to fikcyjne implementacje interfejsu ISensorsSubHal
.
Sub-HAL zawierają różne listy czujników. Gdy czujniki są aktywowane, co jakiś czas wysyłają do HalProxy
automatycznie wygenerowane zdarzenia dotyczące czujnika w odstępach czasu określonych w danym żądaniu dotyczącym czujnika.
Fałszywe sub-HAL można wykorzystać do przetestowania, jak pełny kod Multi-HAL działa z innymi subkontami podrzędnymi wczytywanymi do systemu, oraz do podkreślenia różnych aspektów kodu Multi-HAL czujnika.
Na stronie hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
dostępne są 2 fałszywe sub-HAL.
Aby utworzyć fałszywe sub-HAL i przesłać je na urządzenie, wykonaj te czynności:
Uruchom następujące polecenia, aby utworzyć i przekazać na urządzenie 3 różne fałszywe klucze Sub-HAL:
$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 na
/vendor/etc/sensors/hals.conf
, dodając ścieżki do fałszywych podkatalogó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.so
Uruchom ponownie usługę
HalProxy
i załaduj nowe podrzędne części HAL wymienione w konfiguracji.adb shell stop
adb shell start
Debugowanie
Deweloperzy mogą debugować platformę za pomocą polecenia lshal
. Aby poprosić o dane wyjściowe debugowania interfejsu HAL Sensors, uruchom to polecenie:
adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default
Informacje o bieżącym stanie instancji HalProxy
i jej podrzędnych list HAL są następnie wysyłane do terminala. Poniżej znajdziesz przykład danych wyjściowych polecenia dla obiektu HalProxy
i fałszywych list podrzędnych 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 podana w polu # of events on pending write queue
liczba jest duża (co najmniej 1000), oznacza to, że w ramce czujników oczekuje na zapisanie w platformie wielu zdarzeń. Oznacza to, że usługa czujnika jest zablokowana, uległa awarii i nie przetwarza zdarzeń z czujnika lub że duża porcja takich zdarzeń została niedawno opublikowana z poziomu podrzędnej HAL.
Jeśli liczba referencji blokady uśpienia przekracza 0
, oznacza to, że aplikacja HalProxy
nawiązała blokadę uśpienia. Wartość powinna być większa od 0
tylko wtedy, gdy ScopedWakelock
został celowo wstrzymany lub zdarzenia wybudzenia zostały wysłane do HalProxy
i nie zostały przetworzone przez platformę czujnika.
Deskryptor pliku przekazywany do metody debugowania w interfejsie HalProxy
jest przekazywany do każdej podrzędnej części HAL, dlatego deweloperzy muszą wdrożyć tę metodę debugowania w interfejsie ISensorsSubHal
.