
上面這張圖比較清楚的表現了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 ¬ification) 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 上,這兩個進程的啟動與初始化流程進行了簡單的分析。總體來說是如下邏輯順序:
- android.hardware.camera.provider@2.4-service 進程啟動,僅注冊 Provider;
- cameraserver 進程啟動,實例化 CameraService,並注冊到 ServiceManager 中;
- 由於強指針首次引用,CameraService::onFirstRef() 被調用,相當於進行初始化;
- 在 CameraService 初始化過程中,通過 CameraProviderManager 來獲取已注冊的 Provider,並實例化、初始化 CameraProvider;
- CameraProvider 初始化過程中,從動態庫中加載了 HAL 層的關鍵結構,並將其封裝到 CameraModule 中;
- 將獲取到的 CameraProvider 保存在 ProviderInfo 中,以便后續的使用。
這其實就相當於 Android N 之前,整個 cameraserver 的啟動流程。殊途同歸,最后都是通過 CameraModule 及其內部的 camera_module_t 連接到 Camera HAL。
