Dynamicznie dostępne warstwy HAL

Android 9 obsługuje dynamiczne zamykanie podsystemów sprzętowych Androida, gdy nie są one używane lub potrzebne. Na przykład, jeśli użytkownik nie korzysta z Wi-Fi, podsystemy Wi-Fi nie powinny zużywać pamięci, energii ani innych zasobów systemowych. We wcześniejszych wersjach Androida warstwy HAL/sterowniki były otwarte na urządzeniach z Androidem przez cały czas uruchamiania telefonu z Androidem.

Implementacja dynamicznego zamykania obejmuje okablowanie przepływów danych i wykonywanie procesów dynamicznych, jak opisano szczegółowo w poniższych sekcjach.

Zmiany w definicjach HAL

Dynamiczne zamykanie wymaga informacji o tym, które procesy obsługują jakie interfejsy HAL (ta informacja może być również przydatna później w innych kontekstach), a także nieuruchamiania procesów podczas rozruchu i nieuruchamiania ich ponownie (dopóki nie zostanie ponownie zażądane) po zakończeniu.

# some init.rc script associated with the HAL
service vendor.some-service-name /vendor/bin/hw/some-binary-service
    # init language extension, provides information of what service is served
    # if multiple interfaces are served, they can be specified one on each line
    interface android.hardware.light@2.0::ILight default
    # restarted if hwservicemanager dies
    # would also cause the hal to start early during boot if disabled wasn't set
    class hal
    # will not be restarted if it exits until it is requested to be restarted
    oneshot
    # will only be started when requested
    disabled
    # ... other properties

Zmiany w init i hwservicemanager

Dynamiczne zamykanie wymaga również, aby hwservicemanager wydał polecenie init , aby uruchomił żądane usługi. W Androidzie 9 init zawiera trzy dodatkowe komunikaty sterujące (np. ctl.start ): ctl.interface_start , ctl.interface_stop i ctl.interface_restart . Komunikaty te mogą być użyte do sygnalizowania init w celu wywołania lub wyłączenia określonych interfejsów sprzętowych. Gdy żądana jest usługa, która nie jest zarejestrowana, hwservicemanager żąda uruchomienia usługi. Jednak dynamiczne warstwy HAL nie wymagają użycia żadnego z nich.

Określ wyjście HAL

W systemie Android 9 wyjście HAL należy określić ręcznie. W przypadku Androida 10 i nowszych można to również określić za pomocą automatycznych cykli życia .

Dynamiczne zamykanie wymaga wielu zasad decydujących o tym, kiedy uruchomić warstwę HAL, a kiedy zamknąć warstwę HAL. Jeśli warstwa HAL z jakiegokolwiek powodu zdecyduje się zakończyć, zostanie automatycznie uruchomiona ponownie, gdy będzie potrzebna ponownie, korzystając z informacji podanych w definicji warstwy HAL oraz infrastruktury zapewnianej przez zmiany w init i hwservicemanager . Może to obejmować kilka różnych strategii, w tym:

  • HAL może wywołać na sobie wyjście, jeśli ktoś wywoła na nim bliski lub podobny interfejs API. To zachowanie musi zostać określone w odpowiednim interfejsie HAL.
  • Warstwy HAL mogą zostać zamknięte po zakończeniu zadania (udokumentowane w pliku HAL).

Automatyczne cykle życia

Android 10 dodaje więcej obsługi jądra i hwservicemanager , co pozwala warstwom HAL na automatyczne zamykanie, gdy nie mają one klientów. Aby skorzystać z tej funkcji, wykonaj wszystkie kroki opisane w sekcji Zmiany w definicjach HAL, a także:

  • Zarejestruj usługę w C++ za pomocą LazyServiceRegistrar zamiast funkcji członkowskiej registerAsService , na przykład:
    // only one instance of LazyServiceRegistrar per process
    LazyServiceRegistrar registrar;
    registrar.registerAsService(myHidlService /* , "default" */);
  • Sprawdź, czy klient HAL przechowuje odniesienie do HAL najwyższego poziomu (interfejs zarejestrowany w hwservicemanager ) tylko wtedy, gdy jest używany. Aby uniknąć opóźnień, jeśli to odwołanie zostanie usunięte w wątku hwbinder, który będzie nadal wykonywany, klient powinien także wywołać funkcję IPCThreadState::self()->flushCommands() po usunięciu odniesienia, aby upewnić się, że sterownik bindera zostanie powiadomiony o liczbie powiązanych odwołań zmiany.