Aparat

Ikona HAL aparatu na Androidzie

Warstwa abstrakcji sprzętu aparatu (HAL) na Androidzie łączy interfejsy API platformy aparatu wyższego poziomu w  Camera 2 z podstawowym sterownikiem i sprzętem aparatu. Podsystem aparatu obejmuje implementacje komponentów potoku aparatu, a warstwa HAL aparatu udostępnia interfejsy do implementowania własnej wersji tych komponentów.

Architektura

Na poniższym rysunku i liście opisano komponenty HAL.

Architektura aparatu na Androidzie

Rysunek 1. Architektura aparatu

platforma aplikacji
Na poziomie struktury aplikacji znajduje się kod aplikacji, który korzysta z interfejsu Camera 2 API do interakcji ze sprzętem aparatu. Wewnętrznie ten kod wywołuje odpowiednie interfejsy Bindera, aby uzyskać dostęp do kodu natywnego, który wchodzi w interakcję z aparatem.
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, aby uzyskać dostęp do fizycznego aparatu, i zwraca dane, które są używane do tworzenia obiektów CameraDevice i ostatecznie CameraCaptureSession na poziomie platformy.
platforma natywna,
Ta platforma znajdująca się w frameworks/av/ zapewnia natywny odpowiednik klas CameraDevice CameraCaptureSession. Zobacz też Dokumentacja NDK camera2.
interfejs IPC narzędzia do łączenia
Interfejs IPC Binder ułatwia komunikację między procesami. W katalogu frameworks/av/camera/camera/aidl/android/hardware znajduje się kilka klas powiązań kamery, które wywołują usługę kamery. ICameraService to interfejs usługi aparatu; ICameraDeviceUser to interfejs konkretnego otwartego urządzenia z aparatem; oraz ICameraServiceListener i ICameraDeviceCallbacks to odpowiednie wywołania zwrotne CameraServiceCameraDevice do platformy aplikacji.
usługa kamery
Usługa aparatu, która znajduje się w frameworks/av/services/camera/libcameraservice/CameraService.cpp,frameworks/av/services/camera/libcameraservice/CameraService.cpp to kod, który wchodzi w interakcje z HAL.
HAL
Warstwa abstrakcji sprzętu definiuje standardowy interfejs, do którego wywołuje się usługę aparatu i który musisz wdrożyć, aby sprzęt aparatu działał prawidłowo.

Wdrażanie interfejsu HAL

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

Typowy HAL z interfejsem Binder musi implementować te interfejsy HIDL:

Referencyjne implementacje HIDL są dostępne dla urządzeń CameraProvider.cpp, CameraDevice.cppCameraDeviceSession.cpp. Implementacja obejmuje starsze warstwy HAL, które nadal korzystają z interfejsu API starszego typu. Od Androida 8.0 implementacje HAL aparatu muszą korzystać z interfejsu HIDL API. Używanie starszego interfejsu nie jest obsługiwane.

Weryfikacja danych wejściowych

HAL ma dostęp do innych zasobów niż usługa aparatu, dlatego granica między nimi jest traktowana jako granica bezpieczeństwa. Oznacza to, że parametry przekazywane z usługi aparatu są uznawane za niezaufane i nieoczyszczone. Aby zapobiec lukom w zabezpieczeniach, które umożliwiają atakującym podniesienie uprawnień lub uzyskanie dostępu do danych, do których nie powinni mieć dostępu, warstwa HAL aparatu musi weryfikować parametry przekazywane z usługi aparatu do warstwy HAL. Obejmuje to sprawdzanie, czy wartości długości bufora mieszczą się w dozwolonych zakresach, oraz oczyszczanie parametrów przed użyciem i przekazaniem ich do sterowników sprzętu lub jądra.

Starsze komponenty HAL

W tej sekcji opisujemy architekturę starszych komponentów HAL i sposób implementacji HAL. Implementacje HAL aparatu na Androidzie 8.0 i nowszym muszą zamiast tego używać interfejsu HIDL API opisanego powyżej.

Architektura (starsza wersja)

Na poniższym rysunku i liście opisano starsze komponenty HAL aparatu.

Architektura aparatu na Androidzie

Rysunek 2. Starsza architektura aparatu

