android底層HAL層深入瞭解
需要了解android底層開發,尤其是針對廠商介面對接,我們就需要針對android的HAL層做深入理解,在android的六層架構中,其中HAL層架構在linux驅動層之上,下面我們就來以相機為列做初步瞭解(官方輸出),福利:基礎應用開源框架
Android 的相機硬體抽象層 (HAL) 可將 Camera 2 中較高級別的相機框架 API 連線到底層的相機驅動程式和硬體。相機子系統包括相機管道元件的實現,而相機 HAL 則可提供用於實現您的這些元件版本的介面。
注意:如果您要在搭載 Android 8.0 或更高版本的裝置上實現相機 HAL,則必須使用 HIDL 介面。要了解舊版元件,請參閱
架構
下列圖表和列表說明了 HAL 元件:
圖 1. 相機架構
應用框架
應用程式碼位於應用框架級別,它使用 Camera 2 API 與相機硬體進行互動。在內部,此程式碼會呼叫相應的 Binder 介面,以訪問與該相機互動的原生程式碼。
AIDL
原生框架
Binder IPC 介面
IPC binder 介面用於實現跨越程序邊界的通訊。呼叫相機服務的 frameworks/av/camera/camera/aidl/android/hardware
目錄中有若干個相機 binder 類。 ICameraService 是相機服務的介面;ICameraDeviceUser
相機服務
位於 frameworks/av/services/camera/libcameraservice/CameraService.cpp
下的相機服務是與 HAL 進行互動的實際程式碼。
HAL
硬體抽象層定義了由相機服務呼叫且您必須實現以確保相機硬體正常執行的標準介面。
實現 HAL
HAL 位於相機驅動程式和更高級別的 Android 框架之間,並可定義您必須實現的介面,以便應用可以正確地操作相機硬體。從 Android 8.0 開始,相機 HAL 介面是 Project
典型的繫結式 HAL 必須實現以下 HIDL 介面:
要詳細瞭解 Treble 和 HAL 開發,請參閱 Treble 資源。
舊版 HAL 元件
此部分介紹了舊版 HAL 元件的架構以及如何實現 HAL。搭載 Android 8.0 或更高版本的裝置上的相機 HAL 實現必須改用 HIDL API(如上所述)。
架構(舊版)
下列圖表和列表說明了舊版相機 HAL 元件:
圖 1. 相機架構
應用框架
應用程式碼位於應用框架級別,它利用 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 代理,以獲取對相機服務的訪問許可權。
Binder IPC 代理
IPC binder 代理用於促進跨越程序邊界的通訊。呼叫相機服務的 frameworks/av/camera
目錄中有 3 個相機 binder 類。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
;這是一個標準結構,可用於獲取有關相機的一般資訊,例如相機 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
檔案來編譯共享庫。確保 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 \ ...