A camada de abstração de hardware (HAL, na sigla em inglês) da câmera do Android conecta as APIs de framework de câmera de nível mais alto na Camera 2 ao driver e hardware da câmera. O subsistema da câmera inclui implementações para componentes de pipeline da câmera, enquanto a HAL da câmera fornece interfaces para uso na implementação da sua versão desses componentes.
Arquitetura
A figura e a lista a seguir descrevem os componentes da HAL:
Figura 1. Arquitetura da câmera.
- framework do app
- No nível do framework do app, está o código do app, que usa a API Camera 2 para interagir com o hardware da câmera. Internamente, esse código chama as interfaces Binder correspondentes para acessar o código nativo que interage com a câmera.
- AIDL
- A interface do binder associada ao
CameraServicepode ser encontrada em frameworks/av/camera/aidl/android/hardware. O código gerado chama o código nativo de nível mais baixo para acessar a câmera física e retorna dados usados para criar osCameraDevicee, por fim,CameraCaptureSessionobjetos no nível do framework. - framework nativo
- Esse framework residente em
frameworks/av/fornece um equivalente nativo para asCameraDeviceeCameraCaptureSessionclasses. Consulte também Referência da câmera2 do NDK. - interface IPC do binder
- A interface do binder IPC facilita a comunicação em limites de processos.
Há várias classes de binder de câmera localizadas no
frameworks/av/camera/camera/aidl/android/hardwarediretório que chamam o serviço de câmera.ICameraServiceé a interface para o serviço de câmera;ICameraDeviceUseré a interface para um dispositivo de câmera aberto específico; eICameraServiceListenereICameraDeviceCallbackssão os callbacksCameraServiceeCameraDevicerespectivos para o framework do app. - serviço de câmera
- O serviço de câmera, localizado em
frameworks/av/services/camera/libcameraservice/CameraService.cpp, é o código real que interage com a HAL. - HAL
- A camada de abstração de hardware define a interface padrão que o serviço de câmera chama e que você precisa implementar para que o hardware da câmera funcione corretamente.
Implementar a HAL
A HAL fica entre o driver da câmera e o framework do Android de nível mais alto e define uma interface que você precisa implementar para que os apps possam operar corretamente o hardware da câmera. As interfaces HIDL para a HAL da câmera são definidas em hardware/interfaces/camera.
Uma HAL binderizada típica precisa implementar as seguintes interfaces HIDL:
-
ICameraProvider: Para enumerar dispositivos individuais e gerenciar o status deles. -
ICameraDevice: a interface do dispositivo de câmera. -
ICameraDeviceSession: a interface de sessão ativa do dispositivo de câmera.
Implementações HIDL de referência estão disponíveis para
CameraProvider.cpp,
CameraDevice.cpp, e
CameraDeviceSession.cpp.
A implementação envolve HALs antigas que ainda usam a
API legada.
A partir do Android 8.0, as implementações da HAL da câmera precisam usar a API HIDL. O uso da interface legada não é compatível.
Validação de entrada
Como a HAL tem acesso a recursos diferentes do serviço de câmera, o limite entre os dois é tratado como um limite de segurança. Isso significa que os parâmetros transmitidos do serviço de câmera são considerados não confiáveis e não higienizados. Para evitar vulnerabilidades de segurança que permitam que invasores escalonem privilégios ou acessem dados que não deveriam ter acesso, a HAL da câmera precisa validar os parâmetros transmitidos do serviço de câmera para a HAL. Isso inclui verificar se os valores de comprimento do buffer estão dentro dos intervalos permitidos e higienizar os parâmetros antes do uso e antes de transmiti-los para drivers de hardware ou kernel.
HAL legada
Esta seção descreve a arquitetura dos componentes HAL legados e como implementar a HAL. As implementações da HAL da câmera no Android 8.0 e versões mais recentes precisam usar a API HIDL, descrita acima.
Arquitetura (legada)
A figura e a lista a seguir descrevem os componentes HAL legados da câmera:
Figura 2. Arquitetura de câmera legada.
- framework do app
- No nível do framework do app, está o código do app, que usa a
android.hardware.CameraAPI para interagir com o hardware da câmera. Internamente, esse código chama uma classe de cola JNI correspondente para acessar o código nativo que interage com a câmera. - JNI
- O código JNI associado a
android.hardware.Cameraestá localizado emframeworks/base/core/jni/android_hardware_Camera.cpp. Esse código chama o código nativo de nível mais baixo para acessar a câmera física e retorna dados usados para criar oandroid.hardware.Cameraobjeto no nível do framework. - framework nativo
- O framework nativo definido em
frameworks/av/camera/Camera.cppfornece um equivalente nativo para aandroid.hardware.Cameraclasse. Essa classe chama os proxies do binder IPC para acessar o serviço de câmera. - proxies do binder IPC
- Os proxies do binder IPC facilitam a comunicação em limites de processos.
Há três classes de binder de câmera localizadas no
frameworks/av/cameradiretório que chamam o serviço de câmera.ICameraServiceé a interface para o serviço de câmera,ICameraé a interface para um dispositivo de câmera aberto específico, eICameraClienté a interface do dispositivo de volta para o framework do app. - serviço de câmera
- O serviço de câmera, localizado em
frameworks/av/services/camera/libcameraservice/CameraService.cpp, é o código real que interage com a HAL. - HAL
- A camada de abstração de hardware define a interface padrão que o serviço de câmera chama e que você precisa implementar para que o hardware da câmera funcione corretamente.
- driver do kernel
- O driver da câmera interage com o hardware real da câmera e com a implementação da HAL. A câmera e o driver precisam oferecer suporte aos formatos de imagem YV12 e NV21 para oferecer suporte à visualização da imagem da câmera na tela e à gravação de vídeo.
Implementar a HAL (legada)
A HAL fica entre o driver da câmera e o framework do Android de nível mais alto e define uma interface que você precisa implementar para que os apps possam operar corretamente o hardware da câmera. A interface HAL é definida nos arquivos de cabeçalho hardware/libhardware/include/hardware/camera.h e hardware/libhardware/include/hardware/camera_common.h.
camera_common.h define camera_module, uma estrutura padrão para receber informações gerais sobre a câmera, como o ID e as propriedades comuns a todas as câmeras (ou seja, se é uma câmera frontal ou traseira).
camera.h contém o código correspondente a
android.hardware.Camera. Esse arquivo principal declara uma
camera_device struct que, por sua vez, contém uma
camera_device_ops struct com ponteiros para funções que implementam
a interface HAL. Para documentação sobre os parâmetros da câmera que os desenvolvedores podem definir, consulte frameworks/av/include/camera/CameraParameters.h.
Esses parâmetros são definidos com a função apontada por int
(*set_parameters)(struct camera_device *, const char *parms) na HAL.
Para conferir um exemplo de implementação da HAL, consulte a implementação da HAL do Galaxy Nexus em hardware/ti/omap4xxx/camera.
Configurar a biblioteca compartilhada
Configure o sistema de build do Android para empacotar corretamente a implementação da HAL em uma biblioteca compartilhada e copiá-la para o local apropriado criando um arquivo Android.mk:
- Crie um
device/<company_name>/<device_name>/cameradiretório para conter os arquivos de origem da biblioteca. - Crie um arquivo
Android.mkpara criar a biblioteca compartilhada. Verifique se o makefile contém as seguintes linhas:LOCAL_MODULE := camera.<device_name> LOCAL_MODULE_RELATIVE_PATH := hw
A biblioteca precisa ser nomeada como
camera.<device_name>(.soé anexado automaticamente) para que o Android possa carregar a biblioteca corretamente. Para conferir um exemplo, consulte o makefile da câmera do Galaxy Nexus localizado emhardware/ti/omap4xxx/Android.mk. - Especifique que o dispositivo tem recursos de câmera copiando os arquivos XML de recursos necessários no diretório
frameworks/native/data/etccom o makefile do dispositivo. Por exemplo, para especificar que o dispositivo tem um flash da câmera e pode fazer o autofoco, adicione as seguintes linhas no makefile<device>/<company_name>/<device_name>/device.mkdo 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 conferir um exemplo de makefile de dispositivo, consulte
device/samsung/tuna/device.mk. - Declare os recursos de codec, formato e resolução de mídia da câmera em
device/<company_name>/<device_name>/media_profiles.xmledevice/<company_name>/<device_name>/media_codecs.xmlarquivos XML. Para mais detalhes, consulte Expor codecs ao framework. - Adicione as seguintes linhas no makefile
device/<company_name>/<device_name>/device.mkdo dispositivo para copiar os arquivosmedia_profiles.xmlemedia_codecs.xmlpara o local apropriado:# 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 - Para incluir o app Câmera na imagem do sistema do dispositivo, especifique-o na
PRODUCT_PACKAGESvariável nodevice/<company>/<device>/device.mkmakefile do dispositivo:PRODUCT_PACKAGES := \ Gallery2 \ ...