Camera Service


上面這張圖比較清楚的表現了camera provider進程在camera架構中位置,作為承上啟下的部分,和cameraserver進程和底層的驅動交互,camera provider進程非常重要,camera HAL層幾乎全部運行在camera provider進程中完成。

首先看下camera provider所在源碼中的位置:hardware/interfaces/camera/provider/

可以看出來在hardware/interfaces/camera/provider/2.4/default/ 下面有幾個rc文件,Android初始化就是執行這些rc文件,這里執行的是android.hardware.camera.provider@2.4-service.rc文件,看看其中的執行代碼。

 

1 service vendor.camera-provider-2-4 /vendor/bin/hw/android.hardware.camera.provider@2.4-service
2 class hal
3 user cameraserver
4 group audio camera input drmrpc
5 ioprio rt 4
6 capabilities SYS_NICE
7 writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks

 

第一行就看到了啟動一個 /vendor/bin/hw/android.hardware.camera.provider@2.4-service 進程。

Cameraserver 執行文件對應的源碼為:frameworks\av\camera\cameraserver\main_cameraserver.cpp

 

1     service cameraserver /system/bin/cameraserver
2     class main
3     user cameraserver
4     group audio camera input drmrpc
5     ioprio rt 4
6     writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
7     rlimit rtprio 10 10

 

接下來看具體的流程:

cameraserver 與 provider 這兩個進程啟動、初始化的調用邏輯
@å¾. 主è¦è°ç¨æ­¥éª¤æ»è§

總體邏輯順序:

provider 進程啟動,注冊;
cameraserver 進程啟動,注冊,初始化;
cameraserver 獲取遠端 provider(此時實例化 CameraProvider 並初始化)。
上圖中,實線箭頭是調用關系。左邊是 cameraserver 進程中的動作,右邊則是 provider 進程中的動作,它們之間通過 ICameraProvider 聯系在了一起,而這個東西與 HIDL 相關,我們可以不用關心它的實現方式。

由圖可見:

cameraserver 一側,Cameraservice 類依舊是主體。它通過 CameraProviderManager 來管理對 CameraProvider 的操作。此處初始化的最終目的是連接上 CameraProvider。
provider 一側,最終主體是 CameraProvider。初始化最終目的是得到一個 mModule,通過它可以直接與 HAL 接口定義層進行交互。
至此,我們就能對 Android O 上的 Camera 服務啟動流程有一個大致的了解。但由於我個人功力尚淺,目前只能理解到這個地步,還無法輕易抽象出更容易理解的框架,所以圖片中的流程還是比較凌亂的,可能需要對照相應代碼才能理解
 


CameraProvider 的啟動與注冊


這個服務進程的啟動很簡單,主要動作是注冊該 CameraProvider,以便 CameraServer 啟動時能找到它。需要注意的是,此時 CameraProvider 還未實例化與初始化。

Service.cpp
文件位置:hardware\interfaces\camera\provider\2.4\default

看代碼:

第 6 行:與 /dev/vndbinder 進行某種關聯,注釋表明 Camera HAL 可能會通過它與其它 vendor 組件進行通信。
第 7 行:創建默認為直通模式(passthrough)的 CameraProvider 服務實現。

 

1     int main()
2     {
3         ALOGI("Camera provider Service is starting.");
4         // The camera HAL may communicate to other vendor components via
5         // /dev/vndbinder
6         android::ProcessState::initWithDriver("/dev/vndbinder");
7         return defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0", /*maxThreads*/ 6);
8     }

 


LegacySupport.h
文件路徑:system\libhidl\transport\include\hidl

該函數做了這些事:第 5 行:配置 RPC 線程池(當前設置最大線程為 6)。
第 6 行:將 Interface(即 CameraProvider)以入參 legacy/0 為名注冊到相應的管理服務中。
第 12 行:連接到線程池。

 

 1     template<class Interface>
 2     __attribute__((warn_unused_result))
 3     status_t defaultPassthroughServiceImplementation(std::string name,
 4                                                 size_t maxThreads = 1) {
 5         configureRpcThreadpool(maxThreads, true);
 6         status_t result = registerPassthroughServiceImplementation<Interface>(name);
 7      
 8         if (result != OK) {
 9             return result;
10         }
11      
12         joinRpcThreadpool();
13         return 0;
14     }

 

