Sensors Multi-HAL to platforma, która umożliwia uruchamianie interfejsów HAL czujników obok innych interfejsów HAL czujników. Wielokrotny HAL czujników dynamicznie wczytuje podrzędne HAL-e czujników przechowywane jako biblioteki dynamiczne na partycji dostawcy i przekazuje im obiekt wywołania zwrotnego, który może obsługiwać publikowanie zdarzeń oraz uzyskiwanie i zwalnianie blokady wybudzania. 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 wczytywanie podmodułów HAL mogących 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 umożliwić 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. Wielomodularny 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 HAL-ami.
Interfejs ISensorsSubHal
różni się od interfejsu 2.1/ISensors.hal
(lub 2.0/ISensors.hal
) w tych aspektach:
- Metoda initialize przekazuje
IHalProxyCallback
klasę 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 przesył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 podmoduły HAL korzystały z metody createScopedWakelock
, aby przekazywać obciążenie związane z przekroczeniem limitu czasu blokad wybudzania do modułu Sensors Multi-HAL i centralizować użycie blokad wybudzania w jednej wspólnej blokadzie wybudzania dla całego modułu 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 platforma czujników 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 podrzędnych interfejsach 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
: obiektHalProxy
jest tworzony przez multi-HAL czujników i odpowiada za przekazywanie danych z sub-HAL do platformy czujników.HalProxy.cpp
: implementacjaHalProxy
zawiera całą logikę potrzebną do multipleksowania komunikacji między podrzędnymi HAL-ami a platformą czujników.SubHal.h
: interfejsISensorsSubHal
określa interfejs, którego podrzędne warstwy HAL muszą przestrzegać, aby były zgodne zHalProxy
. Pod-HAL implementuje metodę initialize, dzięki czemu obiektHalProxyCallback
może być używany w przypadkupostEvents
icreateScopedWakelock
.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-a 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 opisujemy, jak wdrożyć interfejs Sensors Multi-HAL w tych sytuacjach:
- Korzystanie z wielu interfejsów HAL czujników z interfejsem HAL czujników AIDL
- 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 za pomocą interfejsu AIDL HAL czujników, zaimportuj moduł warstwy pośredniej AIDL Multi-HAL, który znajduje się w katalogu 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 czujników w wersji 2.1. 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 interfejsie HAL czujników AIDL. 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 interfejsu Sensors Multi-HAL w wersji 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
cc_library_shared
cel, aby utworzyć nowo wdrożony podsystem HAL. Podczas dodawania celu:- Upewnij się, że element docelowy jest umieszczony w dowolnym miejscu na partycji dostawcy urządzenia.
- W pliku konfiguracji znajdującym się w lokalizacji
/vendor/etc/sensors/hals.conf
dodaj ścieżkę do biblioteki w nowym wierszu. W razie potrzeby utwórz plikhals.conf
.
Przykład wpisu
Android.bp
dotyczącego tworzenia biblioteki podrzędnej HAL znajdziesz w sekcjihardware/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 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
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 2.0 do Multi-HAL 2.1, zaimplementuj interfejs SubHal
i ponownie skompiluj podrzędny HAL.
Oto różnice między interfejsami 2.0 i 2.1 SubHal
:
IHalProxyCallback
korzysta z typów utworzonych w wersji 2.1 specyfikacjiISensors.hal
.- Funkcja
initialize()
przekazuje nowy obiektIHalProxyCallback
zamiast obiektu z interfejsu 2.0SubHal
. - Podrzędne HAL-e 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
. - Podmoduły HAL muszą udostępniać
sensorsHalGetSubHal_2_1
zamiastsensorsHalGetSubHal
, 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 interfejsu 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 dynamicznym połączeniu i rozłączeniu czujnika.
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 przypadku interfejsu HAL czujników w wersji 2.0 interfejs HAL może zarządzać blokadą wybudzania 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
.
Zablokowane blokady wybudzania o określonym zakresie muszą być uzyskiwane i przekazywane do postEvents
podczas wysyłania zdarzeń wybudzania do implementacji Multi-HAL.
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ę 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 warstwy 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 interfejsu 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 interfejsie 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 ponowne nawiązanie 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 interfejsie HAL czujników 1.0 interfejs HAL może zarządzać blokadą wybudzania 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
.
Zablokowane blokady wybudzania o określonym zakresie muszą być uzyskiwane i przekazywane do postEvents
podczas wysyłania zdarzeń wybudzania do implementacji Multi-HAL.
Czujniki dynamiczne
W komponencie HAL czujników w wersji 1.0 czujniki dynamiczne są zwracane przez funkcję 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ę 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()
.
Przeniesienie 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.h
ihardware/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 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
test HalProxy
korzystają z fałszywych podmodułów HAL, które są tworzone w ramach testu jednostkowego 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ą prawidłowość implementacji nowego podrzędnego HAL.
Aby uruchomić testy, wpisz te polecenia:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
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.
Dostępne są 2 fałszywe podmoduły HAL: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/
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 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.so
Uruchom ponownie
HalProxy
i wczytaj nowe podmoduły HAL wymienione w konfiguracji.adb shell stop
adb 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 root
adb 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 danych wyjściowych 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 interfejsu Sensors API 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 wybudzania jest większa niż 0
, oznacza to, że HalProxy
uzyskał blokadę wybudzania. Wartość ta powinna być większa od 0
tylko wtedy, gdy celowo wstrzymywane jest wysyłanie 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 podrzędnego interfejsu HAL, więc deweloperzy muszą zaimplementować metodę debugowania w ramach interfejsu ISensorsSubHal
.