Kamera

Symbol für Android Camera HAL

Die Camera Hardware Abstraction Layer (HAL) von Android verbindet die APIs des Kamera-Frameworks auf höherer Ebene in Camera 2 mit dem zugrunde liegenden Kameratreiber und der Hardware. Das Kamera-Subsystem umfasst Implementierungen für Komponenten der Kamerapipeline, 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 der Ebene des App-Frameworks befindet sich der Code der App, der die Camera 2 API verwendet, um mit der Kamerahardware zu interagieren. 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-Schnittstelle finden Sie unter frameworks/av/camera/aidl/android/hardware. Der generierte Code ruft den nativen Code auf niedrigerer Ebene auf, um Zugriff auf die physische Kamera zu erhalten, und gibt Daten zurück, die zum Erstellen der Objekte CameraDevice und schließlich CameraCaptureSession auf Framework-Ebene verwendet werden.
natives Framework
Dieses Framework in frameworks/av/ bietet ein natives Äquivalent zu den Klassen CameraDevice und CameraCaptureSession. Siehe auch NDK camera2-Referenz.
Binder-IPC-Schnittstelle
Die IPC-Binder-Schnittstelle ermöglicht die Kommunikation über Prozessgrenzen hinweg. Im Verzeichnis frameworks/av/camera/camera/aidl/android/hardware befinden sich mehrere Kamerabinder-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 entsprechenden CameraService- und CameraDevice-Callbacks zum App-Framework.
Kameraservice
Der Kameradienst unter frameworks/av/services/camera/libcameraservice/CameraService.cpp ist der tatsächliche Code, der mit dem HAL interagiert.
HAL
Die Hardwareabstraktionsschicht definiert die Standardschnittstelle, die der Kameradienst aufruft und die Sie implementieren müssen, damit Ihre Kamerahardware richtig funktioniert.

HAL implementieren

Die HAL befindet sich zwischen dem Kameratreiber und dem Android-Framework auf höherer 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 in hardware/interfaces/camera definiert.

Eine typische binderisierte 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 Camera HAL-Implementierungen die HIDL-API verwenden. Die Verwendung der alten Schnittstelle wird nicht unterstützt.

Eingabevalidierung

Da das HAL auf andere Ressourcen als der Kameradienst zugreifen kann, wird die Grenze zwischen den beiden als Sicherheitsgrenze betrachtet. Das bedeutet, dass vom Kameradienst übergebene Parameter als nicht vertrauenswürdig und nicht bereinigt gelten. Um Sicherheitslücken zu vermeiden, die es Angreifern ermöglichen, Berechtigungen zu eskalieren oder auf Daten zuzugreifen, auf die sie keinen Zugriff haben sollen, muss die Kamera-HAL Parameter validieren, die vom Kameradienst an die HAL übergeben werden. Dazu gehört, dass die Werte für die Pufferlänge innerhalb der zulässigen Bereiche liegen und die Parameter vor der Verwendung und vor der Übergabe an Hardware- oder Kerneltreiber bereinigt werden.

Legacy-HAL-Komponenten

In diesem Abschnitt wird die Architektur der Legacy-HAL-Komponenten beschrieben und erläutert, wie das HAL implementiert wird. Camera HAL-Implementierungen unter Android 8.0 und höher müssen stattdessen die oben beschriebene HIDL-API verwenden.

Architektur (Legacy)

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

Android-Kameraarchitektur

Abbildung 2: Legacy-Kameraarchitektur

App-Framework
Auf der Ebene des App-Frameworks befindet sich der Code der App, der die android.hardware.Camera-API verwendet, um mit der Kamerahardware zu interagieren. Intern wird mit diesem Code eine entsprechende JNI-Glue-Klasse aufgerufen, 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. Mit diesem Code wird der native Code auf niedrigerer Ebene aufgerufen, um Zugriff auf die physische Kamera zu erhalten. Es werden Daten zurückgegeben, die zum Erstellen des android.hardware.Camera-Objekts auf Framework-Ebene verwendet werden.
natives Framework
Das in frameworks/av/camera/Camera.cpp definierte native Framework bietet ein natives Äquivalent zur Klasse android.hardware.Camera. In dieser Klasse werden die IPC-Binder-Proxys aufgerufen, um Zugriff auf den Kameradienst zu erhalten.
Binder-IPC-Proxys
Die IPC-Binder-Proxys erleichtern die Kommunikation über Prozessgrenzen hinweg. Es gibt drei Kamera-Binder-Klassen im Verzeichnis frameworks/av/camera, die den Kameradienst aufrufen. ICameraService ist die Schnittstelle zum Kameradienst, ICamera ist die Schnittstelle zu einem bestimmten geöffneten Kameragerät und ICameraClient ist die Schnittstelle des Geräts zurück zum App-Framework.
Kameraservice
Der Kameradienst unter frameworks/av/services/camera/libcameraservice/CameraService.cpp ist der tatsächliche Code, der mit dem HAL interagiert.
HAL
Die Hardwareabstraktionsschicht definiert die Standardschnittstelle, die der Kameradienst aufruft und die Sie implementieren müssen, damit Ihre Kamerahardware richtig funktioniert.
Kernel-Treiber
Der Treiber der Kamera interagiert mit der eigentlichen Kamerahardware und Ihrer Implementierung der HAL. Die Kamera und der Treiber müssen die Bildformate YV12 und NV21 unterstützen, damit das Kamerabild auf dem Display angezeigt und Videos aufgenommen werden können.

HAL implementieren (alte Version)

Die HAL befindet sich zwischen dem Kameratreiber und dem Android-Framework auf höherer 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 zum Abrufen allgemeiner Informationen zur Kamera, z. B. der Kamera-ID und Eigenschaften, die für alle Kameras gelten (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 eine camera_device-Struktur deklariert, die wiederum eine camera_device_ops-Struktur mit Zeigern auf Funktionen enthält, die die HAL-Schnittstelle implementieren. Die 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 int (*set_parameters)(struct camera_device *, const char *parms) in der HAL verweist.

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

Geteilte Fotogalerie konfigurieren

Richten Sie das Android-Build-System so ein, dass die HAL-Implementierung korrekt in einer gemeinsam genutzten Bibliothek verpackt und an den entsprechenden 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 gemeinsam genutzte Bibliothek zu erstellen. Prüfen Sie, ob das Make-Datei die folgenden Zeilen enthält:
    LOCAL_MODULE := camera.<device_name>
    LOCAL_MODULE_RELATIVE_PATH := hw
    

    Ihre Bibliothek muss camera.<device_name> heißen (.so wird automatisch angehängt), damit Android die Bibliothek richtig laden kann. Ein Beispiel finden Sie in der Make-Datei für die Galaxy Nexus-Kamera unter hardware/ti/omap4xxx/Android.mk.

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

  4. Deklarieren Sie die Media-Codec-, Format- und Auflösungsfunktionen Ihrer Kamera in den XML-Dateien device/<company_name>/<device_name>/media_profiles.xml und device/<company_name>/<device_name>/media_codecs.xml. Weitere Informationen finden Sie unter Codecs für das Framework verfügbar machen.
  5. Fügen Sie der 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 entsprechenden 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 in der device/<company>/<device>/device.mk-Makefile Ihres Geräts an:
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...