Kamera

Symbol für Android Camera HAL

Die Kamera-Hardware-Abstraktionsschicht (HAL) von Android verbindet die APIs des Kamera-Frameworks der höheren Ebene in Camera 2 mit dem zugrunde liegenden Kameratreiber und der zugrunde liegenden Hardware. Das Kamera-Subsystem enthält Implementierungen für Kamera-Pipeline-Komponenten, während die Kamera-HAL Schnittstellen für die Implementierung Ihrer Version dieser Komponenten bereitstellt.

Architektur

In der folgenden Abbildung und Liste werden die HAL-Komponenten beschrieben.

Android-Kameraarchitektur

Abbildung 1: Kameraarchitektur

App-Framework
Auf App-Framework-Ebene befindet sich der Code der App, der die Camera 2 API zur Interaktion mit der Kamerahardware verwendet. Intern ruft dieser Code entsprechende Binder-Schnittstellen auf, um auf den nativen Code zuzugreifen, der mit der Kamera interagiert.
AIDL
Die mit CameraService verknüpfte Binder-Benutzeroberfläche finden Sie unter frameworks/av/camera/aidl/android/hardware. Der generierte Code ruft den nativen Code der unteren Ebene auf, um Zugriff auf die physische Kamera zu erhalten, und gibt Daten zurück, die zum Erstellen der CameraDevice- und schließlich der CameraCaptureSession-Objekte auf Frameworkebene verwendet werden.
Natives Framework
Dieses Framework in frameworks/av/ bietet ein natives Äquivalent zu den Klassen CameraDevice und CameraCaptureSession. Siehe auch die Referenz für NDK camera2.
Binder-IPC-Schnittstelle
Die IPC-Binder-Schnittstelle erleichtert die Kommunikation über Prozessgrenzen hinweg. Im Verzeichnis frameworks/av/camera/camera/aidl/android/hardware befinden sich mehrere Kamera-Binder-Klassen, die den Kameradienst aufrufen. ICameraService ist die Schnittstelle zum Kameradienst; ICameraDeviceUser ist die Schnittstelle zu einem bestimmten geöffneten Kameragerät; und ICameraServiceListener und ICameraDeviceCallbacks sind die jeweiligen CameraService- und CameraDevice-Callbacks an das App-Framework.
Kameradienst
Der Kameradienst unter frameworks/av/services/camera/libcameraservice/CameraService.cpp ist der Code, der mit der HAL interagiert.
HAL
Die Hardwareabstraktionsschicht definiert die Standardschnittstelle, die vom Kameradienst aufgerufen wird und die Sie implementieren müssen, damit die Kamerahardware ordnungsgemäß funktioniert.

HAL implementieren

Die HAL befindet sich zwischen dem Kameratreiber und dem Android-Framework der höheren Ebene und definiert eine Schnittstelle, die Sie implementieren müssen, damit Apps die Kamerahardware richtig bedienen können. Die HIDL-Schnittstellen für die Kamera-HAL sind unter hardware/interfaces/camera definiert.

Ein typischer binderisierter HAL muss die folgenden HIDL-Schnittstellen implementieren:

Referenz-HIDL-Implementierungen sind für CameraProvider.cpp, CameraDevice.cpp und CameraDeviceSession.cpp verfügbar. Die Implementierung umschließt alte HALs, die noch die alte API verwenden. Ab Android 8.0 müssen Kamera-HAL-Implementierungen die HIDL API verwenden. Die Verwendung der alten Schnittstelle wird nicht unterstützt.

Eingabevalidierung

Da die HAL Zugriff auf andere Ressourcen als der Kameradienst hat, wird die Grenze zwischen den beiden als Sicherheitsgrenze behandelt. Das bedeutet, dass vom Kameradienst übergebene Parameter als nicht vertrauenswürdig und nicht bereinigt betrachtet werden. Um Sicherheitslücken zu verhindern, die es Angreifern ermöglichen, Berechtigungen zu erhöhen oder auf Daten zuzugreifen, auf die sie keinen Zugriff haben sollen, muss die HAL der Kamera Parameter validieren, die vom Kameradienst an die HAL übergeben werden. Dazu gehört auch die Prüfung, ob die Werte für die Pufferlänge innerhalb des zulässigen Bereichs liegen, und die Bereinigung der Parameter vor der Verwendung und vor der Weitergabe an Hardware- oder Kernel-Treiber.

Legacy HAL-Komponenten

In diesem Abschnitt wird die Architektur der bisherigen HAL-Komponenten und die Implementierung der HAL beschrieben. Für Kamera-HAL-Implementierungen unter Android 8.0 und höher muss stattdessen die oben beschriebene HIDL API verwendet werden.

Architektur (alt)

In der folgenden Abbildung und Liste werden die Komponenten der bisherigen HAL für Kameras beschrieben.

Android-Kameraarchitektur

Abbildung 2: Alte Kameraarchitektur

