Appareil photo

Icône HAL de la caméra Android

La couche d'abstraction matérielle de la caméra (HAL) d'Android connecte les API du cadre de caméra de niveau supérieur dans Camera 2 au pilote et au matériel de votre caméra sous-jacents. Le sous-système de caméra comprend des implémentations pour les composants de pipeline de caméra tandis que le HAL de caméra fournit des interfaces à utiliser pour implémenter votre version de ces composants.

Architecture

La figure et la liste suivantes décrivent les composants HAL.

Architecture de la caméra Android

Figure 1. Architecture de la caméra

cadre d'application
Au niveau du framework de l'application se trouve le code de l'application, qui utilise l'API Camera 2 pour interagir avec le matériel de la caméra. En interne, ce code appelle les interfaces Binder correspondantes pour accéder au code natif qui interagit avec la caméra.
AIDL
L'interface de classeur associée à CameraService peut être trouvée sur frameworks/av/camera/aidl/android/hardware . Le code généré appelle le code natif de niveau inférieur pour obtenir l'accès à la caméra physique et renvoie les données utilisées pour créer les objets CameraDevice et éventuellement CameraCaptureSession au niveau du framework.
cadre natif
Ce framework résidant dans frameworks/av/ fournit un équivalent natif aux classes CameraDevice et CameraCaptureSession . Voir également la référence NDK camera2 .
interface IPC du classeur
L'interface du classeur IPC facilite la communication au-delà des limites des processus. Il existe plusieurs classes de classeurs de caméra situées dans le répertoire frameworks/av/camera/camera/aidl/android/hardware qui appellent le service de caméra. ICameraService est l'interface du service de caméra ; ICameraDeviceUser est l’interface vers un périphérique de caméra ouvert spécifique ; et ICameraServiceListener et ICameraDeviceCallbacks sont les rappels respectifs CameraService et CameraDevice vers le framework d'application.
service de caméra
Le service de caméra, situé dans frameworks/av/services/camera/libcameraservice/CameraService.cpp , est le code réel qui interagit avec le HAL.
HAL
La couche d'abstraction matérielle définit l'interface standard à laquelle le service de caméra appelle et que vous devez implémenter pour que le matériel de votre caméra fonctionne correctement.

Implémentation du HAL

Le HAL se situe entre le pilote de la caméra et le framework Android de niveau supérieur et définit une interface que vous devez implémenter pour que les applications puissent faire fonctionner correctement le matériel de la caméra. Les interfaces HIDL pour Camera HAL sont définies dans hardware/interfaces/camera .

Un HAL binderisé typique doit implémenter les interfaces HIDL suivantes :

Des implémentations HIDL de référence sont disponibles pour CameraProvider.cpp , CameraDevice.cpp et CameraDeviceSession.cpp . L'implémentation intègre les anciens HAL qui utilisent toujours l' ancienne API . À partir d'Android 8.0, les implémentations de Camera HAL doivent utiliser l'API HIDL ; l'utilisation de l'interface héritée n'est pas prise en charge.

Validation des entrées

Étant donné que HAL a accès à des ressources différentes de celles du service de caméra, la frontière entre les deux est traitée comme une limite de sécurité. Cela signifie que les paramètres transmis par le service de caméra sont considérés comme non fiables et non vérifiés. Pour éviter les failles de sécurité qui permettent aux attaquants d'élever leurs privilèges ou d'accéder à des données auxquelles ils ne sont pas censés avoir accès, le HAL de la caméra doit valider les paramètres transmis par le service de caméra au HAL. Cela inclut la vérification que les valeurs de longueur de tampon se situent dans les plages autorisées et la vérification des paramètres avant utilisation et avant de les transmettre aux pilotes matériels ou au noyau.

Composants HAL hérités

Cette section décrit l'architecture des composants HAL hérités et comment implémenter HAL. Les implémentations de Camera HAL sur Android 8.0 et versions ultérieures doivent plutôt utiliser l'API HIDL, décrite ci-dessus.

Architecture (héritage)

La figure et la liste suivantes décrivent les composants HAL de la caméra héritée.

Architecture de la caméra Android

Figure 2. Architecture de caméra héritée

cadre d'application
Au niveau du framework de l'application se trouve le code de l'application, qui utilise l'API android.hardware.Camera pour interagir avec le matériel de la caméra. En interne, ce code appelle une classe de colle JNI correspondante pour accéder au code natif qui interagit avec la caméra.
JNI
Le code JNI associé à android.hardware.Camera se trouve dans frameworks/base/core/jni/android_hardware_Camera.cpp . Ce code appelle le code natif de niveau inférieur pour obtenir l'accès à la caméra physique et renvoie les données utilisées pour créer l'objet android.hardware.Camera au niveau du framework.
cadre natif
Le framework natif défini dans frameworks/av/camera/Camera.cpp fournit un équivalent natif à la classe android.hardware.Camera . Cette classe appelle les proxys du classeur IPC pour obtenir l'accès au service de caméra.
proxys IPC de classeur
Les proxys de classeur IPC facilitent la communication au-delà des limites des processus. Il existe trois classes de classeurs de caméra situées dans le répertoire frameworks/av/camera qui appellent le service de caméra. ICameraService est l'interface du service de caméra, ICamera est l'interface vers un appareil photo ouvert spécifique et ICameraClient est l'interface de l'appareil vers le framework d'application.
service de caméra
Le service de caméra, situé dans frameworks/av/services/camera/libcameraservice/CameraService.cpp , est le code réel qui interagit avec le HAL.
HAL
La couche d'abstraction matérielle définit l'interface standard à laquelle le service de caméra appelle et que vous devez implémenter pour que le matériel de votre caméra fonctionne correctement.
pilote du noyau
Le pilote de la caméra interagit avec le matériel réel de la caméra et votre implémentation du HAL. La caméra et le pilote doivent prendre en charge les formats d'image YV12 et NV21 pour permettre la prévisualisation de l'image de la caméra sur l'écran et l'enregistrement vidéo.

Implémentation du HAL (héritage)

Le HAL se situe entre le pilote de la caméra et le framework Android de niveau supérieur et définit une interface que vous devez implémenter pour que les applications puissent faire fonctionner correctement le matériel de la caméra. L'interface HAL est définie dans les fichiers d'en-tête hardware/libhardware/include/hardware/camera.h et hardware/libhardware/include/hardware/camera_common.h .

camera_common.h définit camera_module , une structure standard pour obtenir des informations générales sur la caméra, telles que l'ID de la caméra et les propriétés communes à toutes les caméras (c'est-à-dire s'il s'agit d'une caméra frontale ou arrière).

camera.h contient du code qui correspond à android.hardware.Camera . Ce fichier d'en-tête déclare une structure camera_device qui à son tour contient une structure camera_device_ops avec des pointeurs vers des fonctions qui implémentent l'interface HAL. Pour obtenir de la documentation sur les paramètres de caméra que les développeurs peuvent définir, reportez-vous à frameworks/av/include/camera/CameraParameters.h . Ces paramètres sont définis avec la fonction pointée par int (*set_parameters)(struct camera_device *, const char *parms) dans le HAL.

Pour un exemple d'implémentation de HAL, reportez-vous à l'implémentation du Galaxy Nexus HAL dans hardware/ti/omap4xxx/camera .

Configuration de la bibliothèque partagée

Configurez le système de build Android pour empaqueter correctement l'implémentation HAL dans une bibliothèque partagée et copiez-la à l'emplacement approprié en créant un fichier Android.mk :

  1. Créez un répertoire device/<company_name>/<device_name>/camera pour contenir les fichiers sources de votre bibliothèque.
  2. Créez un fichier Android.mk pour créer la bibliothèque partagée. Assurez-vous que le makefile contient les lignes suivantes :
    LOCAL_MODULE := camera.<device_name>
    LOCAL_MODULE_RELATIVE_PATH := hw
    

    Votre bibliothèque doit être nommée camera.<device_name> ( .so est ajouté automatiquement), afin qu'Android puisse charger correctement la bibliothèque. Pour un exemple, consultez le makefile de la caméra Galaxy Nexus situé dans hardware/ti/omap4xxx/Android.mk .

  3. Spécifiez que votre appareil dispose de fonctionnalités de caméra en copiant les fichiers XML de fonctionnalités nécessaires dans le répertoire frameworks/native/data/etc avec le makefile de votre appareil. Par exemple, pour spécifier que votre appareil dispose d'un flash d'appareil photo et peut effectuer la mise au point automatique, ajoutez les lignes suivantes dans le makefile <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 \
    

    Pour un exemple de makefile de périphérique, voir device/samsung/tuna/device.mk .

  4. Déclarez le codec multimédia, le format et les capacités de résolution de votre caméra dans les fichiers XML device/<company_name>/<device_name>/media_profiles.xml et device/<company_name>/<device_name>/media_codecs.xml . Pour plus de détails, consultez Exposition des codecs au framework .
  5. Ajoutez les lignes suivantes dans device/<company_name>/<device_name>/device.mk de votre appareil pour copier les fichiers media_profiles.xml et media_codecs.xml à l'emplacement approprié :
    # 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. Pour inclure l'application Appareil photo dans l'image système de votre appareil, spécifiez-la dans la variable PRODUCT_PACKAGES dans le makefile device/<company>/<device>/device.mk de votre appareil :
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...