registerPassthroughServiceImplementation 的模板在 LegacySupport.h 接下來就是hidl 相關的實現

 1     template<class Interface>
 2     __attribute__((warn_unused_result))
 3     status_t registerPassthroughServiceImplementation(
 4         std::string name = "default") {
 5         sp<Interface> service = Interface::getService(name, true /* getStub */); //從當前進程空間中拿到IComposer接口類對象
 6          
 7         if (service == nullptr) {
 8         ALOGE("Could not get passthrough implementation for %s/%s.",
 9         Interface::descriptor, name.c_str());
10         return EXIT_FAILURE;
11         }
12          
13         LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!",
14         Interface::descriptor, name.c_str());
15          
16         status_t status = service->registerAsService(name);//將IComposer注冊到hwservicemanager中
17          
18         if (status == OK) {
19         ALOGI("Registration complete for %s/%s.",
20         Interface::descriptor, name.c_str());
21         } else {
22         ALOGE("Could not register service %s/%s (%d).",
23         Interface::descriptor, name.c_str(), status);
24         }
25          
26         return status;
27     }

 

 

這里可以看一下 google 關於注冊服務 registerAsService 的描述: https://source.android.google.cn/devices/architecture/hidl/services

HIDL 接口服務器(實現接口的對象)可注冊為已命名的服務。注冊的名稱不需要與接口或軟件包名稱相關。如果沒有指定名稱,則使用名稱“默認”;這應該用於不需要注冊同一接口的兩個實現的 HAL。例如,在每個接口中定義的服務注冊的 C++ 調用是:

    status_t status = myFoo->registerAsService();
    status_t anotherStatus = anotherFoo->registerAsService("another_foo_service");  // if needed

 

HIDL 接口的版本包含在接口本身中。版本自動與服務注冊關聯,並可通過每個 HIDL 接口上的方法調用 (android::hardware::IInterface::getInterfaceVersion()) 進行檢索。服務器對象不需要注冊,並可通過 HIDL 方法參數傳遞到其他進程,相應的接收進程會向服務器發送 HIDL 方法調用。


CameraService 的啟動與初始化

一般來說應該是 Provider 服務先啟動,然后 Cameraserver 再啟動,並 ”連接“ 到 Provider。 
前面已經分析了 Provider 的啟動,現在就來看看 Cameraserver 的啟動流程。

main_cameraserver.cpp
文件位置:frameworks\av\camera\cameraserver

  • 關於線程池配置的部分就忽略吧,主要關注第 11 行,在該進程中實例化了 CameraService。
  • 實例化只有簡單的一行代碼,但實例化的過程並不那么簡單。這個 instantiate() 接口並不是定義在 CameraService 類中的,而是定義在 BinderService 類里(而 CameraService 繼承了它)。在此處,它的作用是創建一個 CameraService(通過 new 的方式),並將其加入到 ServiceManager 中(注意,在這一過程中,CameraService 被強指針引用了)。
 1     int main(int argc __unused, char** argv __unused)
 2     {
 3         signal(SIGPIPE, SIG_IGN);
 4          
 5         // Set 3 threads for HIDL calls
 6         hardware::configureRpcThreadpool(3, /*willjoin*/ false);
 7          
 8         sp<ProcessState> proc(ProcessState::self());
 9         sp<IServiceManager> sm = defaultServiceManager();
10         ALOGI("ServiceManager: %p", sm.get());
11         CameraService::instantiate();
12         ProcessState::self()->startThreadPool();
13         IPCThreadState::self()->joinThreadPool();
14     }

 

CameraService.cpp
文件位置:frameworks\av\services\camera\libcameraservice

由於首次被強指針引用時,就會調用 onFirstRef() 函數執行初始化之類的業務邏輯,所以現在就看看 CameraService 在此處實現了什么邏輯。

onFirstRef

  • 根據 12~ 17 行可以知道,初始化的主要邏輯實現應該在 enumerateProviders() 函數中。
  • 而最后在 19 行調用一個 ping 函數,可能是在嘗試連接到服務代理吧,不管它。

 

 1     void CameraService::onFirstRef()
 2     {
 3         ALOGI("CameraService process starting");
 4          
 5         BnCameraService::onFirstRef();
 6          
 7         // Update battery life tracking if service is restarting
 8         BatteryNotifier& notifier(BatteryNotifier::getInstance());
 9         notifier.noteResetCamera();
10         notifier.noteResetFlashlight();
11          
12         status_t res = INVALID_OPERATION;
13          
14         res = enumerateProviders();
15         if (res == OK) {
16         mInitialized = true;
17         }
18          
19         CameraService::pingCameraServiceProxy();
20     }

 

