Android Camera之CameraServer的启动过程

目录

前言       

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<ProcessState> proc(ProcessState::self());
34      sp<IServiceManager> 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<CameraService>,
      public virtual ::android::hardware::BnCameraService,
      public virtual IBinder::DeathRecipient,
      public virtual CameraProviderManager::StatusListener
  {
      friend class BinderService<CameraService>;
      friend class CameraOfflineSessionClient;
        ..........................
  }

        这里采用了奇异递归模板模式,即把派生类作为基类的模板参数,这里BinderService是CameraService的基类,是一个模板类,CameraService是BinderService的子类,同时也是BinderService的模板参数。

CameraServer启动过程概览

    下图是CameraService的大致启动过程

  1.  调用CameraService::instantiate()时,会call到其父类BinderService::instantiate(),这里面做的事情主要是向ServiceManager注册服务,即把CameraServer注册到ServiceManager中。如下这段代码所示,因为这里的SERVICE就是CameraService,在addService()函数中,getServiceName()会返回---->"media.camera",new SERVICE()即是构造CameraService
template<typename SERVICE>
class BinderService
{
  public:
      static status_t publish(bool allowIsolated = false,
                              int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) 
      {
          sp<IServiceManager> 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<void> CameraProviderManager::onRegistration(
          const hardware::hidl_string& /*fqName*/,
          const hardware::hidl_string& name,
          bool preexisting) {
      std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
      {
         std::lock_guard<std::mutex> 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的信息,并存储到本地。

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值