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 ¬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。