enumerateProviders

  • 函數內容略多,所以只截取需要重點關注的部分。
  • 首先將 CameraProviderManager 實例化(第 2 行),然后調用 initialize() 接口將其初始化(第 3 行),傳入的參數是 this 指針,指向當前 CameraService 實例的地址。

 

1     if (nullptr == mCameraProviderManager.get()) {
2         mCameraProviderManager = new CameraProviderManager();
3         res = mCameraProviderManager->initialize(this);
4         if (res != OK) {
5             ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
6             __FUNCTION__, strerror(-res), res);
7             return res;
8         }
9     }

 

CameraProviderManager.cpp
文件位置:frameworks\av\services\camera\libcameraservice\common

initialize
在分析具體實現之前,可以先看看它在頭文件中的聲明:

  • 用於初始化管理器,並給它設置一個狀態監聽(即 CameraService 實例)。選擇性地接受一個與服務交互的代理。
  • 默認的代理通過 Hardware 服務管理器進行通信。備用的代理可以用來進行測試。代理的生命周期必須要超過管理器的生命周期。
  • 注意到在 enumerateProviders 中調用該接口時,只有一個入參,說明當前用的是默認代理。

 

1      /**
2     * Initialize the manager and give it a status listener; optionally accepts a service
3     * interaction proxy.
4     *
5     * The default proxy communicates via the hardware service manager; alternate proxies can be
6     * used for testing. The lifetime of the proxy must exceed the lifetime of the manager.
7     */
8     status_t initialize(wp<StatusListener> listener,
9     ServiceInteractionProxy *proxy = &sHardwareServiceInteractionProxy);

 

接下來看看具體實現的邏輯:

  • 第 11~19 行:通過服務代理作出一個注冊動作。根據注釋,注冊會觸發一個給所有已知 Provider 進行通知的動作。
  • 第 22 行:這是我們主要關注的函數。注釋翻譯過來是這樣,看看這是否為一個直通的 HAL,如果不是也沒關系。注意傳入的參數 kLegacyProviderName,在文件開頭有它的定義,即為字符串 legacy/0。

 

 1     status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
 2     ServiceInteractionProxy* proxy) {
 3         std::lock_guard<std::mutex> lock(mInterfaceMutex);
 4         if (proxy == nullptr) {
 5             ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
 6             return BAD_VALUE;
 7         }
 8         mListener = listener;
 9         mServiceProxy = proxy;
10          
11         // Registering will trigger notifications for all already-known providers
12         bool success = mServiceProxy->registerForNotifications(
13         /* instance name, empty means no filter */ "",
14         this);
15         if (!success) {
16             ALOGE("%s: Unable to register with hardware service manager for notifications "
17             "about camera providers", __FUNCTION__);
18             return INVALID_OPERATION;
19         }
20          
21         // See if there's a passthrough HAL, but let's not complain if there's not
22         addProviderLocked(kLegacyProviderName, /*expected*/ false);
23          
24         return OK;
25     }

 

上面是CameraProviderManager的初始化過程,CameraProviderManager就是管理camera Service與camera provider之間通信的工程管理類,兩個參數,其中第二個參數就是遠程代理類。這個參數已經是默認賦值了。不信可以看下CameraProviderManager::initialize的定義。

 

1     status_t initialize(wp<StatusListener> listener,
2     ServiceInteractionProxy *proxy = &sHardwareServiceInteractionProxy);

 

這是定義,默認值就是 ----> sHardwareServiceInteractionProxy,這個sHardwareServiceInteractionProxy是 ----> HardwareServiceInteractionProxy 的實例,可以看出在HardwareServiceInteractionProxy定義中,已經直接調用了ICameraProvider--->getService(...)了。

 

 1     // Standard use case - call into the normal generated static methods which invoke
 2     // the real hardware service manager
 3     struct HardwareServiceInteractionProxy : public ServiceInteractionProxy {
 4     virtual bool registerForNotifications(
 5         const std::string &serviceName,
 6         const sp<hidl::manager::V1_0::IServiceNotification>
 7         &notification) override {
 8             return hardware::camera::provider::V2_4::ICameraProvider::registerForNotifications(
 9                 serviceName, notification);
10         }
11         virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
12         const std::string &serviceName) override {
13             return hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName);
14         }
15     };

 

