Multi-HAL czujników to platforma, która umożliwia uruchamianie interfejsów HAL czujników obok innych interfejsów HAL czujników. 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. Podsystem HAL czujników to interfejs HAL czujników wbudowany w wspólny obiekt w partycji dostawcy, który jest używany przez interfejs wielopoziomowego interfejsu HAL. Te podrzędne HAL nie zależą od siebie ani od kodu z wieloma 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 sterownika HAL interfejsu AIDL dla czujników, 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 czujnikami Multi-HAL 2 a czujnikami 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
. - Sub-HALs musi implementować funkcję debugowania, aby dostarczać informacje o debugowaniu 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 interfejsem Sensors Multi-HAL 2 a interfejsem Sensors HAL 2 dotyczy funkcji 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. W ramach tej usługi zarządza się wszystkimi interakcjami z interfejsami FMQ, aby zapewnić terminowe dostarczanie zdarzeń czujników do wszystkich podrzędnych interfejsów HAL. Zdecydowanie zalecamy, aby interfejsy HAL podrzędnych używały metody createScopedWakelock
, aby przekazać obciążenie związane z czasową blokadą na rzecz interfejsu Sensors Multi-HAL, oraz aby scentralizować użycie blokady na rzecz jednej wspólnej blokady dla całego interfejsu Sensors Multi-HAL, co minimalizuje wywołania blokady i odblokowania.
Sensors Multi-HAL 2 ma 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. 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 HAL-ach w czasie oczekiwania na opublikowanie zdarzeń.
Implementacja kodu źródłowego i referencyjnego
Kod Multi-HAL wszystkich czujników jest dostępny w hardware/interfaces/sensors/common/default/2.X/multihal/
.
Oto kilka linków do 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
określa interfejs, który musi być używany przez podrzędne części HAL, aby były zgodne zHalProxy
. Sub-HAL implementuje metodę initialize, aby obiektHalProxyCallback
można było używać 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 sprawdzają implementacjęHalProxy
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: w tym przykładzie implementacji podsystemu HAL używa się fałszywych czujników 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 opisano, jak zaimplementować interfejs Multi-HAL czujników w tych sytuacjach:
- Korzystanie z wieloplatformowego interfejsu HAL dla czujników z interfejsem HAL dla czujników AIDL
- Implementacja czujników Multi-HAL 2.1
- Przenoszenie z interfejsu Sensors Multi-HAL 2.0 do Multi-HAL 2.1
- Przenoszenie z poziomu Sensors HAL 2.0
- Przenoszenie z Sensors HAL 1.0
- Przenoszenie z Sensors 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 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.
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.
Wdrożenie interfejsu Sensors Multi-HAL 2.1
Aby zaimplementować 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 środowiska docelowego:- Upewnij się, że środowisko docelowe jest przeniesione do partycji dostawcy 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 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ść dane z Multi-HAL 2.0 na Multi-HAL 2.1, zaimplementuj interfejs SubHal
i ponownie skompiluj subdomenę 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 nowy parametrIHalProxyCallback
zamiast 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
. - 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
Podczas aktualizacji z Sensors HAL 2.0 na Sensors Multi-HAL 2.0 sprawdź, czy implementacja HAL spełnia te wymagania.
Inicjowanie HAL
HAL 2.0 ma funkcję inicjowania, która umożliwia usłudze czujnika przekazywanie sygnałów FMQ i dynamiczne wywołanie zwrotne czujnika. W Sensors Multi-HAL 2.0 funkcja initialize()
przekazuje pojedynczą funkcję wywołania zwrotnego, która musi być używana 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 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 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ń aktywacji w implementacji Multi-HAL należy uzyskać i przekazać postEvents
zablokowany ograniczony blokadę aktywacji.
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 Sensors 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
Aby ustanowić wywołanie zwrotne między implementacją sub-HAL a implementacją Multi-HAL, musi być obsługiwana funkcja initialize()
.
Udostępnij dostępne czujniki
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.
Publikuj zdarzenia z czujników w 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 1.0 interfejs HAL może zarządzać blokadą aktywacji w ramach swojej 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ń aktywacji w implementacji Multi-HAL należy uzyskać i przekazać postEvents
zablokowany ograniczony blokadę aktywacji.
Czujniki dynamiczne
W HAL 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ę 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 Czujnika Multi-HAL 1.0
Aby przenieść istniejące rozwiązanie 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ń wszystkie odwołania do
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 docelowy interfejs HAL, wykonaj czynności opisane w punktach 3 i 4 w sekcji Wdrażanie interfejsu Sensors Multi-HAL 2.0.
Weryfikacja
Uruchamianie 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 tego interfejsu spełniają wszystkie wymagania określone w interfejsie Sensors HAL.
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 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 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 wykorzystaniem fałszywych sub-HAL
Fałszywe sub-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
na podstawie interwałów określonych w danym żądaniu czujnika.
Używając fałszywych podsystemów HAL, można testować, jak działa pełny kod Multi-HAL z innymi wczytanymi do systemu podsystemami HAL, 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ć fałszywe sub-HAL i przesłać je 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 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 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 instancji HalProxy
i jej podrzędnych list 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 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ń. Wskazuje to, ż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 aktywacji jest większa niż 0
, oznacza to, że HalProxy
uzyskała blokadę aktywacji. 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 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
.