Aparat

Ikona HAL aparatu Android

Warstwa abstrakcji sprzętu aparatu (HAL) systemu Android łączy interfejsy API aparatu wyższego poziomu w aparacie 2 z podstawowym sterownikiem aparatu i sprzętem. Podsystem kamery obejmuje implementacje komponentów potoku kamery, podczas gdy warstwa HAL kamery udostępnia interfejsy do użycia podczas implementacji tych komponentów.

Architektura

Poniższy rysunek i lista opisują składniki HAL.

Architektura aparatu Android

Rysunek 1. Architektura kamery

struktura aplikacji
Na poziomie struktury aplikacji znajduje się kod aplikacji, który wykorzystuje interfejs API Camera 2 do interakcji ze sprzętem kamery. Wewnętrznie ten kod wywołuje odpowiednie interfejsy Bindera , aby uzyskać dostęp do kodu natywnego, który współdziała z kamerą.
AIDL
Interfejs bindera powiązany z CameraService można znaleźć w frameworks/av/camera/aidl/android/hardware . Wygenerowany kod wywołuje kod natywny niższego poziomu w celu uzyskania dostępu do fizycznej kamery i zwraca dane, które są używane do tworzenia obiektów CameraDevice i ostatecznie CameraCaptureSession na poziomie struktury.
natywna platforma
Ten framework znajdujący się w frameworks/av/ zapewnia natywny odpowiednik klas CameraDevice i CameraCaptureSession . Zobacz także odniesienie NDK camera2 .
interfejs IPC spoiwa
Interfejs bindera IPC ułatwia komunikację ponad granicami procesu. W katalogu frameworks/av/camera/camera/aidl/android/hardware znajduje się kilka klas aparatu, które odwołują się do usługi aparatu. ICameraService to interfejs do usługi aparatu; ICameraDeviceUser to interfejs do określonego otwartego urządzenia z kamerą; a ICameraServiceListener i ICameraDeviceCallbacks to odpowiednie wywołania zwrotne CameraService i CameraDevice do struktury aplikacji.
serwis kamer
Usługa aparatu, znajdująca się w frameworks/av/services/camera/libcameraservice/CameraService.cpp , to rzeczywisty kod, który współdziała z warstwą HAL.
HAL
Warstwa abstrakcji sprzętu definiuje standardowy interfejs, do którego odwołuje się usługa kamery i który należy zaimplementować, aby sprzęt kamery działał poprawnie.

Wdrażanie HAL

HAL znajduje się między sterownikiem aparatu a platformą Android wyższego poziomu i definiuje interfejs, który należy zaimplementować, aby aplikacje mogły poprawnie obsługiwać sprzęt aparatu. Interfejsy HIDL dla warstwy HAL kamery są zdefiniowane w hardware/interfaces/camera .

Typowa zbindowana warstwa HAL musi implementować następujące interfejsy HIDL:

Referencyjne implementacje HIDL są dostępne dla CameraProvider.cpp , CameraDevice.cpp i CameraDeviceSession.cpp . Implementacja obejmuje stare warstwy HAL, które nadal korzystają ze starszego interfejsu API . Począwszy od systemu Android 8.0, implementacje Camera HAL muszą używać interfejsu API HIDL; korzystanie ze starszego interfejsu nie jest obsługiwane.

Walidacja danych wejściowych

Ponieważ warstwa HAL ma dostęp do innych zasobów niż usługa kamery, granica między nimi jest traktowana jako granica bezpieczeństwa. Oznacza to, że parametry przekazywane z usługi aparatu są uważane za niezaufane i nieodkażone. Aby zapobiec lukom w zabezpieczeniach, które umożliwiają atakującym eskalowanie uprawnień lub uzyskiwanie dostępu do danych, do których nie mają mieć dostępu, warstwa HAL kamery musi sprawdzać poprawność parametrów przekazywanych z usługi kamery do warstwy HAL. Obejmuje to sprawdzanie, czy wartości długości buforu mieszczą się w dopuszczalnych zakresach i oczyszczanie parametrów przed użyciem i przed przekazaniem ich do sterowników sprzętu lub jądra.

Starsze komponenty HAL

W tej sekcji opisano architekturę starszych składników warstwy HAL oraz sposób implementacji warstwy HAL. Implementacje warstwy HAL aparatu w systemie Android 8.0 i nowszych muszą zamiast tego używać interfejsu API HIDL, opisanego powyżej.

Architektura (starsza)

Poniższy rysunek i lista opisują starsze komponenty HAL kamery.

Architektura aparatu Android

Rysunek 2. Starsza architektura kamery

