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

図 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
は、開いている特定のカメラ デバイスへのインターフェイスです。ICameraServiceListener
とICameraDeviceCallbacks
は、それぞれアプリケーション フレームワークへのCameraService
とCameraDevice
のコールバックです。 - カメラサービス
frameworks/av/services/camera/libcameraservice/CameraService.cpp
にあるカメラ サービスは、HAL と対話する実際のコードです。- ハル
- ハードウェア抽象化レイヤーは、カメラ サービスが呼び出す標準インターフェイスを定義し、カメラ ハードウェアが正しく機能するために実装する必要があります。
HAL の実装
HAL は、カメラ ドライバーと上位レベルの Android フレームワークの間に位置し、アプリがカメラ ハードウェアを正しく操作できるように実装する必要があるインターフェイスを定義します。 Camera HAL のHIDLインターフェースは、 hardware/interfaces/cameraで定義されています。
一般的なバインドされた HAL は、次の HIDL インターフェースを実装する必要があります。
-
ICameraProvider
: 個々のデバイスを列挙し、それらのステータスを管理します。 -
ICameraDevice
: カメラ デバイス インターフェイス。 -
ICameraDeviceSession
: アクティブなカメラ デバイス セッション インターフェイス。
CameraProvider.cpp
、 CameraDevice.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 コンポーネントを示しています。

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