Android Camera原理之cameraserver與cameraprovider是怎樣聯絡的
我們熟知的camera架構是下面這張圖:
底層是camera driver,和硬體強相關;camera driver上層是操作驅動的camera HAL層,這也是各家廠商camera的核心程式碼,廠商封裝好自己的程式碼,不必遵守開源條件,camera HAL層也是修改優化的重點,這一塊是跑在camera provider程序中的,下面會詳細分析一下。camera service是camera provider和上層通訊的橋樑,只是作為一箇中間層。camera framework是開發者熟知的呼叫介面。
camera架構 (1).jpg
camera framework和camera service層大家可能都比較熟悉,但是camera provider,就是我們熟知的Camera HAL層,這一塊我們還不是很清楚。我們本文主要就是想幫助大家理解清楚camera service與camera provider之間的聯絡。
前面已經講了很多camera framework與camera service之間的呼叫聯絡和相互關係,這兒不展開描述了,camera HAL層一直比較神祕,因為google真是為了保證各家廠商可以完整保護自己的硬體原始碼,才在camera driver基礎上搞了一個camera HAL,便於各家廠商封裝自己的介面,所以各家廠商的camera HAL層其實是不開源的,這也是各家廠商camera優化的重點。
1.camera provider是何時註冊的?
就像aidl是framework和service之間IPC的通訊方式,實際上通過Binder IPC,camera provider與camera service之間的通訊也會藉助一個載體hal ----> hardware abstract layer(硬體抽象層)。
下面看下具體的hal程式碼例子。
image.png
編譯的時候會自動生成 .h 檔案,這個裡面包含的介面可以保證camera provider與 camera service直接通訊呼叫。
./out/soong/.intermediates/hardware/interfaces/camera/provider/2.4/[email protected]_genc++_headers/gen/android/hardware/camera/provider/2.4/ICameraProvider.h
./out/soong/.intermediates/hardware/interfaces/camera/provider/2.4/
言歸正傳,我們知道camera provider主要處理 camera HAL的功能,camera service要和camera provider通訊,也是跨程序呼叫,原理和aidl類似的,也是需要註冊service的。具體的註冊過程如下:
下圖反映了cameraprovider啟動的時候,共註冊了兩個provider,一個名為 legacy/0 ,另一個是 external/0
camera provider註冊流程.jpg
具體的註冊過程大家可以根據我上面圖提示的程式碼路徑去看一下,這兒不贅述了。
2.camera service如何呼叫camera provider?
camera provider註冊的地方已經知道,有註冊肯定有呼叫,呼叫的地方就在camera service,為了方便大家的理解,直接貼上一張時序圖,大家可以對照程式碼自己看看。
camera provider呼叫流程.jpg
從上面的呼叫流程來看,cameraservice初始化的時候,也會建立camera service和camera provider之間的聯絡,將建立的providerInfo放在記憶體中,之後直接取記憶體中的providerInfo,可以從camera service呼叫到camera provider了。
但是這兒我還是要講一講具體的聯絡過程:
status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
ServiceInteractionProxy* proxy) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
if (proxy == nullptr) {
ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
return BAD_VALUE;
}
mListener = listener;
mServiceProxy = proxy;
// Registering will trigger notifications for all already-known providers
bool success = mServiceProxy->registerForNotifications(
/* instance name, empty means no filter */ "",
this);
if (!success) {
ALOGE("%s: Unable to register with hardware service manager for notifications "
"about camera providers", __FUNCTION__);
return INVALID_OPERATION;
}
// See if there's a passthrough HAL, but let's not complain if there's not
addProviderLocked(kLegacyProviderName, /*expected*/ false);
addProviderLocked(kExternalProviderName, /*expected*/ false);
return OK;
}
上面是CameraProviderManager的初始化過程,CameraProviderManager就是管理camera Service與camera provider之間通訊的工程管理類,兩個引數,其中第二個引數就是遠端代理類。這個引數已經是預設賦值了。不信可以看下CameraProviderManager::initialize的定義。
status_t initialize(wp<StatusListener> listener,
ServiceInteractionProxy *proxy = &sHardwareServiceInteractionProxy);
這是定義,預設值就是 ----> sHardwareServiceInteractionProxy,這個sHardwareServiceInteractionProxy是 ----> HardwareServiceInteractionProxy 的例項,可以看出在HardwareServiceInteractionProxy定義中,已經直接呼叫了ICameraProvider--->getService(...)了。
// Standard use case - call into the normal generated static methods which invoke
// the real hardware service manager
struct HardwareServiceInteractionProxy : public ServiceInteractionProxy {
virtual bool registerForNotifications(
const std::string &serviceName,
const sp<hidl::manager::V1_0::IServiceNotification>
¬ification) override {
return hardware::camera::provider::V2_4::ICameraProvider::registerForNotifications(
serviceName, notification);
}
virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
const std::string &serviceName) override {
return hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName);
}
};
CameraProviderManager::initialize 中加入了兩個ProviderName,就是我們camera provider的兩個service name -----> (legacy/0 extrenal/0)
addProviderLocked(kLegacyProviderName, /expected/ false);
addProviderLocked(kExternalProviderName, /expected/ false);
這兒就實現了camera service與camera provider的橋接了。
3.CameraProviderManager→ProviderInfo資料結構
CameraProviderManager中提供了一個ProviderInfo來儲存Camera provider資訊,方便管理camera service呼叫 camera provider,下面分析一下ProviderInfo是怎麼樣的?方便我們接下來從這個為切入掉分析camera provider裡面程式碼。
struct ProviderInfo :
virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,
virtual public hardware::hidl_death_recipient
{
const std::string mProviderName;
const sp<hardware::camera::provider::V2_4::ICameraProvider> mInterface;
ProviderInfo(const std::string &providerName,
sp<hardware::camera::provider::V2_4::ICameraProvider>& interface,
CameraProviderManager *manager);
status_t initialize();
status_t addDevice(const std::string& name,
hardware::camera::common::V1_0::CameraDeviceStatus initialStatus =
hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT,
/*out*/ std::string *parsedId = nullptr);
// ICameraProviderCallbacks interface - these lock the parent mInterfaceMutex
virtual hardware::Return<void> cameraDeviceStatusChange(
const hardware::hidl_string& cameraDeviceName,
hardware::camera::common::V1_0::CameraDeviceStatus newStatus) override;
virtual hardware::Return<void> torchModeStatusChange(
const hardware::hidl_string& cameraDeviceName,
hardware::camera::common::V1_0::TorchModeStatus newStatus) override;
// hidl_death_recipient interface - this locks the parent mInterfaceMutex
virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who) override;
//......
};
ProviderInfo繼承了 hardware::camera::provider::V2_4::ICameraProviderCallback 與 hardware::hidl_death_recipient,其中ProviderInfo 第 2個引數就是camera service與cameraprovider通訊的IPC介面,保證兩層可以順利通訊。
ICameraProviderCallback 是 camera provider的 回撥介面,也是可以IPC間通訊的,hardware::hidl_death_recipient 是hal層的死亡回撥介面,方便在底層死亡的時候通知上層。
initialize() ----> initialize 函式的主要作用是初始化camera provider,並且IPC呼叫到camera provider 獲取camera device資訊,然後呼叫 addDevice介面將獲取的camera device儲存在記憶體中。
addDevice ----> 將底層獲取的camera device資訊儲存在camera service中,防止多次跨程序呼叫。
cameraDeviceStatusChange 與 torchModeStatusChange 都是 ICameraProviderCallback 的回撥函式,當camera provider發生變化的時候需要通知上層這些變化。
serviceDied 是 hardware::hidl_death_recipient 的回撥函式,當底層發生問題的時候會通知上層變化。
我們在camera service中就是使用 ProviderInfo 來和底層的camera provider通訊,儲存camera device順利執行。
4.ProviderInfo ----> DeviceInfo3資料結構
ProviderInfo中還有幾個DeviceInfo型別的資料結構,但是最新的都是採用了DeviceInfo3資料結構,所以這裡只關注DeviceInfo3
// HALv3-specific camera fields, including the actual device interface
struct DeviceInfo3 : public DeviceInfo {
typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT;
const sp<InterfaceT> mInterface;
virtual status_t setTorchMode(bool enabled) override;
virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
virtual bool isAPI1Compatible() const override;
virtual status_t dumpState(int fd) const override;
virtual status_t getCameraCharacteristics(
CameraMetadata *characteristics) const override;
DeviceInfo3(const std::string& name, const metadata_vendor_id_t tagId,
const std::string &id, uint16_t minorVersion,
const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
sp<InterfaceT> interface);
virtual ~DeviceInfo3();
private:
CameraMetadata mCameraCharacteristics;
};
DeviceInfo3中定義的InterfaceT 是 hardware::camera::device::V3_2::ICameraDevice 型別。
./hardware/interfaces/camera/device/3.2/ICameraDevice.hal ----> ./out/soong/.intermediates/hardware/interfaces/camera/device/3.2/[email protected]_genc++_headers/gen/android/hardware/camera/device/3.2/ICameraDevice.h
操作底層camera device硬體就是通過這個介面呼叫