• 虚拟摄像头之六: 《详解 CameraService 都做了什么》之 CameraService 与 CameraProvider 通讯


    前言

    上一篇梳理了 CameraProvider 是独立服务、通过 v4l2 框架管理物理摄像头,本篇主要描述的是 CameraService 如何与 CameraProvider 通讯;
    android 的 CameraService 是 Camera 子系统核心模块,Camera Api1 和 Api2 的接口、是如何与CameraService 通讯呢?笔者将分两篇来介绍。

    CameraService 运行环境部署

    首先看一下他的Android.mk 编译配置文件
    @frameworks/av/camera/cameraserver/Android.mk

    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    
    LOCAL_SRC_FILES:= \
      main_cameraserver.cpp
    
    LOCAL_SHARED_LIBRARIES := \
      libcameraservice \
      liblog \
      libutils \
      libui \
      libgui \
      libbinder \
      libhidltransport \
      android.hardware.camera.common@1.0 \
      android.hardware.camera.provider@2.4 \
      android.hardware.camera.device@1.0 \
      android.hardware.camera.device@3.2
    
    LOCAL_MODULE:= cameraserver
    
    LOCAL_32_BIT_ONLY := true
    LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter
    LOCAL_INIT_RC := cameraserver.rc
    include $(BUILD_EXECUTABLE)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    编译生成的是可执行文件,它依赖的库文件 libcameraservice 就是 CameraService 生成的库;
    依赖的 libbinder 库就是与 libcamera_client.so 通讯使用的库文件;
    依赖的 android.hardware.camera.provider@2.4 库是与 CameraProvider 通讯使用的库文件.

    他的入口函数在哪里呢?

    @frameworks/av/camera/cameraserver/main_cameraserver.cpp

    #define LOG_TAG "cameraserver"
    //#define LOG_NDEBUG 0
    #include "CameraService.h"
    #include 
    
    using namespace android;
    
    int main(int argc __unused, char** argv __unused)
    {
        signal(SIGPIPE, SIG_IGN);
    
        // Set 3 threads for HIDL calls
        hardware::configureRpcThreadpool(3, /*willjoin*/ false);
    
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());
        CameraService::instantiate();
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    什么时候启动这个服务的呢?

    @frameworks/av/camera/cameraserver/cameraserver.rc

    service cameraserver /system/bin/cameraserver
        class main
        user cameraserver
        group audio camera input drmrpc
        ioprio rt 4
        writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    此文件中定义了 cameraserver 服务名称,启动位置在 servicemanager.rc 文件中,笔者开发板文件路径:
    @frameworks/native/cmds/servicemanager/servicemanager.rc

    service servicemanager /system/bin/servicemanager
        class core animation
        user system
        group system readproc
        critical
        onrestart restart healthd
        onrestart restart zygote
        onrestart restart audioserver                //> 启动声卡
        onrestart restart media
        onrestart restart surfaceflinger             
        onrestart restart inputflinger
        onrestart restart drm
        onrestart restart cameraserver               //> 启动 cameraserver 服务
        writepid /dev/cpuset/system-background/tasks
        shutdown critical
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    我们清楚知道 cameraserver 入口函数,以及系统什么时候开启这个服务。当服务启动时执行 CameraService::instantiate();方法是cameraserver 继承 BinderService 类的instantiate方法,他的定义如下: @frameworks/native/include/binder/BinderService.h

    namespace android {
    template<typename SERVICE>
    class BinderService
    {
    public:
        static status_t publish(bool allowIsolated = false) {
            sp<IServiceManager> sm(defaultServiceManager());
            return sm->addService(
                    String16(SERVICE::getServiceName()),
                    new SERVICE(), allowIsolated);
        }
    
        static void publishAndJoinThreadPool(bool allowIsolated = false) {
            publish(allowIsolated);
            joinThreadPool();
        }
    
        static void instantiate() { publish(); }
    
        static status_t shutdown() { return NO_ERROR; }
    
    private:
        static void joinThreadPool() {
            sp<ProcessState> ps(ProcessState::self());
            ps->startThreadPool();
            ps->giveThreadPoolName();
            IPCThreadState::self()->joinThreadPool();
        }
    };
    
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    addService 方法申明如下:

    virtual status_t            addService( const String16& name,
                                                const sp& service,
                                                bool allowIsolated = false) = 0;
    
    • 1
    • 2
    • 3

    在 main_cameraserver.cpp 中, 执行 CameraService::instantiate(); 调用是继承类BinderService的 instantiate() 函数,该函数调用 publish(); ==> sm->addService( String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);BinderService 提供了 Service 的创建和发布;

    而 new SERVICE() 就是 new 一个 CameraService 对象、该对象返回值被 const sp& service 引用, CameraService构造函数内容如下:

    CameraService::CameraService() :
            mEventLog(DEFAULT_EVENT_LOG_LENGTH),
            mNumberOfCameras(0), mNumberOfNormalCameras(0),
            mSoundRef(0), mInitialized(false) {
        ALOGI("CameraService started (pid=%d)", getpid());
    
        this->camera_device_status_change = android::camera_device_status_change;
        this->torch_mode_status_change = android::torch_mode_status_change;
    
        mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这一过程中,CameraService 首次被强指针引用时,就会调用 CameraService::onFirstRef() 函数执行初始化之类的业务逻辑,所以现在就看看 CameraService 在此处实现了什么;

    void CameraService::onFirstRef()
    {
        ALOGI("CameraService process starting");
        //> 1. 继承 BnCameraService 类
        BnCameraService::onFirstRef();
    
        // Update battery life tracking if service is restarting
        BatteryNotifier& notifier(BatteryNotifier::getInstance());
        notifier.noteResetCamera();
        notifier.noteResetFlashlight();
    
        status_t res = INVALID_OPERATION;
        //> 2. CameraProvider 服务
        res = enumerateProviders();
        if (res == OK) {
            mInitialized = true;
        }
        //> 3. 激活 media.camera.proxy 服务
        CameraService::pingCameraServiceProxy();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    该方法中调用 res = enumerateProviders() 函数,此函数就是 CameraService 与 CameraProvider 通讯关联的入口函数。

    CameraService 如何与 CameraProvider 通讯

    在 CameraService::onFirstRef 中调用 enumerateProviders() ,代码内容如下:

    status_t CameraService::enumerateProviders() {
        status_t res;
        Mutex::Autolock l(mServiceLock);
    
        if (nullptr == mCameraProviderManager.get()) {
            mCameraProviderManager = new CameraProviderManager();
            res = mCameraProviderManager->initialize(this);
            if (res != OK) {
                ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
                        __FUNCTION__, strerror(-res), res);
                return res;
            }
        }
    
        mNumberOfCameras = mCameraProviderManager->getCameraCount();
        mNumberOfNormalCameras =
                mCameraProviderManager->getAPI1CompatibleCameraCount();
    
        // Setup vendor tags before we call get_camera_info the first time
        // because HAL might need to setup static vendor keys in get_camera_info
        // TODO: maybe put this into CameraProviderManager::initialize()?
        mCameraProviderManager->setUpVendorTags();
    
        if (nullptr == mFlashlight.get()) {
            mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
        }
    
        res = mFlashlight->findFlashUnits();
        if (res != OK) {
            ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
        }
    
        for (auto& cameraId : mCameraProviderManager->getCameraDeviceIds()) {
            String8 id8 = String8(cameraId.c_str());
            bool cameraFound = false;
            {
    
                Mutex::Autolock lock(mCameraStatesLock);
                auto iter = mCameraStates.find(id8);
                if (iter != mCameraStates.end()) {
                    cameraFound = true;
                }
            }
    
            if (!cameraFound) {
                hardware::camera::common::V1_0::CameraResourceCost cost;
                res = mCameraProviderManager->getResourceCost(cameraId, &cost);
                if (res != OK) {
                    ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
                    continue;
                }
                std::set<String8> conflicting;
                for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
                    conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
                }
    
                {
                    Mutex::Autolock lock(mCameraStatesLock);
                    mCameraStates.emplace(id8,
                        std::make_shared<CameraState>(id8, cost.resourceCost, conflicting));
                }
            }
    
            onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
    
            if (mFlashlight->hasFlashUnit(id8)) {
                mTorchStatusMap.add(id8, TorchModeStatus::AVAILABLE_OFF);
            }
        }
    
        return OK;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    首先将 new CameraProviderManager() 实例化,然后调用 initialize() 接口将其初始化,传入的参数是 this 指针,指向当前 CameraService 实例的地址。 initialize 在分析具体实现之前,可以先看看它在头文件中的声明:

    class CameraProviderManager : virtual public hidl::manager::V1_0::IServiceNotification {
    
        struct HardwareServiceInteractionProxy : public ServiceInteractionProxy {
            virtual bool registerForNotifications(
                    const std::string &serviceName,
                    const sp<hidl::manager::V1_0::IServiceNotification>
                    &notification) override {
                return hardware::camera::provider::V2_4::ICameraProvider::registerForNotifications(
                        serviceName, notification);
            }
    
            virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
                    const std::string &serviceName) override {
                return hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName);
            }
    
        };
    
        static HardwareServiceInteractionProxy sHardwareServiceInteractionProxy;
    
    /**
         * Initialize the manager and give it a status listener; optionally accepts a service
         * interaction proxy.
         *
         * The default proxy communicates via the hardware service manager; alternate proxies can be
         * used for testing. The lifetime of the proxy must exceed the lifetime of the manager.
         */
        status_t initialize(wp<StatusListener> listener,
                ServiceInteractionProxy *proxy = &sHardwareServiceInteractionProxy);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    用于初始化管理器,并给它设置一个状态监听 (即 CameraService 实例), 选择性地接受一个与服务交互的代理。
    默认的代理通过 Hardware 服务管理器进行通信,在创建 HardwareServiceInteractionProxy 代理时执行了hardware:📷:provider::V2_4::ICameraProvider::getService(serviceName);也就开启了 ICameraProvider 对象构建过程,实现 cameraServer 与 CameraProvider 之间关联。

    
    const std::string kLegacyProviderName("legacy/0");
    
    status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
            ServiceInteractionProxy* proxy) {
        std::lock_guard<std::mutex> lock(mInterfaceMutex);
        if (proxy == nullptr) {
            ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
            return BAD_VALUE;
        }
        mListener = listener;
        mServiceProxy = proxy;
    
        // Registering will trigger notifications for all already-known providers
        bool success = mServiceProxy->registerForNotifications(
            /* instance name, empty means no filter */ "",
            this);
        if (!success) {
            ALOGE("%s: Unable to register with hardware service manager for notifications "
                    "about camera providers", __FUNCTION__);
            return INVALID_OPERATION;
        }
    
        // See if there's a passthrough HAL, but let's not complain if there's not
        addProviderLocked(kLegacyProviderName, /*expected*/ false);
    
        return OK;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    上面是CameraProviderManager的初始化过程,CameraProviderManager就是管理camera Service与camera provider之间通信的工程管理类,两个参数,其中第二个参数就是远程代理类,这个参数已经是默认赋值。

    status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
        //> 检查已知的 Provider 中是否已有名为 legacy/0 的。
        for (const auto& providerInfo : mProviders) {
            if (providerInfo->mProviderName == newProvider) {
                ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
                        newProvider.c_str());
                return ALREADY_EXISTS;
            }
        }
    
        //> 根据 legacy/0 从服务代理处获取 CameraProvider 接口,getService("legacy/0") 触发CameraProvider的响应接口
        //> 由上一篇《谁在调用 v4l2_camera_HAL 摄像头驱动》 中,我们知道该接口是CameraProvider构建函数,返回ICameraProvider对象。
        sp<provider::V2_4::ICameraProvider> interface;
        interface = mServiceProxy->getService(newProvider);
    
        if (interface == nullptr) {
            if (expected) {
                ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
                        newProvider.c_str());
                return BAD_VALUE;
            } else {
                return OK;
            }
        }
    
        //> 通过 ProviderInfo 来保存当前 Provider 相关信息。
        sp<ProviderInfo> providerInfo =
                new ProviderInfo(newProvider, interface, this);
        status_t res = providerInfo->initialize();
        if (res != OK) {
            return res;
        }
    
        mProviders.push_back(providerInfo);
    
        return OK;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    这个函数主要作用是将找到的这个 Provider 通过 ProviderInfo 记录下来并初始化,并再次执行通过接口代理 执行 getService(),这儿就实现了camera service与camera provider的桥接了;

    CameraProviderManager中提供了一个ProviderInfo来保存Camera provider信息,方便管理camera service调用 camera provider,下面分析一下ProviderInfo是怎么样的?源码路径在 CameraProviderManager.h 文件中,是 CameraProviderManager 类的子类内容;

    struct ProviderInfo :
                virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,
                virtual public hardware::hidl_death_recipient
        {
            const std::string mProviderName;
            const sp<hardware::camera::provider::V2_4::ICameraProvider> mInterface;
            const metadata_vendor_id_t mProviderTagid;
    
            //> 构建函数中关联服务名称、ICameraProvider 和 CameraProviderManager 之间对应关系
            ProviderInfo(const std::string &providerName,
                    sp<hardware::camera::provider::V2_4::ICameraProvider>& interface,
                    CameraProviderManager *manager);
            ~ProviderInfo();
    
            status_t initialize();
    
            const std::string& getType() const;
    
            status_t addDevice(const std::string& name,
                    hardware::camera::common::V1_0::CameraDeviceStatus initialStatus =
                    hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT,
                    /*out*/ std::string *parsedId = nullptr);
    
            status_t dump(int fd, const Vector<String16>& args) const;
    
            // ICameraProviderCallbacks interface - these lock the parent mInterfaceMutex
            virtual hardware::Return<void> cameraDeviceStatusChange(
                    const hardware::hidl_string& cameraDeviceName,
                    hardware::camera::common::V1_0::CameraDeviceStatus newStatus) override;
            virtual hardware::Return<void> torchModeStatusChange(
                    const hardware::hidl_string& cameraDeviceName,
                    hardware::camera::common::V1_0::TorchModeStatus newStatus) override;
    
            // hidl_death_recipient interface - this locks the parent mInterfaceMutex
            virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who) override;
    
            // Basic device information, common to all camera devices
            struct DeviceInfo {
                const std::string mName;  // Full instance name
                const std::string mId;    // ID section of full name
                const hardware::hidl_version mVersion;
                const metadata_vendor_id_t mProviderTagid;
    
                const hardware::camera::common::V1_0::CameraResourceCost mResourceCost;
    
                hardware::camera::common::V1_0::CameraDeviceStatus mStatus;
    
                bool hasFlashUnit() const { return mHasFlashUnit; }
                virtual status_t setTorchMode(bool enabled) = 0;
                virtual status_t getCameraInfo(hardware::CameraInfo *info) const = 0;
                virtual bool isAPI1Compatible() const = 0;
                virtual status_t getCameraCharacteristics(CameraMetadata *characteristics) const {
                    (void) characteristics;
                    return INVALID_OPERATION;
                }
    
                DeviceInfo(const std::string& name, const metadata_vendor_id_t tagId,
                        const std::string &id, const hardware::hidl_version& version,
                        const hardware::camera::common::V1_0::CameraResourceCost& resourceCost) :
                        mName(name), mId(id), mVersion(version), mProviderTagid(tagId),
                        mResourceCost(resourceCost),
                        mStatus(hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT),
                        mHasFlashUnit(false) {}
                virtual ~DeviceInfo();
            protected:
                bool mHasFlashUnit;
    
                template<class InterfaceT>
                static status_t setTorchMode(InterfaceT& interface, bool enabled);
            };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    ProviderInfo继承了 hardware:📷:provider::V2_4::ICameraProviderCallback 与 hardware::hidl_death_recipient;
    ICameraProviderCallback 是 cameraProvider的 回调接口,hardware::hidl_death_recipient 是hal层的死亡回调接口,方便在底层死亡的时候通知上层。
    cameraDeviceStatusChange 与 torchModeStatusChange 都是 ICameraProviderCallback 的回调函数,当camera provider发生变化的时候需要通知上层这些变化。

    status_t CameraProviderManager::ProviderInfo::initialize() {
        status_t res = parseProviderName(mProviderName, &mType, &mId);
        if (res != OK) {
            ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
            return BAD_VALUE;
        }
        ALOGI("Connecting to new camera provider: %s, isRemote? %d",
                mProviderName.c_str(), mInterface->isRemote());
        hardware::Return<Status> status = mInterface->setCallback(this);
        if (!status.isOk()) {
            ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
                    __FUNCTION__, mProviderName.c_str(), status.description().c_str());
            return DEAD_OBJECT;
        }
        if (status != Status::OK) {
            ALOGE("%s: Unable to register callbacks with camera provider '%s'",
                    __FUNCTION__, mProviderName.c_str());
            return mapToStatusT(status);
        }
    
        hardware::Return<bool> linked = mInterface->linkToDeath(this, /*cookie*/ mId);
        if (!linked.isOk()) {
            ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
                    __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
            return DEAD_OBJECT;
        } else if (!linked) {
            ALOGW("%s: Unable to link to provider '%s' death notifications",
                    __FUNCTION__, mProviderName.c_str());
        }
    
        // Get initial list of camera devices, if any
        std::vector<std::string> devices;
        hardware::Return<void> ret = mInterface->getCameraIdList([&status, &devices](
                Status idStatus,
                const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
            status = idStatus;
            if (status == Status::OK) {
                for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
                    devices.push_back(cameraDeviceNames[i]);
                }
            } });
        if (!ret.isOk()) {
            ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
                    __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
            return DEAD_OBJECT;
        }
        if (status != Status::OK) {
            ALOGE("%s: Unable to query for camera devices from provider '%s'",
                    __FUNCTION__, mProviderName.c_str());
            return mapToStatusT(status);
        }
    
        sp<StatusListener> listener = mManager->getStatusListener();
        for (auto& device : devices) {
            std::string id;
            status_t res = addDevice(device,
                    hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
            if (res != OK) {
                ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
                        __FUNCTION__, device.c_str(), strerror(-res), res);
                continue;
            }
        }
    
        for (auto& device : mDevices) {
            mUniqueCameraIds.insert(device->mId);
            if (device->isAPI1Compatible()) {
                mUniqueAPI1CompatibleCameraIds.insert(device->mId);
            }
        }
        mUniqueDeviceCount = mUniqueCameraIds.size();
    
        ALOGI("Camera provider %s ready with %zu camera devices",
                mProviderName.c_str(), mDevices.size());
    
        return OK;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    initialize 函数的主要作用是初始化cameraProvider,并且IPC调用到cameraProvider 获取camera device信息,然后调用 addDevice接口将获取的camera device保存在cameraService中,防止多次跨进程调用。

    至此、回答第一个问题 CameraService 如何与 CameraProvider 通讯,是通过 CameraProviderManager管理 cameraService 与 cameraProvider 间通信;

    因第二个问题涉及到 Binder IPC 通讯相关内容较多、所以另外开启一篇续《详解 CameraService 都做了什么》之 CameraService 与 cameraclient 通讯 篇专门梳理分析此部分内容。

  • 相关阅读:
    SpringBoot日志文件
    OpenCV实战(31)——基于级联Haar特征的目标检测
    微信小程序注册指引
    腾讯大牛手撕SpringBoot,Cloud,Nginx与Docker,你凭什么还搞不懂啊!
    #循循渐进学51单片机#函数进阶与按键#not.7
    1.3 常规信息系统集成技术
    u盘无法复制过大文件怎么解决?揭秘!
    设计模式—— 工厂方法模式(Factory Pattern)+ Spring相关源码
    R语言—数据框
    跟我学C++中级篇——Pimpl中的unique_ptr
  • 原文地址:https://blog.csdn.net/weixin_38387929/article/details/126303343