platforma aplikacji
Na poziomie struktury aplikacji znajduje się kod aplikacji, który korzysta z interfejsu API android.hardware.Camera, aby wchodzić w interakcje ze sprzętem aparatu. Wewnętrznie ten kod wywołuje odpowiednią klasę JNI, aby uzyskać dostęp do kodu natywnego, który wchodzi w interakcję z aparatem.
JNI
Kod JNI powiązany z właściwością android.hardware.Camera znajduje się w frameworks/base/core/jni/android_hardware_Camera.cpp. Ten kod wywołuje kod natywny niższego poziomu, aby uzyskać dostęp do fizycznego aparatu, i zwraca dane, które są używane do utworzenia obiektu android.hardware.Camera na poziomie platformy.
platforma natywna,
Platforma natywna zdefiniowana w frameworks/av/camera/Camera.cpp zapewnia natywny odpowiednik klasy android.hardware.Camera. Ta klasa wywołuje proxy interfejsu IPC, aby uzyskać dostęp do usługi aparatu.
serwery proxy IPC do łączenia
Pełnomocnicy IPC ułatwiają komunikację między procesami. W katalogu frameworks/av/camera znajdują się 3 klasy powiązań aparatu, które wywołują usługę aparatu. ICameraService to interfejs usługi aparatu, ICamera to interfejs konkretnego otwartego urządzenia z aparatem, a ICameraClient to interfejs urządzenia z powrotem do struktury aplikacji.
usługa kamery
Usługa aparatu, która znajduje się w frameworks/av/services/camera/libcameraservice/CameraService.cpp,frameworks/av/services/camera/libcameraservice/CameraService.cpp to kod, który wchodzi w interakcje z HAL.
HAL
Warstwa abstrakcji sprzętu definiuje standardowy interfejs, do którego wywołuje się usługę aparatu i który musisz wdrożyć, aby sprzęt aparatu działał prawidłowo.
sterownik jądra
Sterownik kamery współpracuje z rzeczywistym sprzętem kamery i Twoją implementacją HAL. Aby można było wyświetlać obraz z kamery na ekranie i nagrywać filmy, kamera i sterownik muszą obsługiwać formaty obrazu YV12 i NV21.

Implementowanie interfejsu HAL (starsza wersja)

Warstwa HAL znajduje się między sterownikiem aparatu a platformą Android wyższego poziomu i definiuje interfejs, który musisz zaimplementować, aby aplikacje mogły prawidłowo obsługiwać sprzęt aparatu. Interfejs HAL jest zdefiniowany w plikach nagłówkowych 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 aparacie, takich jak identyfikator aparatu i właściwości wspólne dla wszystkich aparatów (czyli czy jest to aparat skierowany do przodu czy do 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. Dokumentację parametrów kamery, które deweloperzy mogą ustawiać, znajdziesz w frameworks/av/include/camera/CameraParameters.h. Te parametry są ustawiane za pomocą funkcji wskazywanej przez int (*set_parameters)(struct camera_device *, const char *parms) w HAL.

Przykład implementacji HAL znajdziesz w hardware/ti/omap4xxx/camera.

Konfigurowanie biblioteki udostępnionej

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

  1. Utwórz katalog device/<company_name>/<device_name>/camera, w którym będą przechowywane pliki źródłowe biblioteki.
  2. Utwórz plik Android.mk, aby utworzyć bibliotekę udostępnioną. Upewnij się, że plik makefile zawiera te wiersze:
    LOCAL_MODULE := camera.<device_name>
    LOCAL_MODULE_RELATIVE_PATH := hw
    

    Biblioteka musi mieć nazwę camera.<device_name> (.so jest dodawane automatycznie), aby Android mógł ją prawidłowo wczytać. Przykład znajdziesz w pliku makefile aparatu Galaxy Nexus w lokalizacji hardware/ti/omap4xxx/Android.mk.

  3. Określ, że urządzenie ma funkcje aparatu, kopiując niezbędne pliki XML funkcji do katalogu frameworks/native/data/etc w pliku makefile urządzenia. Aby na przykład określić, że urządzenie ma lampę błyskową i może automatycznie ustawiać ostrość, dodaj te wiersze do pliku makefile urządzenia:<device>/<company_name>/<device_name>/device.mk
    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 \
    

    Przykładowy plik makefile urządzenia znajdziesz na stronie device/samsung/tuna/device.mk.

  4. Zadeklaruj kodek multimedialny, format i rozdzielczość aparatu w plikach XML device/<company_name>/<device_name>/media_profiles.xmldevice/<company_name>/<device_name>/media_codecs.xml. Szczegółowe informacje znajdziesz w artykule Udostępnianie kodeków w frameworku.
  5. Dodaj te wiersze do pliku makefile urządzenia,device/<company_name>/<device_name>/device.mk aby skopiować pliki media_profiles.xmlmedia_codecs.xmldevice/<company_name>/<device_name>/device.mk 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 uwzględnić aplikację Aparat w obrazie systemu urządzenia, określ ją w zmiennej PRODUCT_PACKAGES w pliku device/<company>/<device>/device.mk makefile urządzenia:
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...