Sensors Multi-HAL to platforma, która umożliwia współpracę czujników HAL z innymi czujnikami HAL. Sensors Multi-HAL dynamicznie ładuje pod-HAL czujników przechowywane jako biblioteki dynamiczne na partycji dostawcy i udostępnia im obiekt wywołania zwrotnego, który może obsłużyć wysyłanie zdarzeń oraz pozyskiwanie i zwalnianie blokady wybudzania. Sub-HAL czujników to warstwa HAL czujników wbudowana we współdzielony obiekt na partycji dostawcy i używana przez platformę multi-HAL. Te pod-HAL nie zależą od siebie nawzajem ani od kodu multi-HAL, który zawiera główną funkcję procesu.
Sensors Multi-HAL 2.1, dostępny na urządzeniach z systemem Android 11 lub nowszym, to wersja Sensors Multi-HAL 2.0, która obsługuje ładowanie sub-HAL, które mogą ujawnić typ czujnika kąta zawiasu . Aby obsługiwać ten typ czujnika, sub-HAL muszą używać interfejsów API sub-HAL zdefiniowanych w nagłówku SubHal 2.1 .
W przypadku urządzeń z systemem Android 13 lub nowszym, które korzystają z czujników AIDL HAL , można użyć warstwy podkładki multi-HAL, aby umożliwić obsługę multi-HAL. Aby poznać szczegóły implementacji, zobacz Używanie czujników Multi-HAL z czujnikami AIDL HAL .
Różnica pomiędzy czujnikami Multi-HAL 2 i czujnikami HAL 2
Sensors Multi-HAL 2, dostępny na urządzeniach z systemem Android 10 lub nowszym, oprócz Sensors HAL 2 wprowadza kilka abstrakcji, aby ułatwić interakcję z interfejsami API HAL. Sensors Multi-HAL 2 wprowadza klasę HalProxy do obsługi implementacji interfejsu Sensors HAL 2 i interfejsu V2_1/SubHal
(lub V2_0/SubHal
), aby umożliwić HalProxy
interakcję z podrzędnymi warstwami HAL.
Interfejs ISensorsSubHal
różni się od interfejsu 2.1/ISensors.hal
(lub 2.0/ISensors.hal
) pod następującymi względami:
- Metoda inicjalizacji przekazuje klasę
IHalProxyCallback
zamiast dwóch FMQ iISensorsCallback
. - Sub-HAL muszą implementować funkcję debugowania w celu dostarczania informacji debugowania w raportach o błędach.
- Sub-HAL muszą implementować funkcję nazwy, aby załadowana pod-HAL mogła zostać odróżniona od innych pod-HAL.
Główna różnica pomiędzy Sensors Multi-HAL 2 i Sensors HAL 2 polega na funkcjach inicjalizacji. Zamiast udostępniać FMQ, interfejs IHalProxyCallback
udostępnia dwie metody, jedną metodę wysyłania zdarzeń czujnika do struktury czujników i jedną metodę tworzenia blokad uśpienia. Pod maską Sensors Multi-HAL zarządza wszystkimi interakcjami z FMQ, aby zapewnić terminowe dostarczanie zdarzeń z czujników dla wszystkich sub-HAL. Zdecydowanie zaleca się, aby podrzędne warstwy HAL korzystały z metody createScopedWakelock
w celu delegowania ciężaru związanego z przekroczeniem limitu czasu blokad wybudzenia na warstwę Sensors Multi-HAL i aby scentralizować użycie blokady wybudzenia w jednej wspólnej blokadzie wybudzenia dla całej warstwy Sensors Multi-HAL, co minimalizuje blokowanie i odblokowywanie dzwoni.
Czujniki Multi-HAL 2 posiadają także wbudowane funkcje bezpieczeństwa. Obsługuje sytuacje, w których FMQ czujnika jest zapełnione lub gdy środowisko czujnika Android uruchamia się ponownie i konieczne jest zresetowanie stanu czujnika. Dodatkowo, gdy zdarzenia są wysyłane do klasy HalProxy
, ale struktura czujnika nie jest w stanie natychmiast ich zaakceptować, Sensors Multi-HAL może przenieść zdarzenia do wątku w tle, aby umożliwić kontynuację pracy we wszystkich podrzędnych warstwach HAL podczas oczekiwania na zdarzenia Do wysłania.
Kod źródłowy i implementacja referencyjna
Kod Multi-HAL wszystkich czujników jest dostępny w hardware/interfaces/sensors/common/default/2.X/multihal/
. Oto wskazówki do niektórych zasobów.
-
HalProxy.h
: ObiektHalProxy
jest tworzony przez technologię Sensors multi-HAL i obsługuje przekazywanie danych z podrzędnych warstw HAL do struktury czujnika. -
HalProxy.cpp
: ImplementacjaHalProxy
zawiera całą logikę potrzebną do multipleksowania komunikacji pomiędzy podrzędnymi warstwami HAL i strukturą czujników. SubHal.h
: InterfejsISensorsSubHal
definiuje interfejs, którego muszą przestrzegać sub-HAL, aby były kompatybilne zHalProxy
. Sub-HAL implementuje metodę inicjowania, dzięki czemu obiektHalProxyCallback
może być używany dlapostEvents
icreateScopedWakelock
.W przypadku implementacji Multi-HAL 2.0 użyj wersji 2.0
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 sub-HAL wykorzystuje fałszywe czujniki do generowania fałszywych danych. Przydatne do testowania interakcji wielu sub-HAL na urządzeniu.
Realizacja
W tej sekcji opisano, jak wdrożyć Sensors Multi-HAL w następujących sytuacjach:
- Używanie czujników Multi-HAL z czujnikami AIDL HAL
- Implementacja czujników Multi-HAL 2.1
- Przejście z czujników Multi-HAL 2.0 do Multi-HAL 2.1
- Przenoszenie z Sensors HAL 2.0
- Przenoszenie z czujników HAL 1.0
- Portowanie z Sensors Multi-HAL 1.0
Używanie czujników Multi-HAL z czujnikami AIDL HAL
Aby umożliwić obsługę wielu HAL za pomocą Sensors AIDL HAL, zaimportuj moduł warstwy podkładki AIDL Multi-HAL, który można znaleźć w hardware/interfaces/sensors/aidl/default/multihal/ . Moduł obsługuje konwersję pomiędzy typami definicji HAL czujników AIDL i HIDL oraz definiuje opakowanie wokół interfejsu multi-HAL opisanego w Implementing Sensors Multi-HAL 2.1 . Warstwa podkładkowa AIDL multi-HAL jest kompatybilna z urządzeniami obsługującymi Sensors Multi-HAL 2.1.
Warstwa podkładki AIDL multi-HAL umożliwia wyeksponowanie czujników śledzenia głowy i czujników IMU o ograniczonej osi w czujnikach AIDL HAL. Aby używać 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 czujników AIDL i HIDL HAL nie nakładają się.
Implementacja czujników Multi-HAL 2.1
Aby wdrożyć Sensors Multi-HAL 2.1 na nowym urządzeniu, wykonaj następujące kroki:
- Zaimplementuj interfejs
ISensorsSubHal
zgodnie z opisem wSubHal.h
. - Zaimplementuj metodę
sensorsHalGetSubHal_2_1
wSubHal.h
. Dodaj cel
cc_library_shared
, aby zbudować nowo zaimplementowaną sub-HAL. Podczas dodawania celu:- Upewnij się, że cel został wypchnięty gdzieś na partycję dostawcy urządzenia.
- W pliku konfiguracyjnym znajdującym się pod
/vendor/etc/sensors/hals.conf
dodaj w nowej linii ścieżkę do biblioteki. Jeśli to konieczne, utwórz plikhals.conf
.
Przykładowy wpis
Android.bp
dotyczący budowania biblioteki sub-HAL można znaleźć 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 warstw HAL na urządzeniu.Usuń wszystkie pliki
android.hardware.sensors
service iservice.rc
z plikudevice.mk
i dodajandroid.hardware.sensors@2.1-service.multihal
iandroid.hardware.sensors@2.1-service.multihal.rc
doPRODUCT_PACKAGES
.
Podczas rozruchu HalProxy
uruchamia się, szuka nowo zaimplementowanej warstwy podrzędnej HAL i inicjuje ją, wywołując sensorsHalGetSubHal_2_1
.
Przejście z czujników Multi-HAL 2.0 do Multi-HAL 2.1
Aby przenieść z Multi-HAL 2.0 do Multi-HAL 2.1, zaimplementuj interfejs SubHal
i przekompiluj sub-HAL.
Oto różnice pomiędzy interfejsami SubHal
2.0 i 2.1:
-
IHalProxyCallback
używa typów utworzonych w wersji 2.1 specyfikacjiISensors.hal
. - Funkcja
initialize()
przekazuje noweIHalProxyCallback
zamiast tego z interfejsuSubHal
2.0 - Sub-HAL muszą implementować metody
getSensorsList_2_1
iinjectSensorData_2_1
zamiastgetSensorsList
iinjectSensorData
, ponieważ metody te korzystają z nowych typów dodanych w wersji 2.1 specyfikacjiISensors.hal
. - Sub-HAL muszą udostępniać
sensorsHalGetSubHal_2_1
zamiastsensorsHalGetSubHal
, aby Multi-HAL traktował je jako sub-HAL w wersji 2.1.
Przenoszenie z Sensors HAL 2.0
W przypadku aktualizacji do Sensors Multi-HAL 2.0 z Sensors HAL 2.0 należy upewnić się, że implementacja HAL spełnia następujące wymagania.
Inicjowanie warstwy HAL
Czujniki HAL 2.0 posiada funkcję inicjowania, która umożliwia usłudze czujnika przekazywanie FMQ i dynamicznego wywołania zwrotnego czujnika. W Sensors Multi-HAL 2.0 funkcja initialize()
przekazuje pojedyncze wywołanie zwrotne, które musi zostać użyte do wysłania zdarzeń z czujnika, uzyskania blokady wybudzania i powiadomienia o dynamicznym podłączeniu i rozłączeniu czujnika.
Wysyłanie zdarzeń czujnika do implementacji Multi-HAL
Zamiast wysyłać zdarzenia czujnika przez FMQ, podrzędna warstwa HAL musi zapisywać zdarzenia czujnika do IHalProxyCallback
, gdy zdarzenia czujnika są dostępne.
Wydarzenia WAKE_UP
W Sensors HAL 2.0 warstwa HAL może zarządzać blokadą wybudzania w celu jej wdrożenia. W Sensors Multi-HAL 2.0 podrzędne warstwy HAL umożliwiają implementacji Multi-HAL zarządzanie blokadami uśpienia i mogą zażądać uzyskania blokady uśpienia poprzez wywołanie createScopedWakelock
. Podczas wysyłania zdarzeń wybudzenia do implementacji Multi-HAL należy uzyskać blokadę uśpienia o zablokowanym zakresie i przekazać ją do postEvents
.
Czujniki dynamiczne
Sensors Multi-HAL 2.0 wymaga, aby onDynamicSensorsConnected
i onDynamicSensorsDisconnected
w IHalProxyCallback
były wywoływane za każdym razem, gdy zmieniają się połączenia czujników dynamicznych. Te wywołania zwrotne są dostępne jako część wskaźnika IHalProxyCallback
udostępnianego za pośrednictwem funkcji initialize()
.
Przenoszenie z czujników HAL 1.0
W przypadku aktualizacji do wersji Sensors Multi-HAL 2.0 z wersji Sensors HAL 1.0 należy upewnić się, że implementacja HAL spełnia następujące wymagania.
Inicjowanie warstwy HAL
Funkcja initialize()
musi być obsługiwana, aby ustanowić wywołanie zwrotne pomiędzy implementacją sub-HAL i Multi-HAL.
Odsłonięcie dostępnych czujników
W Sensors Multi-HAL 2.0 funkcja getSensorsList()
musi zwracać tę samą wartość podczas uruchamiania pojedynczego urządzenia, nawet po ponownym uruchomieniu HAL czujników. Dzięki temu struktura może podjąć próbę ponownego nawiązania połączenia z czujnikiem w przypadku ponownego uruchomienia serwera systemowego. Wartość zwrócona przez getSensorsList()
może ulec zmianie po ponownym uruchomieniu urządzenia.
Wysyłanie zdarzeń czujnika do implementacji Multi-HAL
W Sensors HAL 2.0, zamiast czekać na wywołanie poll()
, sub-HAL musi proaktywnie zapisywać zdarzenia czujników do IHalProxyCallback
, gdy tylko zdarzenia czujnika są dostępne.
Wydarzenia WAKE_UP
W Sensors HAL 1.0 warstwa HAL może zarządzać blokadą wybudzania w celu jej wdrożenia. W Sensors Multi-HAL 2.0 podrzędne warstwy HAL umożliwiają implementacji Multi-HAL zarządzanie blokadami uśpienia i mogą zażądać uzyskania blokady uśpienia poprzez wywołanie createScopedWakelock
. Podczas wysyłania zdarzeń wybudzenia do implementacji Multi-HAL należy uzyskać blokadę uśpienia o zablokowanym zakresie i przekazać ją do postEvents
.
Czujniki dynamiczne
W Sensors HAL 1.0 czujniki dynamiczne są zwracane poprzez funkcję poll()
. Sensors Multi-HAL 2.0 wymaga, aby onDynamicSensorsConnected
i onDynamicSensorsDisconnected
w IHalProxyCallback
były wywoływane za każdym razem, gdy zmieniają się połączenia czujników dynamicznych. Te wywołania zwrotne są dostępne jako część wskaźnika IHalProxyCallback
udostępnianego za pośrednictwem funkcji initialize()
.
Portowanie z Sensors Multi-HAL 1.0
Aby przenieść istniejącą implementację z Sensors Multi-HAL 1.0 , wykonaj następujące kroki.
- Upewnij się, że konfiguracja HAL czujników znajduje się w
/vendor/etc/sensors/hals.conf.
Może to obejmować przeniesienie pliku znajdującego się w/system/etc/sensors/hals.conf
. - Usuń wszelkie odniesienia do
hardware/hardware.h
ihardware/sensors.h
ponieważ nie są one obsługiwane przez HAL 2.0. - Port sub-HAL zgodnie z opisem w sekcji Porting from Sensors Hal 1.0 .
- Ustaw Sensors Multi-HAL 2.0 jako wyznaczoną warstwę HAL, wykonując kroki 3 i 4 w sekcji Implementowanie Sensors Mutli-HAL 2.0 .
Walidacja
Uruchamiam VTS
Jeśli zintegrujesz jedną lub więcej sub-HAL z Sensors Multi-Hal 2.1, użyj pakietu Vendor Test Suite (VTS) , aby upewnić się, że Twoje implementacje sub-HAL spełniają wszystkie wymagania określone przez interfejs Sensors HAL.
Aby uruchomić tylko testy czujników VTS, gdy VTS jest skonfigurowany na komputerze głównym, wykonaj następujące 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ładki 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
testują HalProxy
przy użyciu fałszywych podrzędnych warstw HAL, które są tworzone w teście jednostkowym i nie są ładowane dynamicznie. Podczas tworzenia nowej pod-HAL testy te powinny służyć jako wskazówka, jak dodać testy jednostkowe weryfikujące, czy nowa pod-HAL jest poprawnie zaimplementowana.
Aby uruchomić testy, wykonaj następujące polecenia:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
Testowanie z fałszywymi sub-HAL
Fałszywe sub-HAL są fikcyjnymi implementacjami interfejsu ISensorsSubHal
. Sub-HAL udostępniają różne listy czujników. Gdy czujniki są aktywowane, okresowo wysyłają automatycznie wygenerowane zdarzenia czujnika do HalProxy
w oparciu o interwały określone w danym żądaniu czujnika.
Fałszywych warstw podrzędnych HAL można używać do testowania działania pełnego kodu Multi-HAL z innymi podrzędnymi warstwami HAL załadowanymi do systemu oraz do podkreślania różnych aspektów kodu Multi-HAL czujników.
Dwie fałszywe sub-HAL są dostępne pod hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
.
Aby zbudować i wypchnąć fałszywe sub-HAL do urządzenia, wykonaj następujące kroki:
Uruchom następujące polecenia, aby zbudować i wypchnąć trzy różne fałszywe warstwy podrzędne HAL do urządzenia:
$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
/vendor/etc/sensors/hals.conf
, podając ścieżki do fałszywych sub-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
HalProxy
i załaduj nowe podrzędne warstwy HAL wymienione w pliku config.adb shell stop
adb shell start
Debugowanie
Programiści mogą debugować framework za pomocą polecenia lshal
. Aby zażądać wyników debugowania warstwy Sensors HAL, uruchom następującą komendę:
adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default
Informacje o bieżącym stanie HalProxy
i jego podrzędnych warstw HAL są następnie wysyłane do terminala. Poniżej pokazano przykład wyniku polecenia dla obiektu HalProxy
i fałszywych sub-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 określona dla # of events on pending write queue
jest duża (1000 lub więcej), oznacza to, że istnieje wiele zdarzeń oczekujących na zapis w strukturze czujników. Oznacza to, że usługa czujnika jest zablokowana, uległa awarii i nie przetwarza zdarzeń czujnika, lub że niedawno opublikowano dużą partię zdarzeń czujnika z podrzędnej warstwy HAL.
Jeśli liczba ref. blokady wybudzenia jest większa niż 0
, oznacza to, że HalProxy
uzyskał blokadę wybudzenia. Wartość ta powinna być większa od 0
, jeśli celowo wstrzymywano ScopedWakelock
lub jeśli zdarzenia wybudzania zostały wysłane do HalProxy
i nie zostały przetworzone przez strukturę czujnika.
Deskryptor pliku przekazany do metody debugowania HalProxy
jest przekazywany do każdej podrzędnej warstwy HAL, więc programiści muszą zaimplementować metodę debugowania jako część interfejsu ISensorsSubHal
.