Aparat

Ikona interfejsu HAL aparatu na Androida

Warstwę abstrakcji sprzętu aparatu (HAL) w Androidzie łączy interfejsy API frameworku aparatu wyższego poziomu w  Camera 2 z podstawowym sterownikiem aparatu i sprzętem. Podsystem kamery zawiera implementacje komponentów potoku kamery, a interfejs HAL kamery udostępnia interfejsy do implementacji wersji tych komponentów.

Architektura

Na rysunku i w tabeli poniżej opisano komponenty HAL.

Architektura aparatu w Androidzie

Rysunek 1. Architektura kamery

platforma aplikacji
Na poziomie platformy aplikacji znajduje się kod aplikacji, który korzysta z interfejsu Camera 2 API do interakcji z sprzętem aparatu. Wewnętrznie ten kod wywołuje odpowiednie interfejsy Binder, aby uzyskać dostęp do kodu natywnego, który współpracuje z kamerą.
AIDL
Interfejs bindera powiązany z CameraService można znaleźć w folderze frameworks/av/camera/aidl/android/hardware. Wygenerowany kod wywołuje kod natywny niższego poziomu, aby uzyskać dostęp do fizycznej kamery, i zwraca dane, które są używane do tworzenia obiektów CameraDevice, a następnie obiektów CameraCaptureSession na poziomie frameworka.
platforma natywna
Ten framework, który znajduje się w frameworks/av/, zapewnia natywny odpowiednik klas CameraDevice CameraCaptureSession. Zobacz też dokumentację NDK camera2.
interfejs binder IPC,
Interfejs bindera IPC ułatwia komunikację między procesami. W katalogu frameworks/av/camera/camera/aidl/android/hardware znajduje się kilka klas łączników kamer, które wywołują usługę kamery. ICameraService to interfejs usługi aparatu; ICameraDeviceUser to interfejs konkretnego otwartego urządzenia z aparatem; ICameraServiceListener i ICameraDeviceCallbacks to odpowiednio wywołania zwrotne CameraServiceCameraDevice do frameworku aplikacji.
serwis kamery
Usługa aparatu, która znajduje się w pliku frameworks/av/services/camera/libcameraservice/CameraService.cpp, to kod, który współpracuje z interfejsem HAL.
HAL
Warstwa abstrakcji sprzętowej definiuje standardowy interfejs, do którego wywołuje usługa aparatu, i który musisz zaimplementować, aby sprzęt aparatu działał prawidłowo.

Wdrażanie interfejsu HAL

HAL znajduje się między sterownikiem aparatu a wyższym poziomem platformy Androida i określa interfejs, który musisz zaimplementować, aby aplikacje mogły prawidłowo obsługiwać sprzęt kamery. Interfejce HIDL dla interfejsu Camera HAL są zdefiniowane w katalogu hardware/interfaces/camera.

Typowy binderized HAL musi implementować te interfejsy HIDL:

Referencyjne implementacje HIDL są dostępne dla CameraProvider.cpp, CameraDevice.cpp i CameraDeviceSession.cpp. Implementacja zawiera stare interfejsy HAL, które nadal używają starego interfejsu API. Począwszy od Androida 8.0 implementacje interfejsu Camera HAL muszą używać interfejsu HIDL API; starszy interfejs nie jest obsługiwany.

weryfikacja danych wejściowych;

Ponieważ HAL ma dostęp do innych zasobów niż usługa aparatu, granica między nimi jest traktowana jako granica zabezpieczeń. Oznacza to, że parametry przekazywane przez usługę kamery są uważane za niezaufane i nieprzetworzone. Aby zapobiec podatnościom w zabezpieczeniach, które umożliwiają atakującym podniesienie uprawnień lub dostęp do danych, do których nie powinni mieć dostępu, interfejs HAL aparatu musi sprawdzać parametry przekazywane przez usługę aparatu do interfejsu HAL. Obejmuje to sprawdzanie, czy wartości długości bufora mieszczą się w dozwolonych zakresach, oraz sterylizację parametrów przed ich użyciem i przekazaniem do sterowników sprzętowych lub jądra.

