Камера

Значок Android Camera HAL

Уровень абстракции камеры (HAL) в Android соединяет API фреймворка камеры более высокого уровня в Camera 2 с драйвером и оборудованием камеры. Подсистема камеры включает реализации для компонентов конвейера камеры, а HAL камеры предоставляет интерфейсы для реализации вашей версии этих компонентов.

Архитектура

На рисунке и в списке ниже описаны компоненты HAL.

Архитектура камеры Android

Рисунок 1. Архитектура камеры.

фреймворк приложений
На уровне фреймворка приложения находится код, который использует API Camera 2 для взаимодействия с оборудованием камеры. Внутренне этот код вызывает соответствующие интерфейсы Binder для доступа к нативному коду, который взаимодействует с камерой.
AIDL
Интерфейс связывания, связанный с CameraService, можно найти по адресу frameworks/av/camera/aidl/android/hardware. Сгенерированный код вызывает нативный код более низкого уровня, чтобы получить доступ к физической камере, и возвращает данные, которые используются для создания объектов CameraDevice и CameraCaptureSession на уровне фреймворка.
нативный фреймворк;
Этот фреймворк, находящийся в frameworks/av/, предоставляет нативный эквивалент классов CameraDevice и CameraCaptureSession. См. также справочник по camera2 в NDK.
Интерфейс IPC Binder
Интерфейс связывания IPC упрощает обмен данными между процессами. В каталоге frameworks/av/camera/camera/aidl/android/hardware есть несколько классов связывания камеры, которые вызывают сервис камеры. ICameraService – это интерфейс для сервиса камеры; ICameraDeviceUser – это интерфейс для определенного открытого устройства камеры; а ICameraServiceListener и ICameraDeviceCallbacks – это соответствующие обратные вызовы CameraService и CameraDevice для фреймворка приложения.
сервис камеры;
Сервис камеры, расположенный в каталоге frameworks/av/services/camera/libcameraservice/CameraService.cpp, представляет собой код, который взаимодействует с HAL.
HAL
Уровень абстрагирования оборудования определяет стандартный интерфейс, который вызывает сервис камеры и который вы должны реализовать, чтобы оборудование камеры работало правильно.

Как реализовать HAL

Уровень абстракции оборудования (HAL) находится между драйвером камеры и фреймворком Android более высокого уровня. Он определяет интерфейс, который необходимо реализовать, чтобы приложения могли правильно работать с оборудованием камеры. Интерфейсы HIDL для HAL камеры определены в hardware/interfaces/camera.

Типичный HAL с привязкой должен реализовывать следующие интерфейсы HIDL:

  • ICameraProvider: Для перечисления отдельных устройств и управления их статусом.
  • ICameraDevice: Интерфейс устройства камеры.
  • ICameraDeviceSession: Интерфейс активного сеанса устройства камеры.

Эталонные реализации HIDL доступны для CameraProvider.cpp, CameraDevice.cpp и CameraDeviceSession.cpp. Реализация оборачивает старые HAL, которые по-прежнему используют устаревший API. Начиная с Android 8.0, реализации Camera HAL должны использовать HIDL API. Использование устаревшего интерфейса не поддерживается.

Проверка входных данных

Поскольку у HAL есть доступ к другим ресурсам, нежели у сервиса камеры, граница между ними считается границей безопасности. Это означает, что параметры, передаваемые из сервиса камеры, считаются ненадежными и не прошедшими очистку. Чтобы предотвратить уязвимости, позволяющие злоумышленникам повышать привилегии или получать доступ к данным, к которым они не должны иметь доступа, HAL камеры должен проверять параметры, передаваемые из сервиса камеры в HAL. Это включает проверку того, что значения длины буфера находятся в допустимых диапазонах, и очистку параметров перед использованием и передачей их драйверам оборудования или ядра.

Устаревший HAL

В этом разделе описывается архитектура устаревших компонентов HAL и рассказывается, как реализовать HAL. В Android 8.0 и более поздних версий реализации HAL камеры должны использовать описанный выше HIDL API.

Архитектура (устаревшая версия)

На рисунке и в списке ниже описаны компоненты устаревшего HAL камеры:

Архитектура камеры Android

Рисунок 2. Устаревшая архитектура камеры.

