カメラ

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。
Android カメラ HAL アイコン

Android のカメラ ハードウェア アブストラクション レイヤー (HAL) は、 Camera 2の高レベルのカメラ フレームワーク API を、基盤となるカメラ ドライバーとハードウェアに接続します。カメラ サブシステムにはカメラ パイプライン コンポーネントの実装が含まれており、カメラ HAL にはこれらのコンポーネントのバージョンを実装する際に使用するインターフェースが用意されています。

建築

次の図とリストで、HAL コンポーネントについて説明します。

Android カメラのアーキテクチャ

図 1.カメラのアーキテクチャ

アプリ フレームワーク
アプリ フレームワーク レベルはアプリのコードで、 Camera 2 API を使用してカメラ ハードウェアとやり取りします。内部的に、このコードは対応するBinderインターフェイスを呼び出して、カメラと対話するネイティブ コードにアクセスします。
AIDL
CameraServiceに関連付けられたバインダー インターフェイスは、 frameworks/av/camera/aidl/android/hardwareにあります。生成されたコードは、下位レベルのネイティブ コードを呼び出して物理カメラへのアクセスを取得し、 CameraDeviceの作成に使用されるデータを返し、最終的にフレームワーク レベルでCameraCaptureSessionオブジェクトを返します。
ネイティブ フレームワーク
frameworks/av/にあるこのフレームワークは、 CameraDeviceおよびCameraCaptureSessionクラスに相当するネイティブを提供します。 NDK camera2 リファレンスも参照してください。
バインダー IPC インターフェース
IPC バインダー インターフェイスは、プロセス境界を越えた通信を容易にします。 frameworks/av/camera/camera/aidl/android/hardwareディレクトリには、カメラ サービスを呼び出すカメラ バインダー クラスがいくつかあります。 ICameraServiceは、カメラ サービスへのインターフェイスです。 ICameraDeviceUserは、開いている特定のカメラ デバイスへのインターフェイスです。 ICameraServiceListenerICameraDeviceCallbacksは、それぞれアプリケーション フレームワークへのCameraServiceCameraDeviceのコールバックです。
カメラサービス
frameworks/av/services/camera/libcameraservice/CameraService.cppにあるカメラ サービスは、HAL と対話する実際のコードです。
ハル
ハードウェア抽象化レイヤーは、カメラ サービスが呼び出す標準インターフェイスを定義し、カメラ ハードウェアが正しく機能するために実装する必要があります。

HAL の実装

HAL は、カメラ ドライバーと上位レベルの Android フレームワークの間に位置し、アプリがカメラ ハードウェアを正しく操作できるように実装する必要があるインターフェイスを定義します。 Camera HAL のHIDLインターフェースは、 hardware/interfaces/cameraで定義されています。

一般的なバインドされた HAL は、次の HIDL インターフェースを実装する必要があります。

  • ICameraProvider : 個々のデバイスを列挙し、それらのステータスを管理します。
  • ICameraDevice : カメラ デバイス インターフェイス。
  • ICameraDeviceSession : アクティブなカメラ デバイス セッション インターフェイス。

CameraProvider.cppCameraDevice.cppおよびCameraDeviceSession.cppの参照 HIDL 実装を使用できます。この実装では、従来の APIをまだ使用している古い HAL がラップされます。 Android 8.0 以降、Camera HAL の実装では HIDL API を使用する必要があります。レガシー インターフェイスの使用はサポートされていません。

入力検証

HAL はカメラ サービスとは異なるリソースにアクセスできるため、2 つの間の境界はセキュリティ境界として扱われます。これは、カメラ サービスから渡されたパラメーターが信頼されておらず、サニタイズされていないと見なされることを意味します。攻撃者が権限を昇格させたり、アクセスするつもりのないデータにアクセスしたりすることを可能にするセキュリティの脆弱性を防ぐために、カメラ HAL は、カメラ サービスから HAL に渡されたパラメータを検証する必要があります。これには、バッファー長の値が許容範囲内にあることの確認と、使用前およびハードウェアまたはカーネル ドライバーに渡す前のパラメーターのサニタイズが含まれます。

従来の HAL コンポーネント

このセクションでは、従来の HAL コンポーネントのアーキテクチャと、HAL の実装方法について説明します。 Android 8.0 以降の Camera HAL 実装では、代わりに上記の HIDL API を使用する必要があります。

アーキテクチャ (レガシー)

次の図とリストは、従来のカメラ HAL コンポーネントを示しています。

Android カメラのアーキテクチャ

図 2.従来のカメラ アーキテクチャ