addProviderLocked
這個函數主要作用是將找到的這個 Provider 通過 ProviderInfo 記錄下來並初始化。這兒就實現了camera service與camera provider的橋接了。

  • 第 2~8 行:檢查已知的 Provider 中是否已有名為 legacy/0 的。
  • 第 10~21 行:根據 legacy/0 從服務代理處獲取 CameraProvider 接口,這里需要特別注意,因為此處真正地初始化了對應的 CameraProvider(怎么就在這初始化了?下一節繼續分析)。
  • 第 23~28 行:通過 ProviderInfo 來保存當前 Provider 相關信息。
  • 第 30 行:記錄當前 Provider。

 

 1     status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
 2         for (const auto& providerInfo : mProviders) {
 3             if (providerInfo->mProviderName == newProvider) {
 4                 ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
 5                 newProvider.c_str());
 6                 return ALREADY_EXISTS;
 7             }
 8         }
 9          
10         sp<provider::V2_4::ICameraProvider> interface;
11         interface = mServiceProxy->getService(newProvider);
12          
13         if (interface == nullptr) {
14             if (expected) {
15                 ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
16                 newProvider.c_str());
17                 return BAD_VALUE;
18             } else {
19                 return OK;
20             }
21         }
22          
23         sp<ProviderInfo> providerInfo =
24         new ProviderInfo(newProvider, interface, this);
25         status_t res = providerInfo->initialize();
26         if (res != OK) {
27             return res;
28         }
29          
30         mProviders.push_back(providerInfo);
31          
32         return OK;
33     }

 

這里可以看一下 google 關於注冊服務 getService 的描述: https://source.android.google.cn/devices/architecture/hidl/services

發現服務 
客戶端代碼按名稱和版本請求給定的接口,並對所需的 HAL 類調用 getService:

 

1     // C++
2     sp<V1_1::IFooService> service = V1_1::IFooService::getService();
3     sp<V1_1::IFooService> alternateService = V1_1::IFooService::getService("another_foo_service");
4     // Java
5     V1_1.IFooService service = V1_1.IFooService.getService(true /* retry */);
6     V1_1.IFooService alternateService = V1_1.IFooService.getService("another", true /* retry */);

 

每個版本的 HIDL 接口都會被視為單獨的接口。因此,IFooService 版本 1.1 和 IFooService 版本 2.2 都可以注冊為“foo_service”,在任一接口上調用 getService("foo_service") 都會獲得相應接口的已注冊服務。因此,在大多數情況下,注冊或發現服務均無需提供名稱參數(也就是說名稱為“默認”)。

供應商接口對象還會影響所返回接口的傳輸方法。對於軟件包 android.hardware.foo@1.0 中的接口 IFoo,IFoo::getService 返回的接口始終使用設備清單中針對 android.hardware.foo 聲明的傳輸方法(如果相應條目存在的話);如果該傳輸方法不存在,則返回 nullptr。

在某些情況下,即使沒有獲得相關服務,也可能需要立即繼續。例如,當客戶端希望自行管理服務通知或者在需要獲得所有 hwservice 並檢索它們的診斷程序(如 atrace)中時,可能會發生這種情況。在這種情況下,可以使用其他 API,如 C++ 中的 tryGetService 或 Java 中的 getService("instance-name", false)。Java 中提供的舊版 API getService 也必須與服務通知一起使用。使用此 API 不會避免以下競態條件:當客戶端使用某個非重試 API 請求服務器后,該服務器對自身進行了注冊。