struktura aplikacji
Na poziomie struktury aplikacji znajduje się kod aplikacji, który wykorzystuje interfejs API android.hardware.Camera do interakcji ze sprzętem kamery. Wewnętrznie ten kod wywołuje odpowiednią klasę kleju JNI, aby uzyskać dostęp do kodu natywnego, który współdziała z kamerą.
JNI
Kod JNI powiązany z android.hardware.Camera znajduje się w frameworks/base/core/jni/android_hardware_Camera.cpp . Ten kod wywołuje kod natywny niższego poziomu w celu uzyskania dostępu do fizycznej kamery i zwraca dane używane do tworzenia obiektu android.hardware.Camera na poziomie struktury.
natywna platforma
Natywna platforma zdefiniowana w frameworks/av/camera/Camera.cpp zapewnia natywny odpowiednik klasy android.hardware.Camera . Ta klasa wywołuje serwery proxy IPC binder, aby uzyskać dostęp do usługi aparatu.
proxy IPC segregatora
Serwery proxy IPC ułatwiają komunikację ponad granicami procesu. Istnieją trzy klasy powiązania aparatu, które znajdują się w katalogu frameworks/av/camera , który wywołuje usługę aparatu. ICameraService to interfejs do usługi aparatu, ICamera to interfejs do określonego otwartego urządzenia z aparatem, a ICameraClient to interfejs urządzenia z powrotem do struktury aplikacji.
serwis kamer
Usługa aparatu, znajdująca się w frameworks/av/services/camera/libcameraservice/CameraService.cpp , to rzeczywisty kod, który współdziała z warstwą HAL.
HAL
Warstwa abstrakcji sprzętu definiuje standardowy interfejs, do którego odwołuje się usługa kamery i który należy zaimplementować, aby sprzęt kamery działał poprawnie.
sterownik jądra
Sterownik kamery współdziała z rzeczywistym sprzętem kamery i implementacją warstwy HAL. Kamera i sterownik muszą obsługiwać formaty obrazu YV12 i NV21, aby zapewnić obsługę podglądu obrazu z kamery na wyświetlaczu i nagrywania wideo.

Wdrażanie HAL (starsze)

HAL znajduje się między sterownikiem aparatu a platformą Android wyższego poziomu i definiuje interfejs, który należy zaimplementować, aby aplikacje mogły poprawnie obsługiwać sprzęt aparatu. Interfejs HAL jest zdefiniowany w hardware/libhardware/include/hardware/camera.h i hardware/libhardware/include/hardware/camera_common.h .

camera_common.h definiuje camera_module , standardową strukturę do uzyskiwania ogólnych informacji o kamerze, takich jak identyfikator kamery i właściwości wspólne dla wszystkich kamer (to znaczy, czy jest to kamera z przodu czy z tyłu).

camera.h zawiera kod odpowiadający android.hardware.Camera . Ten plik nagłówkowy deklaruje strukturę camera_device , która z kolei zawiera strukturę camera_device_ops ze wskaźnikami do funkcji implementujących interfejs HAL. Aby uzyskać dokumentację dotyczącą parametrów kamery, które programiści mogą ustawić, zapoznaj się z frameworks/av/include/camera/CameraParameters.h . Parametry te są ustawiane za pomocą funkcji wskazywanej przez int (*set_parameters)(struct camera_device *, const char *parms) w warstwie HAL.

Aby zapoznać się z przykładem implementacji warstwy HAL, zapoznaj się z implementacją warstwy HAL Galaxy Nexus w hardware/ti/omap4xxx/camera .

Konfiguracja biblioteki współdzielonej

Skonfiguruj system kompilacji Androida, aby poprawnie spakować implementację HAL do biblioteki współdzielonej i skopiuj ją do odpowiedniej lokalizacji, tworząc plik Android.mk :

  1. Utwórz katalog device/<company_name>/<device_name>/camera , który będzie zawierał pliki źródłowe biblioteki.
  2. Utwórz plik Android.mk , aby zbudować bibliotekę współdzieloną. Upewnij się, że plik makefile zawiera następujące wiersze:
    LOCAL_MODULE := camera.<device_name>
    LOCAL_MODULE_RELATIVE_PATH := hw
    

    Twoja biblioteka musi mieć nazwę camera.<device_name> ( .so jest dodawane automatycznie), aby system Android mógł poprawnie załadować bibliotekę. Na przykład zobacz plik makefile dla aparatu Galaxy Nexus znajdujący się w hardware/ti/omap4xxx/Android.mk .

  3. Określ, czy Twoje urządzenie ma funkcje aparatu, kopiując niezbędne pliki XML funkcji do katalogu frameworks/native/data/etc z plikiem makefile urządzenia. Na przykład, aby określić, że urządzenie ma lampę błyskową aparatu i może autofokus, dodaj następujące wiersze w pliku <device>/<company_name>/<device_name>/device.mk makefile:
    PRODUCT_COPY_FILES := \ ...
    
    PRODUCT_COPY_FILES += \
    frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \
    

    Aby zapoznać się z przykładem pliku makefile urządzenia, zobacz device/samsung/tuna/device.mk .

  4. Zadeklaruj kodek, format i rozdzielczość aparatu w plikach XML device/<company_name>/<device_name>/media_profiles.xml i device/<company_name>/<device_name>/media_codecs.xml . Aby uzyskać szczegółowe informacje, zobacz Udostępnianie kodeków do frameworka .
  5. Dodaj następujące wiersze w urządzeniu device/<company_name>/<device_name>/device.mk makefile, aby skopiować pliki media_profiles.xml i media_codecs.xml do odpowiedniej lokalizacji:
    # media config xml file
    PRODUCT_COPY_FILES += \
        <device>/<company>/<device>/media_profiles.xml:system/etc/media_profiles.xml
    
    # media codec config xml file
    PRODUCT_COPY_FILES += \
        <device>/<company>/<device>/media_codecs.xml:system/etc/media_codecs.xml
    
  6. Aby dołączyć aplikację Aparat do obrazu systemu urządzenia, określ ją w zmiennej PRODUCT_PACKAGES w urządzeniu device/<company>/<device>/device.mk makefile:
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...