アプリ フレームワーク
アプリ フレームワーク レベルはアプリのコードで、 android.hardware.Camera API を使用してカメラ ハードウェアとやり取りします。内部的に、このコードは対応する JNI グルー クラスを呼び出して、カメラと対話するネイティブ コードにアクセスします。
JNI
android.hardware.Cameraに関連付けられた JNI コードは、 frameworks/base/core/jni/android_hardware_Camera.cppます。このコードは、下位レベルのネイティブ コードを呼び出して物理カメラへのアクセスを取得し、フレームワーク レベルでandroid.hardware.Cameraオブジェクトを作成するために使用されるデータを返します。
ネイティブ フレームワーク
frameworks/av/camera/Camera.cppで定義されているネイティブ フレームワークは、 android.hardware.Cameraクラスに相当するネイティブを提供します。このクラスは、IPC バインダー プロキシを呼び出して、カメラ サービスへのアクセスを取得します。
バインダー IPC プロキシ
IPC バインダー プロキシは、プロセス境界を越えた通信を容易にします。 frameworks/av/cameraディレクトリに配置され、カメラ サービスを呼び出す 3 つのカメラ バインダー クラスがあります。 ICameraServiceはカメラ サービスへのインターフェイス、 ICameraは特定の開かれたカメラ デバイスへのインターフェイス、 ICameraClientはアプリ フレームワークへのデバイスのインターフェイスです。
カメラサービス
frameworks/av/services/camera/libcameraservice/CameraService.cppにあるカメラ サービスは、HAL と対話する実際のコードです。
ハル
ハードウェア抽象化レイヤーは、カメラ サービスが呼び出す標準インターフェイスを定義し、カメラ ハードウェアが正しく機能するために実装する必要があります。
カーネルドライバー
カメラのドライバーは、実際のカメラ ハードウェアおよび HAL の実装と対話します。カメラとドライバーは、ディスプレイでのカメラ画像のプレビューとビデオ録画をサポートするために、YV12 および NV21 画像形式をサポートする必要があります。

HAL の実装 (レガシー)

HAL は、カメラ ドライバーと上位レベルの Android フレームワークの間に位置し、アプリがカメラ ハードウェアを正しく操作できるように実装する必要があるインターフェイスを定義します。 HAL インターフェイスは、 hardware/libhardware/include/hardware/camera.hおよびhardware/libhardware/include/hardware/camera_common.hヘッダー ファイルで定義されています。

camera_common.hcamera_moduleを定義します。これは、カメラ ID やすべてのカメラに共通のプロパティ (つまり、前面カメラか背面カメラか) など、カメラに関する一般的な情報を取得するための標準構造です。

camera.hにはandroid.hardware.Cameraに対応するコードが含まれています。このヘッダー ファイルはcamera_device構造体を宣言します。この構造体には、HAL インターフェイスを実装する関数へのポインターを含むcamera_device_ops構造体が含まれています。開発者が設定できるカメラ パラメーターのドキュメントについては、 frameworks/av/include/camera/CameraParameters.hを参照してください。これらのパラメータは、HAL のint (*set_parameters)(struct camera_device *, const char *parms)が指す関数で設定されます。

HAL 実装の例については、 hardware/ti/omap4xxx/cameraにある Galaxy Nexus HAL の実装を参照してください。

共有ライブラリの構成

Android ビルド システムをセットアップして、HAL 実装を共有ライブラリに正しくパッケージ化し、 Android.mkファイルを作成して適切な場所にコピーします。

  1. ライブラリのソース ファイルを格納するためのdevice/<company_name>/<device_name>/cameraディレクトリを作成します。
  2. Android.mkファイルを作成して、共有ライブラリをビルドします。メイクファイルに次の行が含まれていることを確認します:
    LOCAL_MODULE := camera.<device_name>
    LOCAL_MODULE_RELATIVE_PATH := hw
    

    Android がライブラリを正しくロードできるように、ライブラリにはcamera.<device_name> ( .soが自動的に追加されます) という名前を付ける必要があります。例については、 hardware/ti/omap4xxx/Android.mkにある Galaxy Nexus カメラの makefile を参照してください。

  3. デバイスの makefile を使用して、 frameworks/native/data/etcディレクトリにある必要な機能の XML ファイルをコピーして、デバイスにカメラ機能があることを指定します。たとえば、デバイスにカメラ フラッシュがあり、オートフォーカスできることを指定するには、デバイスの<device>/<company_name>/<device_name>/device.mk makefile に次の行を追加します:
    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 \
    

    デバイス makefile の例については、 device/samsung/tuna/device.mkを参照してください。

  4. カメラのメディア コーデック、フォーマット、解像度機能をdevice/<company_name>/<device_name>/media_profiles.xmlおよびdevice/<company_name>/<device_name>/media_codecs.xml XML ファイルで宣言します。詳細については、フレームワークへのコーデックの公開を参照してください。
  5. デバイスのdevice/<company_name>/<device_name>/device.mk makefile に次の行を追加して、 media_profiles.xmlおよびmedia_codecs.xmlファイルを適切な場所にコピーします:
    # 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. デバイスのシステム イメージにカメラ アプリを含めるには、デバイスのdevice/<company>/<device>/device.mk makefile のPRODUCT_PACKAGES変数で指定します:
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...