фреймворк приложений
На уровне фреймворка приложения находится код приложения, который использует API android.hardware.Camera для взаимодействия с аппаратным обеспечением камеры. Внутри этот код вызывает соответствующий связующий класс JNI для доступа к нативному коду, который взаимодействует с камерой.
JNI
Код JNI, связанный с android.hardware.Camera, находится в frameworks/base/core/jni/android_hardware_Camera.cpp. Этот код вызывает низкоуровневый собственный код, чтобы получить доступ к физической камере, и возвращает данные, которые используются для создания объекта android.hardware.Camera на уровне фреймворка.
нативный фреймворк;
Нативный фреймворк, определенный в frameworks/av/camera/Camera.cpp, предоставляет нативный эквивалент класса android.hardware.Camera. Этот класс вызывает прокси-серверы связывателя IPC, чтобы получить доступ к сервису камеры.
Прокси-серверы IPC Binder
Прокси-серверы IPC Binder упрощают обмен данными между процессами. В каталоге frameworks/av/camera, который вызывает сервис камеры, есть три класса связывания камеры. ICameraService – интерфейс сервиса камеры, ICamera – интерфейс определенного открытого устройства камеры, а ICameraClient – интерфейс устройства для взаимодействия с фреймворком приложения.
сервис камеры;
Сервис камеры, расположенный в каталоге frameworks/av/services/camera/libcameraservice/CameraService.cpp, представляет собой код, который взаимодействует с HAL.
HAL
Аппаратно-зависимый уровень определяет стандартный интерфейс, который вызывает сервис камеры и который необходимо реализовать, чтобы камера работала правильно.
драйвер ядра
Драйвер камеры взаимодействует с аппаратным обеспечением камеры и вашей реализацией HAL. Камера и драйвер должны поддерживать графические форматы YV12 и NV21, чтобы можно было просматривать изображение с камеры на дисплее и записывать видео.

Как реализовать HAL (устаревший способ)

HAL находится между драйвером камеры и фреймворком Android более высокого уровня и определяет интерфейс, который необходимо реализовать, чтобы приложения могли правильно управлять аппаратным обеспечением камеры. Интерфейс HAL определяется в заголовочных файлах hardware/libhardware/include/hardware/camera.h и hardware/libhardware/include/hardware/camera_common.h.

camera_common.h определяет camera_module – стандартную структуру для получения общей информации о камере, например ее идентификатора и свойств, общих для всех камер (например, является ли она фронтальной или задней).

camera.h содержит код, соответствующий android.hardware.Camera. Этот заголовочный файл объявляет структуру camera_device, которая, в свою очередь, содержит структуру camera_device_ops с указателями на функции, реализующие интерфейс HAL. Документацию по параметрам камеры, которые могут задавать разработчики, можно найти на странице frameworks/av/include/camera/CameraParameters.h. Эти параметры задаются с помощью функции, на которую указывает int (*set_parameters)(struct camera_device *, const char *parms) в HAL.

Пример реализации HAL можно найти в hardware/ti/omap4xxx/camera.

Как настроить общую библиотеку

Настройте систему сборки Android так, чтобы реализация HAL правильно упаковывалась в общую библиотеку и копировалась в нужное место. Для этого создайте файл Android.mk:

  1. Создайте каталог device/<company_name>/<device_name>/camera, в котором будут храниться исходные файлы библиотеки.
  2. Создайте файл Android.mk, чтобы создать общую библиотеку. Убедитесь, что файл makefile содержит следующие строки:
    LOCAL_MODULE := camera.<device_name>
    LOCAL_MODULE_RELATIVE_PATH := hw
    

    Библиотека должна называться camera.<device_name> (.so добавляется автоматически), чтобы Android мог правильно ее загрузить. Пример можно найти в файле makefile для камеры Galaxy Nexus, расположенном в каталоге hardware/ti/omap4xxx/Android.mk.

  3. Укажите, что на устройстве есть камера, скопировав необходимые XML-файлы функций в каталог frameworks/native/data/etc с помощью файла 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 \
    

    Пример make-файла устройства можно найти на странице device/samsung/tuna/device.mk.

  4. Задекларируйте возможности камеры по работе с медиакодеками, форматами и разрешением в XML-файлах device/<company_name>/<device_name>/media_profiles.xml и device/<company_name>/<device_name>/media_codecs.xml. Подробнее о том, как предоставить фреймворку доступ к кодекам…
  5. Добавьте в файл makefile устройства следующие строки, чтобы скопировать файлы media_profiles.xml и media_codecs.xml в нужную папку:device/<company_name>/<device_name>/device.mk
    # 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. Чтобы добавить приложение "Камера" в системный образ устройства, укажите его в переменной PRODUCT_PACKAGES в файле makefile устройства device/<company>/<device>/device.mk:
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...