Cámara

Ícono de 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 nivel superior del framework de la cámara en Camera 2 al controlador y hardware subyacentes de la cámara. El subsistema de la cámara incluye implementaciones para componentes de la canalización de la cámara, mientras que el HAL de la cámara proporciona interfaces para usar en la implementación de tu versión de estos componentes.

Arquitectura

En la siguiente imagen y lista, se describen los componentes del sistema 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. De forma interna, este código llama a las interfaces correspondientes de Binder 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 los datos que se usan para crear los objetos CameraDevice y, finalmente, CameraCaptureSession a nivel del framework.
framework nativo
Este framework que reside en frameworks/av/ proporciona un equivalente nativo a las clases CameraDevice y CameraCaptureSession. Consulta también la referencia de Camera2 del NDK.
Interfaz de IPC de Binder
La interfaz del Binder de IPC facilita la comunicación a través de los límites del proceso. Hay varias clases de vinculación de cámaras ubicadas en el directorio frameworks/av/camera/camera/aidl/android/hardware que llaman al servicio de la cámara. ICameraService es la interfaz del servicio de la cámara; ICameraDeviceUser es la interfaz de un dispositivo de cámara abierto específico; y ICameraServiceListener y ICameraDeviceCallbacks son las devoluciones de llamada CameraService y CameraDevice correspondientes al framework de la app.
servicio de cámara
El servicio de la cámara, que se encuentra en frameworks/av/services/camera/libcameraservice/CameraService.cpp, es el código real que interactúa con el HAL.
HAL
La capa de abstracción de hardware define la interfaz estándar a la que llama el servicio de la cámara y que debes implementar para que el hardware de la cámara funcione correctamente.

Implementa el 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.

Un HAL vinculado típico 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 une los HAL antiguos 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 el HAL tiene acceso a recursos diferentes al servicio de la cámara, el límite entre ambos se considera un límite de seguridad. Esto significa que los parámetros que se pasan desde el servicio de la cámara se consideran no confiables y no se limpian. Para evitar vulnerabilidades de seguridad que permitan a los atacantes escalar privilegios o acceder a datos a los que no deberían tener acceso, el HAL de la cámara debe validar los parámetros que se pasan del servicio de la cámara al HAL. Esto incluye verificar que los valores de la longitud del búfer estén dentro de los rangos permitidos y limpiar los parámetros antes de usarlos y 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 el HAL. Las implementaciones de HAL de la cámara en Android 8.0 y versiones posteriores deben usar la API de HIDL, como se describió anteriormente.

Arquitectura (heredada)

En la siguiente imagen y lista, se describen los componentes del HAL de la cámara heredada.

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 API de android.hardware.Camera para interactuar con el hardware de la cámara. De forma interna, este código llama a una clase de unión 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 los datos que se usan para crear el objeto android.hardware.Camera a nivel del framework.
framework nativo
El framework nativo definido en frameworks/av/camera/Camera.cpp proporciona un equivalente nativo a la clase android.hardware.Camera. Esta clase llama a los proxies de Binder de IPC para obtener acceso al servicio de la 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 la cámara que se encuentran en el directorio frameworks/av/camera que llama al servicio de la cámara. ICameraService es la interfaz del servicio de la cámara, ICamera es la interfaz de un dispositivo de cámara abierto específico y ICameraClient es la interfaz del dispositivo que vuelve al framework de la app.
servicio de cámara
El servicio de la cámara, que se encuentra en frameworks/av/services/camera/libcameraservice/CameraService.cpp, es el código real que interactúa con el HAL.
HAL
La capa de abstracción de hardware define la interfaz estándar a la que llama el servicio de la cámara y que debes implementar para que el hardware de la cámara funcione correctamente.
controlador de kernel
El controlador de la cámara interactúa con el hardware real de la cámara y tu implementación del HAL. La cámara y el controlador deben admitir los formatos de imagen YV12 y NV21 para brindar compatibilidad con la vista previa de la imagen de la cámara en la pantalla y la grabación de video.

Implementa el HAL (heredado)

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 de 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 posterior).

camera.h contiene código que corresponde a android.hardware.Camera. Este archivo de encabezado declara una estructura camera_device que, a su vez, contiene una estructura camera_device_ops con punteros a funciones que implementan la interfaz HAL. Para obtener documentación sobre los parámetros de la cámara que los desarrolladores pueden configurar, 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 el sistema HAL.

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

Configura la biblioteca compartida

Configura el sistema de compilación de Android para que empaquete correctamente la implementación de HAL en una biblioteca compartida y cópiala en la ubicación adecuada. Para ello, crea un archivo Android.mk:

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

    Tu biblioteca debe llamarse camera.<device_name> (.so se agrega automáticamente) para que Android pueda cargarla correctamente. Como ejemplo, consulta el archivo makefile de la cámara del Galaxy Nexus, que se encuentra en hardware/ti/omap4xxx/Android.mk.

  3. Para especificar que tu dispositivo tiene funciones de cámara, copia los archivos XML de funciones necesarios en el directorio frameworks/native/data/etc con el archivo de configuración del dispositivo. Por ejemplo, para especificar que tu dispositivo tiene un flash de cámara y puede enfocar automáticamente, agrega las siguientes líneas en el archivo de compilación <device>/<company_name>/<device_name>/device.mk del 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 resolución, formato y códec multimedia de la cámara en los archivos en formato XML device/<company_name>/<device_name>/media_profiles.xml y device/<company_name>/<device_name>/media_codecs.xml. Para obtener más información, consulta Cómo exponer códecs al framework.
  5. Agrega las siguientes líneas al archivo de configuración make device/<company_name>/<device_name>/device.mk de tu dispositivo para copiar los archivos media_profiles.xml y media_codecs.xml a 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 variable PRODUCT_PACKAGES del archivo de configuración device/<company>/<device>/device.mk de tu dispositivo:
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...