zoukankan      html  css  js  c++  java
  • 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 执行文件对应的源码为:frameworksavcameracameraservermain_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
    文件位置:hardwareinterfacescameraprovider2.4default

    看代码:

    第 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
    文件路径:systemlibhidl ransportincludehidl

    该函数做了这些事:第 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
    文件位置:frameworksavcameracameraserver

    • 关于线程池配置的部分就忽略吧,主要关注第 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
    文件位置:frameworksavservicescameralibcameraservice

    由于首次被强指针引用时,就会调用 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
    文件位置:frameworksavservicescameralibcameraservicecommon

    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         &notification) 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
    文件位置:hardwareinterfacescameraprovider2.4default

    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 上,这两个进程的启动与初始化流程进行了简单的分析。总体来说是如下逻辑顺序:

    1. android.hardware.camera.provider@2.4-service 进程启动,仅注册 Provider;
    2. cameraserver 进程启动,实例化 CameraService,并注册到 ServiceManager 中;
    3. 由于强指针首次引用,CameraService::onFirstRef() 被调用,相当于进行初始化;
    4. 在 CameraService 初始化过程中,通过 CameraProviderManager 来获取已注册的 Provider,并实例化、初始化 CameraProvider;
    5. CameraProvider 初始化过程中,从动态库中加载了 HAL 层的关键结构,并将其封装到 CameraModule 中;
    6. 将获取到的 CameraProvider 保存在 ProviderInfo 中,以便后续的使用。

    这其实就相当于 Android N 之前,整个 cameraserver 的启动流程。殊途同归,最后都是通过 CameraModule 及其内部的 camera_module_t 连接到 Camera HAL。

  • 相关阅读:
    根据模板自动生成数据
    CSV to XLSX (专用)
    释放用完的Excel COM组件
    配置文件的力量
    字符编解码的故事(ASCII,ANSI,Unicode,Utf-8区别)
    将结果中的省略号内容全部输出
    Powershell变量的类型
    一些用过的C#类库收集
    运算符
    特殊运算符
  • 原文地址:https://www.cnblogs.com/SaraMoring/p/14348263.html
Copyright © 2011-2022 走看看