CameraProviderManager中提供了一個ProviderInfo來保存Camera provider信息,方便管理camera service調用 camera provider,下面分析一下ProviderInfo是怎么樣的?方便我們接下來從這個為切入掉分析camera provider里面代碼。

 

 1     struct ProviderInfo :
 2     virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,
 3     virtual public hardware::hidl_death_recipient
 4     {
 5         const std::string mProviderName;
 6         const sp<hardware::camera::provider::V2_4::ICameraProvider> mInterface;
 7          
 8         ProviderInfo(const std::string &providerName,
 9         sp<hardware::camera::provider::V2_4::ICameraProvider>& interface,
10         CameraProviderManager *manager);
11          
12          
13         status_t initialize();
14         status_t addDevice(const std::string& name,
15         hardware::camera::common::V1_0::CameraDeviceStatus initialStatus =
16         hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT,
17         /*out*/ std::string *parsedId = nullptr);
18          
19          
20         // ICameraProviderCallbacks interface - these lock the parent mInterfaceMutex
21         virtual hardware::Return<void> cameraDeviceStatusChange(
22         const hardware::hidl_string& cameraDeviceName,
23         hardware::camera::common::V1_0::CameraDeviceStatus newStatus) override;
24         virtual hardware::Return<void> torchModeStatusChange(
25         const hardware::hidl_string& cameraDeviceName,
26         hardware::camera::common::V1_0::TorchModeStatus newStatus) override;
27          
28          
29         // hidl_death_recipient interface - this locks the parent mInterfaceMutex
30         virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who) override;
31          
32          
33         //......
34     };

 

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順利運行。


CameraProvider 的初始化


在 CameraService 的初始化過程中,CameraProvider 才開始進行初始化,只不過這個初始化是通過服務代理進行遠端調用而進行的。

在 CameraProviderManager::addProviderLocked 函數的實現邏輯中,調用了 ICameraProvider::getService 接口,該接口最終會調用到一個名為 HIDL_FETCH_ICameraProvider 的函數。

CameraProvider.cpp
文件位置:hardware\interfaces\camera\provider\2.4\default

HIDL_FETCH_ICameraProvider
若傳入的參數是 legacy/0,則創建一個 CameraProvider 實例(構造函數中調用了它自身的初始化函數)並返回相應指針給函數調用者。
 

 1     ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
 2         if (strcmp(name, kLegacyProviderName) != 0) {
 3             return nullptr;
 4         }
 5         CameraProvider* provider = new CameraProvider();
 6         if (provider == nullptr) {
 7             ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
 8             return nullptr;
 9         }
10         if (provider->isInitFailed()) {
11             ALOGE("%s: camera provider init failed!", __FUNCTION__);
12             delete provider;
13             return nullptr;
14         }
15         return provider;
16     }

 

 

initialize
整個函數實現比較冗長,只貼出我們需要關注的部分分析。

  • 第 1~7 行:需要注意 rawModule 這個指針指向的結構,通過 hw_get_module 函數獲取到它的實例(從相應的 Camera HAL 動態庫中加載得到)。實際上這個結構就是連接到 HAL 層的關鍵點,通過它就可以調用到 HAL 中的一些函數。
  • (關於 hw_get_module,我以前分析過 Android N 上相關的邏輯,在 O 上其實沒有很大改動,如果要詳細了解可以去看看那篇文章)
  • 第 9~15 行:基於 rawModule 創建 CameraModule 實例並初始化。之后都是通過 mModule 來對 HAL 進行操作的。(其實 CameraModule 是對於 camera_module_t 的一層封裝,諸如 init、open 這樣的操作,實際上都是通過調用 camera_module_t 結構中函數指針指向的 HAL 層的具體實現函數來完成的)
  • 執行完這個函數,CameraProvider 也就隨之初始化完成了。

 

 1     camera_module_t *rawModule;
 2     int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
 3     (const hw_module_t **)&rawModule);
 4     if (err < 0) {
 5         ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
 6         return true;
 7     }
 8      
 9     mModule = new CameraModule(rawModule);
10     err = mModule->init();
11     if (err != OK) {
12         ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
13         mModule.clear();
14         return true;
15     }
16     ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());

 

期間使用了camera_module_t這個結構體。可以看下 CameraModule::init函數。

 

 1     int CameraModule::init() {
 2         ATRACE_CALL();
 3         int res = OK;
 4         if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 &&
 5             mModule->init != NULL) {
 6             ATRACE_BEGIN("camera_module->init");
 7             res = mModule->init();
 8             ATRACE_END();
 9         }
10         mCameraInfoMap.setCapacity(getNumberOfCameras());
11         return res;
12     }

 

