
Android 的相機硬體抽象層 (HAL) 將Camera 2中的更高階相機框架 API 連接到底層相機驅動程式和硬體。相機子系統包括相機管道組件的實現,而相機 HAL 提供用於實現您的這些組件版本的介面。
建築學
下圖和列表描述了 HAL 組件。

圖 1.相機架構
- 應用程式框架
- 應用程式框架層級是應用程式的程式碼,它使用Camera 2 API 與相機硬體進行互動。在內部,程式碼會呼叫對應的Binder介面來存取與相機互動的本機程式碼。
- 人工智慧DL
- 與
CameraService
相關的 Binder 介面可以在Frameworks/av/camera/aidl/android/hardware中找到。產生的程式碼會呼叫較低層級的本機程式碼來取得對實體相機的存取權限,並傳回用於在框架層級建立CameraDevice
和最終CameraCaptureSession
物件的資料。 - 原生框架
- 此框架位於
frameworks/av/
中,提供了與CameraDevice
和CameraCaptureSession
類別相同的本機等效項。另請參閱NDKcamera2 參考。 - 綁定器工控機介面
- 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 框架之間,定義了一個必須實現的接口,以便應用程式可以正確操作相機硬體。相機 HAL 的HIDL介面在hardware/interfaces/camera中定義。
典型的綁定化 HAL 必須實作以下 HIDL 介面:
-
ICameraProvider
:用於列舉單一裝置並管理其狀態。 -
ICameraDevice
:相機設備介面。 -
ICameraDeviceSession
:活動相機設備會話介面。
參考 HIDL 實作可用於CameraProvider.cpp
、 CameraDevice.cpp
和CameraDeviceSession.cpp
。此實作包裝了仍使用舊版 API 的舊 HAL。從 Android 8.0 開始,Camera HAL 實作必須使用 HIDL API;不支援使用舊版介面。
輸入驗證
由於 HAL 可以存取與相機服務不同的資源,因此兩者之間的邊界被視為安全邊界。這意味著從相機服務傳遞的參數被認為是不可信和未經消毒的。為了防止安全漏洞允許攻擊者升級權限或存取他們不打算存取的數據,攝影機 HAL 必須驗證從攝影機服務傳遞到 HAL 的參數。這包括檢查緩衝區長度值是否在允許的範圍內,以及在使用之前以及將參數傳遞給硬體或核心驅動程式之前清理參數。
舊版 HAL 組件
本節介紹舊版 HAL 元件的架構以及如何實作 HAL。 Android 8.0 及更高版本上的相機 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 綁定器代理程式可取得相機服務的存取權限。- Binder IPC 代理
- IPC 綁定器代理程式有助於跨進程邊界的通訊。位於
frameworks/av/camera
目錄中的三個相機綁定器類別可呼叫相機服務。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
結構體,該結構體又包含一個camera_device_ops
結構體,其中包含指向實作HAL介面的函數的指標。有關開發人員可以設定的相機參數的文檔,請參閱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
檔案來建立共享庫。確保 makefile 包含以下行:LOCAL_MODULE := camera.<device_name> LOCAL_MODULE_RELATIVE_PATH := hw
您的庫必須命名為
camera.<device_name>
(.so
會自動附加),以便Android可以正確載入該庫。有關範例,請參閱位於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 \ ...