1. 程式人生 > >Android Camera原理之cameraserver與cameraprovider是怎樣聯絡的

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/

[email protected]_genc++_headers/gen/android/hardware/camera/provider/2.4/ICameraProviderCallback.h

言歸正傳,我們知道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>
            &notification) 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硬體就是通過這個介面呼叫