Czujniki Multi-HAL

Multi-HAL czujników to framework, który umożliwia uruchamianie HAL-i czujników wraz z innymi HAL-ami czujników. Interfejs wielopoziomowych czujników dynamicznie wczytuje podinterfejsy czujników przechowywane jako dynamiczne biblioteki w partycji dostawcy i przekazuje im obiekt wywołania, 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 interfejs wielopoziomowego interfejsu HAL. Te podrzędne HAL-e nie zależą od siebie nawzajem ani od kodu wielorzędowego HAL, który zawiera główną funkcję procesu.

Czujniki Multi-HAL 2.1, dostępne na urządzeniach z Androidem 11 lub wyższej, jest powtórzenia interfejsu Sensors Multi-HAL 2.0, który obsługuje wczytywanie podrzędnych list HAL, które mogą ujawnić kąt zawiasu typu czujnika. Aby obsługiwać ten typ czujnika, podrzędne interfejsy HAL muszą używać interfejsów API podrzędnych HAL. zdefiniowane w 2.1 Nagłówek SubHal.

Na urządzeniach z Androidem 13 lub nowszym, na których: HAL AIDL, możesz użyć podkładka z wieloma HAL, która umożliwia obsługę wielu HAL. Szczegóły implementacji: zobacz Korzystanie z czujników Multi-HAL z czujnikami 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 inicjowania przekazuje IHalProxyCallback zamiast dwóch FMQ i ISensorsCallback.
  • Sub-HALs musi 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 wprowadzenia FMQ, IHalProxyCallback udostępnia 2 metody – jedną z nich do wysyłania zdarzeń z czujników do czujników. oraz jedną metodę 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 wygaszaniem blokady na czas trwania blokady na rzecz interfejsu Sensors Multi-HAL i zcentralizować używanie blokady na rzecz całego interfejsu Sensors Multi-HAL, co zminimalizuje wywołania blokady i odblokowania.

Sensory Multi-HAL 2 mają też wbudowane funkcje bezpieczeństwa. Obsługuje gdy czujnik FMQ jest pełny lub gdy uruchomi się ponownie i trzeba zresetować stan czujnika. Ponadto, jeśli zdarzenia są została opublikowana w klasie HalProxy, ale platforma czujnika nie akceptuje zdarzenia od razu, funkcja Sensors Multi-HAL może przenieść je w tle w wątku, aby umożliwić kontynuowanie pracy na wszystkich podrzędnych listach HAL podczas oczekiwania na wydarzenia, które mają zostać opublikowane.

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 wskazówek dotyczących przydatnych materiałów.

  • HalProxy.h: obiekt HalProxy jest tworzony przez wieloplatformowy interfejs API czujników i przekazuje dane z interfejsów podrzędnych do interfejsu sensora.
  • HalProxy.cpp: Implementacja HalProxy zawiera całą logikę potrzebną do multipleksowania komunikacji między podsystemami HAL i ramką czujnika.
  • SubHal.h: Interfejs ISensorsSubHal definiuje interfejs, którego podsystemy HAL muszą przestrzegać, aby być zgodnymi z HalProxy. Sub-HAL implementuje metodę initialize, aby obiekt HalProxyCallback można było używać w przypadku postEventscreateScopedWakelock.

    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/: Ta przykładowa implementacja sub-HAL wykorzystuje fałszywe czujniki, aby wygenerować fałszywe i skalowalnych 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ć rozwiązanie Czujniki Multi-HAL w następujących sekcjach: w sytuacjach:

Używaj czujników Multi-HAL z czujnikami AIDL HAL

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 czujnikami AIDL i HIDL i definiuje otokę wokół interfejsu HAL opisanego w Implementacja czujników Multi-HAL 2.1. Multi-HAL AIDL warstwa podkładkowa jest zgodna z urządzeniami z obsługą Sensors Multi-HAL 2.1.

Warstwa podkładek AIDL multi-HAL pozwala odsłonić tracker na głowie Ograniczone typy czujników IMU w interfejsie Sensors AIDL HAL. Aby użyć tego czujnika zdefiniowane przez interfejs AIDL HAL, ustaw pole type w Struktura 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ą.

Zastosuj czujniki Multi-HAL 2.1

Aby wdrożyć Sensors Multi-HAL 2.1 na nowym urządzeniu, wykonaj te czynności:

  1. Zaimplementuj interfejs ISensorsSubHal, tak jak to opisano w SubHal.h
  2. Zaimplementuj tag sensorsHalGetSubHal_2_1 w metodzie SubHal.h.
  3. Dodaj cel cc_library_shared, aby utworzyć nowo wdrożoną podrzędną listę klientów (HAL). Podczas dodawania środowiska docelowego:

    1. Upewnij się, że docelowy element jest przesyłany do jakiegoś miejsca na partycji dostawcy na urządzeniu.
    2. W pliku konfiguracyjnym znajdującym się w lokalizacji /vendor/etc/sensors/hals.conf dodaj ścieżkę do biblioteki w nowym wierszu. W razie potrzeby utwórz hals.conf.

    Przykładowy wpis Android.bp dotyczący tworzenia biblioteki podrzędnej HAL znajdziesz tutaj hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp

  4. Usuń wszystkie wpisy android.hardware.sensors z pliku manifest.xml, który zawiera listę obsługiwanych interfejsów HAL na urządzeniu.

  5. Usuń wszystkie usługi android.hardware.sensors i service.rc pliki z plik device.mk i dodaj do niego android.hardware.sensors@2.1-service.multihal i android.hardware.sensors@2.1-service.multihal.rc do PRODUCT_PACKAGES.

Podczas uruchamiania HalProxy szuka nowo zaimplementowanego podsystemu HAL i inicjuje go, wywołując sensorsHalGetSubHal_2_1.

Przenoszenie z Sensors Multi-HAL 2.0 do Multi-HAL 2.1

Aby przenieść kod 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 specyfikacji ISensors.hal.
  • Funkcja initialize() przekazuje nowy IHalProxyCallback. zamiast interfejsu 2.0 SubHal.
  • Sub-HAL musi implementować getSensorsList_2_1 i injectSensorData_2_1 zamiast getSensorsList i injectSensorData, ponieważ te metody używają nowe typy dodane w wersji 2.1 specyfikacji ISensors.hal.
  • Sub-HAL musi udostępniać element sensorsHalGetSubHal_2_1, a nie sensorsHalGetSubHal dla multi-HAL, aby traktować je jako wersję 2.1 sub-HAL.

Przenoszenie z Sensors 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 przekazywać sygnały FMQ i dynamiczne wywołanie zwrotne czujnika. W interfejsie Sensors Multi-HAL 2.0 Funkcja initialize() przekazuje jedno wywołanie zwrotne, które musi zostać użyte do opublikowania zdarzeń z czujników, uzyskiwanie blokad uśpienia oraz powiadamianie o dynamicznym połączeniu z czujnikiem oraz odłączania kont.

Publikuj zdarzenia z czujników w implementacji Multi-HAL

Zamiast publikować zdarzenia z czujników przez FMQ, interfejs podrzędny HAL musi zapisywać dane czujnika wydarzeń na IHalProxyCallback gdy dostępne są zdarzenia z czujnika.

Zdarzenia WAKE_UP

W interfejsie HAL 2.0 interfejs HAL może zarządzać blokadą aktywacji w ramach swojej implementacji. W interfejsie Multi-HAL 2.0 interfejsy podrzędne umożliwiają zarządzanie blokadami uśpienia przez interfejs Multi-HAL i możliwość żądania blokady uśpienia przez wywołanie interfejsu createScopedWakelock. Blokada uśpienia o zakresie zablokowanym musi zostać uzyskana i przekazana do postEvents, gdy publikowanie zdarzeń wybudzenia w implementacji Multi-HAL.

Czujniki dynamiczne

Czujniki Multi-HAL 2.0 wymagają tych elementów: onDynamicSensorsConnected i onDynamicSensorsDisconnected in IHalProxyCallback są wywoływane zawsze, gdy zmienią się dynamiczne połączenia czujnika. Te funkcje wywołania zwrotnego 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 HAL 1.0 na wersję 2.0 interfejsu HAL dla czujników upewnij się, że implementacja HAL spełnia te wymagania.

Inicjowanie HAL

Funkcja initialize() musi być obsługiwana, aby ustanowić wywołanie zwrotne między implementacją sub-HAL a implementacją Multi-HAL.

Udostępnianie dostępnych czujników

W ramach interfejsu 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ść zwrócona przez funkcję getSensorsList() może się zmienić, gdy urządzenie po ponownym uruchomieniu.

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 przypadku interfejsu Sensors HAL 1.0 HAL może zarządzać blokadą uśpienia w celu jej implementacji. W ramach interfejsu Sensory Multi-HAL 2.0 interfejsy podrzędne umożliwiają zarządzanie blokadami uśpienia i można za ich pomocą poprosić o uzyskanie blokady uśpienia (wywołaniecreateScopedWakelock). 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 onDynamicSensorsConnectedonDynamicSensorsDisconnectedIHalProxyCallback były wywoływane za każdym razem, gdy zmieniają się dynamiczne połączenia czujników. Te funkcje wywołania zwrotnego 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ącą implementację z: Czujniki Multi-HAL 1.0, wykonaj te czynności.

  1. 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.
  2. Usuń wszelkie odniesienia do hardware/hardware.h oraz hardware/sensors.h , które nie są obsługiwane w przypadku HAL 2.0.
  3. Sub-HAL portów zgodnie z opisem w sekcji Przenoszenie z Sensors Hal 1,0.
  4. Ustaw Sensors Multi-HAL 2.0 jako wyznaczoną HAL, wykonując kroki 3 i 4 w sekcji Implementowanie czujników Mutli-HAL 2.0.

Weryfikacja

Uruchom VTS

Po zintegrowaniu co najmniej 1 interfejsu HAL podrzędnego z interfejsem Sensors Multi-HAL 2.1 użyj pakietu testów dostawcy (VTS), aby sprawdzić, czy implementacje interfejsu HAL podrzędnego spełniają wszystkie wymagania określone przez interfejs 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 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ą aktywne, okresowo publikują automatycznie wygenerowane zdarzenia dotyczące czujnika w usłudze HalProxy na podstawie odstępó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.

2 fałszywe sub-HAL są dostępne na hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/

Aby utworzyć fałszywe sub-HAL i przesłać je na urządzenie, wykonaj te czynności:

  1. Uruchom następujące polecenia, aby utworzyć i przekazać 3 różne fałszywe na urządzeniu:

    $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
  2. Zaktualizuj konfigurację HAL czujników w domenie /vendor/etc/sensors/hals.conf za pomocą ścieżek dla 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
    
  3. 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 klienta HalProxy i jego podrzędnych kont HAL będą dane wyjściowe 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 wartość podana w polu # of events on pending write queue to duża liczba (1000 lub więcej), oznacza to, że istnieje wiele zdarzeń oczekujących na zapisanie w czujnikach. platformy. Oznacza to, że usługa czujnika jest zablokowana lub uległa awarii, nie przetwarza zdarzeń czujnika lub że duża liczba takich zdarzeń opublikowane niedawno z sub-HAL.

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 od 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.