目录
前言
CameraServer启动过程概览
总结
在系统启动过程中,init进程会启动起来,当init进程启动后,会去解析位于system/core/rootdir目录下的init.rc文件,最终会解析到到/frameworks/av/camera/cameraserver/cameraserver.rc
service cameraserver /system/bin/cameraserver
class main
user cameraserver
group audio camera input drmrpc
ioprio rt 4
task_profiles CameraServiceCapacity MaxPerformance
rlimit rtprio 10 10
这个服务的名字叫cameraserver,其对应的可执行文件的位置在/system/bin/cameraserver。关于.rc文件的讲解(类似于读取配置文件的方式,来启动不同的进程),请参考一下网上其他博客,本文就直接略过了.......
最终会进入到 /frameworks/av/camera/cameraserver/main_cameraserver.cpp的main函数中,CameraService::instantiate()就是开始唤起cameraserver了。
int main(int argc __unused, char** argv __unused)
26 {
27 signal(SIGPIPE, SIG_IGN);
28
29 // Set 5 threads for HIDL calls. Now cameraserver will serve HIDL calls in
30 // addition to consuming them from the Camera HAL as well.
31 hardware::configureRpcThreadpool(5, /*willjoin*/ false);
32
33 sp proc(ProcessState::self());
34 sp sm = defaultServiceManager();
35 ALOGI("ServiceManager: %p", sm.get());
36 CameraService::instantiate();
37 ALOGI("ServiceManager: %p done instantiate", sm.get());
38 ProcessState::self()->startThreadPool();
39 IPCThreadState::self()->joinThreadPool();
40 }
41
下面来看一看CameraService类的构成,如下
class CameraService :
public BinderService,
public virtual ::android::hardware::BnCameraService,
public virtual IBinder::DeathRecipient,
public virtual CameraProviderManager::StatusListener
{
friend class BinderService;
friend class CameraOfflineSessionClient;
..........................
}
这里采用了奇异递归模板模式,即把派生类作为基类的模板参数,这里BinderService是CameraService的基类,是一个模板类,CameraService是BinderService的子类,同时也是BinderService的模板参数。
下图是CameraService的大致启动过程
template
class BinderService
{
public:
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT)
{
sp sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);
}
static void instantiate() { publish(); }
...............
}
2. 在addService()中,这里new了一个CameraService对象,CameraService被强指针引用,因此会进入到CameraService::onFirstRef()中。这里面做的事情主要是enumProviders(),里面会进一步调用addProviderLocked(),即枚举provider。
但是这一步有可能不会成功,因为这时候时候cameraProvider可能还没有完全起来,可以看有没有打印这条log(以‘internal/0’为例):Camera provider HAL 'internal/0' is not actually available
3.如果在onFirstRef()中addProvider没有成功,那么后面会在CameraProviderManager::onRegistration()中再次调用addProviderLocked()去枚举Provider,流程如下图所示
hardware::Return CameraProviderManager::onRegistration(
const hardware::hidl_string& /*fqName*/,
const hardware::hidl_string& name,
bool preexisting) {
std::lock_guard providerLock(mProviderLifecycleLock);
{
std::lock_guard lock(mInterfaceMutex);
addProviderLocked(name, preexisting);
}
..............
}
可见在添加Provider的过程中会去构造ProviderInfo,在ProviderInfo初始化的过程中会先获取CameraProvider,通过Provider去获取 camera device相关的信息(如上图红色部分,ie.name、resourceCost、CameraId和版本等等),并将ProviderInfo和DeviceInfo存储在本地。CameraService、CameraProviderManager、ProviderInfo和DeviceInfo之前的关系如下图所示。
所以cameraserver在启动过程中主要做两件事情:
1.向serviceManager注册服务
2.获取CameraProvider、CameraDevice的信息,并存储到本地。