App-Framework
Auf App-Framework-Ebene befindet sich der Code der App, der die android.hardware.Camera API verwendet, um mit der Kamerahardware zu interagieren. Intern ruft dieser Code eine entsprechende JNI-Glue-Klasse auf, um auf den nativen Code zuzugreifen, der mit der Kamera interagiert.
JNI
Der JNI-Code, der mit android.hardware.Camera verknüpft ist, befindet sich in frameworks/base/core/jni/android_hardware_Camera.cpp. Dieser Code ruft den nativen Code der unteren Ebene auf, um Zugriff auf die physische Kamera zu erhalten, und gibt Daten zurück, mit denen das android.hardware.Camera-Objekt auf Frameworkebene erstellt wird.
Natives Framework
Das in frameworks/av/camera/Camera.cpp definierte native Framework ist ein natives Äquivalent zur Klasse android.hardware.Camera. Diese Klasse ruft die IPC-Binder-Proxys auf, um Zugriff auf den Kameradienst zu erhalten.
Binder-IPC-Proxys
Die IPC-Binder-Proxys erleichtern die Kommunikation über Prozessgrenzen hinweg. Im Verzeichnis frameworks/av/camera befinden sich drei Kamera-Binder-Klassen, die den Kameradienst aufrufen. ICameraService ist die Schnittstelle zum Kameradienst, ICamera die Schnittstelle zu einem bestimmten geöffneten Kameragerät und ICameraClient die Schnittstelle des Geräts zum App-Framework.
Kameradienst
Der Kameradienst unter frameworks/av/services/camera/libcameraservice/CameraService.cpp ist der Code, der mit der HAL interagiert.
HAL
Die Hardwareabstraktionsschicht definiert die Standardschnittstelle, die vom Kameradienst aufgerufen wird und die Sie implementieren müssen, damit die Kamerahardware ordnungsgemäß funktioniert.
Kerneltreiber
Der Kameratreiber interagiert mit der tatsächlichen Kamerahardware und Ihrer Implementierung der HAL. Die Kamera und der Treiber müssen die Bildformate YV12 und NV21 unterstützen, um die Vorschau des Kamerabilds auf dem Display und die Videoaufzeichnung zu ermöglichen.

HAL (alte Version) implementieren

Die HAL befindet sich zwischen dem Kameratreiber und dem Android-Framework der höheren Ebene und definiert eine Schnittstelle, die Sie implementieren müssen, damit Apps die Kamerahardware richtig bedienen können. Die HAL-Schnittstelle ist in den Headerdateien hardware/libhardware/include/hardware/camera.h und hardware/libhardware/include/hardware/camera_common.h definiert.

camera_common.h definiert camera_module, eine Standardstruktur, mit der allgemeine Informationen zur Kamera abgerufen werden können, z. B. die Kamera-ID und Eigenschaften, die für alle Kameras gleich sind (d. h. ob es sich um eine Front- oder Rückkamera handelt).

camera.h enthält Code, der android.hardware.Camera entspricht. In dieser Headerdatei wird ein camera_device-Typ deklariert, der wiederum einen camera_device_ops-Typ mit Verweis auf Funktionen enthält, die die HAL-Schnittstelle implementieren. Eine Dokumentation zu den Kameraparametern, die Entwickler festlegen können, finden Sie unter frameworks/av/include/camera/CameraParameters.h. Diese Parameter werden mit der Funktion festgelegt, auf die in der HAL mit int (*set_parameters)(struct camera_device *, const char *parms) verwiesen wird.

Ein Beispiel für eine HAL-Implementierung finden Sie in hardware/ti/omap4xxx/camera in der Implementierung für die Galaxy Nexus HAL.

Gemeinsam genutzte Bibliothek konfigurieren

Richten Sie das Android-Buildsystem so ein, dass die HAL-Implementierung korrekt in einer freigegebenen Bibliothek verpackt und an den richtigen Speicherort kopiert wird. Erstellen Sie dazu eine Android.mk-Datei:

  1. Erstellen Sie ein device/<company_name>/<device_name>/camera-Verzeichnis für die Quelldateien Ihrer Bibliothek.
  2. Erstellen Sie eine Android.mk-Datei, um die freigegebene Bibliothek zu erstellen. Das Makefile muss die folgenden Zeilen enthalten:
    LOCAL_MODULE := camera.<device_name>
    LOCAL_MODULE_RELATIVE_PATH := hw
    

    Ihre Bibliothek muss den Namen camera.<device_name> haben (.so wird automatisch angehängt), damit Android die Bibliothek korrekt laden kann. Ein Beispiel finden Sie im Makefile für die Kamera des Galaxy Nexus unter hardware/ti/omap4xxx/Android.mk.

  3. Geben Sie an, dass Ihr Gerät Kamerafunktionen hat, indem Sie die erforderlichen XML-Dateien der Funktionen in das Verzeichnis frameworks/native/data/etc mit dem Makefile Ihres Geräts kopieren. Wenn Sie beispielsweise angeben möchten, dass Ihr Gerät einen Kamerablitz hat und Autofokus unterstützt, fügen Sie der <device>/<company_name>/<device_name>/device.mk-Makefile Ihres Geräts die folgenden Zeilen hinzu:
    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 \
    

    Ein Beispiel für ein Geräte-Makefile finden Sie unter device/samsung/tuna/device.mk.

  4. Geben Sie den Medien-Codec, das Format und die Auflösungsfunktionen Ihrer Kamera in device/<company_name>/<device_name>/media_profiles.xml- und device/<company_name>/<device_name>/media_codecs.xml-XML-Dateien an. Weitere Informationen finden Sie unter Codecs für das Framework freigeben.
  5. Fügen Sie dem device/<company_name>/<device_name>/device.mk-Makefile Ihres Geräts die folgenden Zeilen hinzu, um die Dateien media_profiles.xml und media_codecs.xml an den richtigen Speicherort zu kopieren:
    # 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. Wenn Sie die Kamera App in das System-Image Ihres Geräts aufnehmen möchten, geben Sie sie in der Variablen PRODUCT_PACKAGES im device/<company>/<device>/device.mk-Makefile Ihres Geräts an:
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...