這兒調用的mModule->init(); 這個mModule就是camera_module_t結構體對象

 

 1     typedef struct camera_module {
 2         hw_module_t common;
 3         int (*get_number_of_cameras)(void);
 4         int (*get_camera_info)(int camera_id, struct camera_info *info);
 5         int (*set_callbacks)(const camera_module_callbacks_t *callbacks);
 6         void (*get_vendor_tag_ops)(vendor_tag_ops_t* ops);
 7         int (*open_legacy)(const struct hw_module_t* module, const char* id,
 8         uint32_t halVersion, struct hw_device_t** device);
 9         int (*set_torch_mode)(const char* camera_id, bool enabled);
10         int (*init)();
11         void* reserved[5];
12     } camera_module_t;

 

結構體中有一些函數指針,我們現在需要搞清楚這些函數指針被映射到什么地方了? camx 和 mm-camera 是一樣的實現 類似於:(關於qcom的code只是copy了其他博文上的code)

 

 1     camera_module_t HAL_MODULE_INFO_SYM __attribute__ ((visibility("default"))) = {
 2         .common = {
 3             .tag = HARDWARE_MODULE_TAG,
 4             .module_api_version = CAMERA_MODULE_API_VERSION_2_2,
 5             .hal_api_version = HARDWARE_HAL_API_VERSION,
 6             .id = CAMERA_HARDWARE_MODULE_ID,
 7             .name = "Default Camera HAL",
 8             .author = "The Android Open Source Project",
 9             .methods = &gCameraModuleMethods,
10             .dso = NULL,
11             .reserved = {0},
12         },
13         .get_number_of_cameras = get_number_of_cameras,
14         .get_camera_info = get_camera_info,
15         .set_callbacks = set_callbacks,
16         .get_vendor_tag_ops = get_vendor_tag_ops,
17         .open_legacy = NULL,
18         .set_torch_mode = NULL,
19         .init = NULL,
20         .reserved = {0},
21     };

 

 

 1     static hw_module_t camera_common = {
 2         .tag = HARDWARE_MODULE_TAG,
 3         .module_api_version = CAMERA_MODULE_API_VERSION_2_4,
 4         .hal_api_version = HARDWARE_HAL_API_VERSION,
 5         .id = CAMERA_HARDWARE_MODULE_ID,
 6         .name = "QCamera Module",
 7         .author = "Qualcomm Innovation Center Inc",
 8         .methods = &qcamera::QCamera2Factory::mModuleMethods,
 9         .dso = NULL,
10         .reserved = {0}
11     };
12      
13     camera_module_t HAL_MODULE_INFO_SYM = {
14         .common = camera_common,
15         .get_number_of_cameras = qcamera::QCamera2Factory::get_number_of_cameras,
16         .get_camera_info = qcamera::QCamera2Factory::get_camera_info,
17         .set_callbacks = qcamera::QCamera2Factory::set_callbacks,
18         .get_vendor_tag_ops = qcamera::QCamera3VendorTags::get_vendor_tag_ops,
19         .open_legacy = NULL,
20         .set_torch_mode = qcamera::QCamera2Factory::set_torch_mode,
21         .init = NULL,
22         .reserved = {0}
23     };

 

 

 

 


小結


在 Android O 之前,Service 與 HAL 的耦合比較嚴重,而現在 Google 通過 HIDL 這個進程通信機制將他們分隔成兩個進程,這使得 Service 與 HAL 之間的通路建立過程變得復雜了一些。 
本文對 Android O 上,這兩個進程的啟動與初始化流程進行了簡單的分析。總體來說是如下邏輯順序:

  1. android.hardware.camera.provider@2.4-service 進程啟動,僅注冊 Provider;
  2. cameraserver 進程啟動,實例化 CameraService,並注冊到 ServiceManager 中;
  3. 由於強指針首次引用,CameraService::onFirstRef() 被調用,相當於進行初始化;
  4. 在 CameraService 初始化過程中,通過 CameraProviderManager 來獲取已注冊的 Provider,並實例化、初始化 CameraProvider;
  5. CameraProvider 初始化過程中,從動態庫中加載了 HAL 層的關鍵結構,並將其封裝到 CameraModule 中;
  6. 將獲取到的 CameraProvider 保存在 ProviderInfo 中,以便后續的使用。

這其實就相當於 Android N 之前,整個 cameraserver 的啟動流程。殊途同歸,最后都是通過 CameraModule 及其內部的 camera_module_t 連接到 Camera HAL。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM