Cámara

Ícono del HAL de la cámara de Android

La capa de abstracción de hardware (HAL) de la cámara de Android conecta las APIs de framework de la cámara de nivel superior en Camera 2 con el controlador y el hardware de la cámara subyacentes. El subsistema de cámara incluye implementaciones para componentes de la canalización de la cámara, mientras que la HAL de la cámara proporciona interfaces para usar en la implementación de tu versión de estos componentes.

Arquitectura

En la siguiente figura y lista, se describen los componentes de HAL.

Arquitectura de la cámara de Android

Figura 1: Arquitectura de la cámara

framework de la app
En el nivel del framework de la app, se encuentra el código de la app, que usa la API de Camera 2 para interactuar con el hardware de la cámara. Internamente, este código llama a las interfaces de Binder correspondientes para acceder al código nativo que interactúa con la cámara.
AIDL
La interfaz de Binder asociada con CameraService se puede encontrar en frameworks/av/camera/aidl/android/hardware. El código generado llama al código nativo de nivel inferior para obtener acceso a la cámara física y muestra datos que se usan para crear los CameraDevice y, finalmente, CameraCaptureSession objetos en el nivel del framework.
framework nativo
Este framework que reside en frameworks/av/ proporciona un equivalente nativo a las CameraDevice y CameraCaptureSession clases. Consulta también la referencia de NDK camera2.
interfaz de IPC de Binder
La interfaz de Binder de IPC facilita la comunicación a través de los límites del proceso. Hay varias clases de Binder de cámara ubicadas en el frameworks/av/camera/camera/aidl/android/hardware directorio que llaman al servicio de cámara. ICameraService es la interfaz del servicio de cámara; ICameraDeviceUser es la interfaz de un dispositivo de cámara abierto específico; y ICameraServiceListener y ICameraDeviceCallbacks son las devoluciones de llamada respectivas de CameraService y CameraDevice al framework de la app.
servicio de cámara
El servicio de cámara, ubicado en frameworks/av/services/camera/libcameraservice/CameraService.cpp, es el código real que interactúa con la HAL.
HAL
La capa de abstracción de hardware define la interfaz estándar a la que llama el servicio de cámara y que debes implementar para que el hardware de la cámara funcione correctamente.

Implementa la HAL

La HAL se encuentra entre el controlador de la cámara y el framework de Android de nivel superior, y define una interfaz que debes implementar para que las apps puedan operar correctamente el hardware de la cámara. Las interfaces HIDL para la HAL de la cámara se definen en hardware/interfaces/camera.

Una HAL de Binder típica debe implementar las siguientes interfaces HIDL:

Las implementaciones de HIDL de referencia están disponibles para CameraProvider.cpp, CameraDevice.cpp, y CameraDeviceSession.cpp. La implementación incluye HALs antiguas que aún usan la API heredada. A partir de Android 8.0, las implementaciones de HAL de la cámara deben usar la API de HIDL; no se admite el uso de la interfaz heredada.

Validación de entradas

Debido a que la HAL tiene acceso a diferentes recursos que el servicio de cámara, el límite entre ambos se trata como un límite de seguridad. Esto significa que los parámetros que se pasan desde el servicio de cámara se consideran no confiables y no desinfectados. Para evitar vulnerabilidades de seguridad que permitan a los atacantes escalar privilegios o acceder a datos a los que no deberían tener acceso, la HAL de la cámara debe validar los parámetros que se pasan del servicio de cámara a la HAL. Esto incluye verificar que los valores de longitud del búfer estén dentro de los rangos permitidos y desinfectar los parámetros antes de usarlos y antes de pasarlos a los controladores de hardware o kernel.

Componentes de HAL heredados

En esta sección, se describe la arquitectura de los componentes de HAL heredados y cómo implementar la HAL. Las implementaciones de HAL de la cámara en Android 8.0 y versiones posteriores deben usar la API de HIDL, que se describió anteriormente.

Arquitectura (heredada)

En la siguiente figura y lista, se describen los componentes de HAL de la cámara heredados.

Arquitectura de la cámara de Android

Figura 2: Arquitectura de la cámara heredada

framework de la app
En el nivel del framework de la app, se encuentra el código de la app, que usa la android.hardware.Camera API para interactuar con el hardware de la cámara. Internamente, este código llama a una clase de pegamento JNI correspondiente para acceder al código nativo que interactúa con la cámara.
JNI
El código JNI asociado con android.hardware.Camera se encuentra en frameworks/base/core/jni/android_hardware_Camera.cpp. Este código llama al código nativo de nivel inferior para obtener acceso a la cámara física y muestra datos que se usan para crear el android.hardware.Camera objeto en el nivel del framework.
framework nativo
El framework nativo definido en frameworks/av/camera/Camera.cpp proporciona un equivalente nativo a la android.hardware.Camera clase. Esta clase llama a los proxies de Binder de IPC para obtener acceso al servicio de cámara.
proxies de IPC de Binder
Los proxies de Binder de IPC facilitan la comunicación a través de los límites del proceso. Hay tres clases de Binder de cámara ubicadas en el frameworks/av/camera directorio que llaman al servicio de cámara. ICameraService es la interfaz del servicio de cámara, ICamera es la interfaz de un dispositivo de cámara abierto específico, y ICameraClient es la interfaz del dispositivo de vuelta al framework de la app.
servicio de cámara
El servicio de cámara, ubicado en frameworks/av/services/camera/libcameraservice/CameraService.cpp, es el código real que interactúa con la HAL.
HAL
La capa de abstracción de hardware define la interfaz estándar a la que llama el servicio de cámara y que debes implementar para que el hardware de la cámara funcione correctamente.
controlador del kernel
El controlador de la cámara interactúa con el hardware de la cámara real y con tu implementación de la HAL. La cámara y el controlador deben admitir los formatos de imagen YV12 y NV21 para proporcionar compatibilidad con la vista previa de la imagen de la cámara en la pantalla y la grabación de video.

Implementa la HAL (heredada)

La HAL se encuentra entre el controlador de la cámara y el framework de Android de nivel superior, y define una interfaz que debes implementar para que las apps puedan operar correctamente el hardware de la cámara. La interfaz HAL se define en los archivos de encabezado hardware/libhardware/include/hardware/camera.h y hardware/libhardware/include/hardware/camera_common.h.

camera_common.h define camera_module, una estructura estándar para obtener información general sobre la cámara, como el ID de la cámara y las propiedades comunes a todas las cámaras (es decir, si es una cámara frontal o trasera).

camera.h contiene código que corresponde a android.hardware.Camera. Este archivo de encabezado declara una camera_device estructura que, a su vez, contiene una camera_device_ops estructura con punteros a funciones que implementan la interfaz HAL. Para obtener documentación sobre los parámetros de la cámara que pueden establecer los desarrolladores, consulta frameworks/av/include/camera/CameraParameters.h. Estos parámetros se establecen con la función a la que apunta int (*set_parameters)(struct camera_device *, const char *parms) en la HAL.

Para ver un ejemplo de una implementación de HAL, consulta la implementación de la HAL de Galaxy Nexus en hardware/ti/omap4xxx/camera.

Configura la biblioteca compartida

Configura el sistema de compilación de Android para empaquetar correctamente la implementación de HAL en una biblioteca compartida y copiarla en la ubicación adecuada creando un archivo Android.mk:

  1. Crea un device/<company_name>/<device_name>/camera directorio para que contenga los archivos fuente de tu biblioteca.
  2. Crea un archivo Android.mk para compilar la biblioteca compartida. Asegúrate de que el archivo Make contenga las siguientes líneas:
    LOCAL_MODULE := camera.<device_name>
    LOCAL_MODULE_RELATIVE_PATH := hw
    

    Tu biblioteca debe llamarse camera.<device_name> (se agrega .so automáticamente) para que Android pueda cargar la biblioteca correctamente. Para ver un ejemplo, consulta el archivo Make de la cámara de Galaxy Nexus ubicado en hardware/ti/omap4xxx/Android.mk.

  3. Especifica que tu dispositivo tiene funciones de cámara copiando los archivos XML de funciones necesarios en el directorio frameworks/native/data/etc con el archivo Make de tu dispositivo. Por ejemplo, para especificar que tu dispositivo tiene un flash de la cámara y puede enfocar automáticamente, agrega las siguientes líneas en el archivo Make <device>/<company_name>/<device_name>/device.mk de tu dispositivo:
    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 \
    

    Para ver un ejemplo de un archivo Make de dispositivo, consulta device/samsung/tuna/device.mk.

  4. Declara las capacidades de códec, formato y resolución de medios de tu cámara en device/<company_name>/<device_name>/media_profiles.xml y device/<company_name>/<device_name>/media_codecs.xml archivos XML. Para obtener más detalles, consulta Cómo exponer códecs al framework.
  5. Agrega las siguientes líneas en el archivo Make device/<company_name>/<device_name>/device.mk de tu dispositivo para copiar los archivos media_profiles.xml y media_codecs.xml en la ubicación adecuada:
    # 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. Para incluir la app de Cámara en la imagen del sistema de tu dispositivo, especifícala en la PRODUCT_PACKAGES variable en el archivo Make device/<company>/<device>/device.mk de tu dispositivo:
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...