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 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的模板参数。

CameraServer启动过程概览

    下图是CameraService的大致启动过程

Android Camera之CameraServer的启动过程_第1张图片

  1.  调用CameraService::instantiate()时,会call到其父类BinderService::instantiate(),这里面做的事情主要是向ServiceManager注册服务,即把CameraServer注册到ServiceManager中。如下这段代码所示,因为这里的SERVICE就是CameraService,在addService()函数中,getServiceName()会返回---->"media.camera",new SERVICE()即是构造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);
      }
..............
}

Android Camera之CameraServer的启动过程_第2张图片

        可见在添加Provider的过程中会去构造ProviderInfo,在ProviderInfo初始化的过程中会先获取CameraProvider,通过Provider去获取 camera device相关的信息(如上图红色部分,ie.name、resourceCost、CameraId和版本等等),并将ProviderInfo和DeviceInfo存储在本地。CameraService、CameraProviderManager、ProviderInfo和DeviceInfo之前的关系如下图所示。

Android Camera之CameraServer的启动过程_第3张图片

总结

所以cameraserver在启动过程中主要做两件事情:

1.向serviceManager注册服务

2.获取CameraProvider、CameraDevice的信息,并存储到本地。

你可能感兴趣的:(Android,Camera,android,java,apache)