Starsze komponenty HAL

W tej sekcji opisaliśmy architekturę starszych komponentów HAL i sposób ich implementacji. W implementacjach interfejsu HAL aparatu w systemie Android 8.0 lub nowszym należy zamiast tego używać interfejsu HIDL API, opisanego powyżej.

Architektura (starsza wersja)

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

Architektura aparatu w Androidzie

Rysunek 2. Starsza architektura kamery

platforma aplikacji
Na poziomie platformy aplikacji znajduje się kod aplikacji, który korzysta z interfejsu API android.hardware.Camera do interakcji z sprzętem aparatu. Wewnętrznie ten kod wywołuje odpowiednią klasę JNI glue, aby uzyskać dostęp do kodu natywnego, który współpracuje 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 niskiego poziomu, aby uzyskać dostęp do fizycznej kamery, i zwraca dane, które są używane do tworzenia obiektu android.hardware.Camera na poziomie frameworka.
platforma natywna
Natywny framework zdefiniowany w frameworks/av/camera/Camera.cpp zapewnia natywną odpowiedniczkę klasy android.hardware.Camera. Ta klasa wywołuje binder proxy IPC, aby uzyskać dostęp do usługi aparatu.
binder IPC proxies
Pośrednicy bindera IPC ułatwiają komunikację między procesami. W katalogu frameworks/av/camera znajdują się 3 klasy bindera 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, który łączy się z ramą aplikacji.
serwis kamery
Usługa aparatu, która znajduje się w pliku frameworks/av/services/camera/libcameraservice/CameraService.cpp, to kod, który współpracuje z interfejsem HAL.
HAL
Warstwa abstrakcji sprzętowej definiuje standardowy interfejs, do którego wywołuje usługa aparatu, i który musisz zaimplementować, aby sprzęt aparatu działał prawidłowo.
sterownik jądra
Sterownik kamery współpracuje z rzeczywistym sprzętem kamery i z Twoją implementacją interfejsu HAL. Kamera i sterownik muszą obsługiwać formaty obrazu YV12 i NV21, aby umożliwić podgląd obrazu z kamery na wyświetlaczu oraz nagrywanie filmów.

Zaimplementuj interfejs HAL (starsza wersja)

HAL znajduje się między sterownikiem aparatu a wyższym poziomem platformy Androida i określa interfejs, który musisz zaimplementować, aby aplikacje mogły prawidłowo obsługiwać sprzęt kamery. Interfejs HAL jest zdefiniowany w plikach nagłówka hardware/libhardware/include/hardware/camera.hhardware/libhardware/include/hardware/camera_common.h.

camera_common.h definiuje camera_module, standardową strukturę służącą do uzyskiwania ogólnych informacji o aparacie, takich jak identyfikator aparatu i właściwości wspólne dla wszystkich aparatów (czy jest to aparat skierowany do przodu czy do tyłu).

camera.h zawiera kod odpowiadający android.hardware.Camera. Ten plik nagłówka deklaruje strukturę camera_device, która z kolei zawiera strukturę camera_device_ops z wskaźnikami do funkcji implementujących interfejs HAL. Dokumentację dotyczącą parametrów aparatu, które mogą ustawiać deweloperzy, 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 pliku Galaxy Nexus HAL w pliku hardware/ti/omap4xxx/camera.

Konfigurowanie biblioteki udostępnionej

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

  1. Utwórz device/<company_name>/<device_name>/camera katalog, który będzie zawierać pliki źródłowe biblioteki.
  2. Utwórz plik Android.mk, aby zbudować zasoby wspólne. 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 pliku make dla kamery Galaxy Nexus, który znajduje się w folderze 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 za pomocą 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 <device>/<company_name>/<device_name>/device.mkmakefile urządzenia:
    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ład makefile urządzenia znajdziesz w artykule device/samsung/tuna/device.mk.

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