美文网首页
[Android Camera精讲]CameraServer启动

[Android Camera精讲]CameraServer启动

作者: ZZH的Android | 来源:发表于2024-01-07 23:24 被阅读0次

    1、环境

    代码基于Android 13,代码分支为aosp android-13.0.0_r44;调试机型为Google Pixel5。

    2、Camera架构

    这张图是我另一篇文章里的,直接拿过来。
    cameraserver进程是承上启下的,对上是Camera Api,对应Camera App进程,
    对下是CameraProvider进程,也就是Camera HAL。

    为什么要讲启动流程呢,因为启动过程中初始化了很多东西,如果这部分略过不看的话,
    在看Camera打开、预览等流程时就会很懵,有很多东西不知道哪里来的,其实就是开
    机时,进程启动过程初始化的,所以这个很重要。

    3、启动流程

    整体流程图如下,可以看到,主要都在CameraProviderManager.cpp和对应的ProviderInfo文件中。

    3.1 入口

    代码目录

    frameworks/av/camera/cameraserver/
    

    这里包含如下四个文件

    其中Android.bp里面有如下内容

    init_rc: ["cameraserver.rc"],
    

    这样的话系统在编译时会将cameraserver.rc放到system/etc/init目录下,
    init进程启动的时候会解析这个目录下的所有.rc文件。

    编译完成之后的out目录

    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
    

    上面的语法规则说明,将会以二进制/system/bin/cameraserver启动一个名称为cameraserver的服务

    cameraserver进程

    Android.bp里有如下内容

    cc_binary {
        name: "cameraserver",
        srcs: ["main_cameraserver.cpp"],
        
    // 这里说明二进制cameraserver的入口函数在
    // main_cameraserver.cpp文件的main函数里
    #define LOG_TAG "cameraserver"
    //#define LOG_NDEBUG 0
    
    #include "CameraService.h"
    #include <hidl/HidlTransportSupport.h>
    
    using namespace android;
    
    int main(int argc __unused, char** argv __unused)
    {
        signal(SIGPIPE, SIG_IGN);
    
        // Set 5 threads for HIDL calls. Now cameraserver will serve HIDL calls in
        // addition to consuming them from the Camera HAL as well.
        hardware::configureRpcThreadpool(5, /*willjoin*/ false);
    
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());
        CameraService::instantiate();
        ALOGI("ServiceManager: %p done instantiate", sm.get());
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
    }
    
    // 这里处了binder相关的,剩下的就是下面一行了
    CameraService::instantiate();
    // 下面我们就从CameraService继续分析。
    

    3.2 CameraService

    从上图可以看出,CameraService类中并没有定义instantiate()函数,所以它最终调用的是父类
    BinderService的instantiate()函数。这个类的代码比较少,我们全贴出来看下。可以看到
    instantiate()里面直接调用了publish()方法。

    // frameworks/native/libs/binder/include/binder/BinderService.h
    namespace android {
    
    // 模板类,对于CameraServer来说,
    // 这里的SERVICE是CameraService,
    // 因为CameraService继承的是
    // BinderService<CameraService>
    template<typename SERVICE>
    class BinderService
    {
    public:
        // instantiate() 直接调用的这个方法,
        // 两个参数都用默认值。
        static status_t publish(bool allowIsolated = false,
                int dumpFlags =IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
            sp<IServiceManager> sm(defaultServiceManager());
            // 这里SERVICE是CameraService,
            // 所以这里调用的CameraService
            // 的静态方法getServiceName()
            // 并且创建了一个CameraService对象。
            // 最后使用ServiceManager的
            // addService方法进行了binder服务注册
            return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated, dumpFlags);
        }
    
        // 这里是带显示参数的使用
        static void publishAndJoinThreadPool(
                bool allowIsolated = false,
                int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
            publish(allowIsolated, dumpFlags);
            joinThreadPool();
        }
    
        // 直接调用了publish()方法
        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();
        }
    };
    
    } // namespace android
    

    下面再看下上面提到的CameraService中的方法

    // frameworks/av/services/camera/libcameraservice/CameraService.h
    class CameraService :
        // 继承BinderService指定泛型类型为CameraService
        public BinderService<CameraService>,
        public virtual ::android::hardware::BnCameraService,
        public virtual IBinder::DeathRecipient,
        public virtual CameraProviderManager::StatusListener
    {
        ...
    public:
        ...
        // 注册的binder服务名称为“media.camera”
        static char const* getServiceName() { 
          return "media.camera"; 
        }
        ...
    }
    

    接下来我们看下上面提到的ServiceManager的addService方法
    这里有一个神奇的地方,所以拿出来提一下,讲清楚。

    // frameworks/native/libs/binder/include/binder/IServiceManager.h
    // 第一个参数是字符串media.camera
    // 第二个参数是new的CameraService对象
    // 这里相当于const sp<IBinder>& service = new CameraService()
    virtual status_t addService(const String16& name, const sp<IBinder>& service,
                                bool allowIsolated = false,
                                int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0;
    

    我们看下class sp的实现

    // system/core/libutils/include/utils/StrongPointer.h
    // 下面的T就是CameraService*
    template <typename T>
    sp<T>& sp<T>::operator=(T* other) {
        T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
        if (other) {
            check_not_on_stack(other);
            // 可以看到如果指针不为空的话
            // 会调用自身的incStrong方法
            other->incStrong(this);
        }
        if (oldPtr) oldPtr->decStrong(this);
        if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
        m_ptr = other;
        return *this;
    }
    

    但是我们发现CameraService里并没有incStrong方法,那么一定
    是它的父类的方法,由此引出了一个非常重要的类RefBase。
    RefBase是Android中所有C++对象的基类。

    // system/core/libutils/RefBase.cpp
    RefBase::RefBase()
        // 这里的this是CameraService*
        : mRefs(new weakref_impl(this))
    {
    }
    
    explicit weakref_impl(RefBase* base)
        : mStrong(INITIAL_STRONG_VALUE)
        , mWeak(0)
        // 这里的mBase其实还是CameraService*
        , mBase(base)
        , mFlags(OBJECT_LIFETIME_STRONG)
    {
    }
    
    void RefBase::incStrong(const void* id) const
    {
        weakref_impl* const refs = mRefs;
        refs->incWeak(id);
    
        refs->addStrongRef(id);
        const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);
        ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
    #if PRINT_REFS
        ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
    #endif
        if (c != INITIAL_STRONG_VALUE)  {
            return;
        }
    
        int32_t old __unused = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed);
        // A decStrong() must still happen after us.
        ALOG_ASSERT(old > INITIAL_STRONG_VALUE, "0x%x too small", old);
        // 如上可知refs->mBase是CameraService*,
        // 所以这里会调用CameraService的onFirstRef()方法。
        refs->mBase->onFirstRef();
    }
    

    可以看到,基类RefBase中有一个空实现,当子类未重新该方法时,将调用基类的这个空实现的方法。

    void RefBase::onFirstRef()
    {
    }
    

    所以,有上面的分析得出一个结论:被sp引用的对象在创建后会执行自身的onFirstRef函数。所以在addService的时候,会执行CameraService的onFirstRef函数,而CameraService是重写了onFirstRef函数的,所以我们下面开始接着分析其构造函数和onFirstRef函数。

    构造函数比较简单,进行了一些初始化操作

    CameraService::CameraService() :
            mEventLog(DEFAULT_EVENT_LOG_LENGTH),
            mNumberOfCameras(0),
            mNumberOfCamerasWithoutSystemCamera(0),
            mSoundRef(0), mInitialized(false),
            mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE) {
        ALOGI("CameraService started (pid=%d)", getpid());
        mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
        mMemFd = memfd_create(sFileName, MFD_ALLOW_SEALING);
        if (mMemFd == -1) {
            ALOGE("%s: Error while creating the file: %s", __FUNCTION__, sFileName);
        }
    }
    

    这里面的核心是enumerateProviders

    void CameraService::onFirstRef()
    {
    
        ALOGI("CameraService process starting");
    
        BnCameraService::onFirstRef();
    
        // Update battery life tracking if service is restarting
        BatteryNotifier& notifier(BatteryNotifier::getInstance());
        notifier.noteResetCamera();
        notifier.noteResetFlashlight();
    
        status_t res = INVALID_OPERATION;
    
        // 核心实现,从命令可以看出主要是枚举系统的CameraProviders,
        // 也就是Camera HAL所在进程,CameraProvider可能有多个
        res = enumerateProviders();
        if (res == OK) {
            // 上面执行ok后,mInitialized赋值为true
            mInitialized = true;
        }
    
        mUidPolicy = new UidPolicy(this);
        mUidPolicy->registerSelf();
        mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
        mSensorPrivacyPolicy->registerSelf();
        mInjectionStatusListener = new InjectionStatusListener(this);
        mAppOps.setCameraAudioRestriction(mAudioRestriction);
        sp<HidlCameraService> hcs = HidlCameraService::getInstance(this);
        if (hcs->registerAsService() != android::OK) {
            ALOGE("%s: Failed to register default android.frameworks.cameraservice.service@1.0",
                  __FUNCTION__);
        }
    
        // This needs to be last call in this function, so that it's as close to
        // ServiceManager::addService() as possible.
        CameraServiceProxyWrapper::pingCameraServiceProxy();
        ALOGI("CameraService pinged cameraservice proxy");
    }
    

    3.2.1 enumerateProviders

    下面重点看下enumerateProviders()函数的实现

    status_t CameraService::enumerateProviders() {
        status_t res;
    
        std::vector<std::string> deviceIds;
        std::unordered_map<std::string, std::set<std::string>> unavailPhysicalIds;
        {
            Mutex::Autolock l(mServiceLock);
    
            // 创建CameraProvider对象,并且调用初始化方法initialize
            // 这里是实现的核心,在initialize方法里会遍历系统中配置
            // 的CameraProvider,我们先重点分析这部分
            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);
                    logServiceError(String8::format("Unable to initialize camera provider manager"),
                    ERROR_DISCONNECTED);
                    return res;
                }
            }
        ...
        return OK;
    }
    

    CameraProviderManager没有显示构造函数,所以直接看其initialize方法

    // frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
    // 这里的第二个参数有默认值,在CameraProviderManager.h当中。
    status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
            HidlServiceInteractionProxy* hidlProxy) {
        std::lock_guard<std::mutex> lock(mInterfaceMutex);
        if (hidlProxy == nullptr) {
            ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
            return BAD_VALUE;
        }
        mListener = listener;
        mDeviceState = 0;
        // 遍历HIDL实现的CameraProviders
        auto res = tryToInitAndAddHidlProvidersLocked(hidlProxy);
        // 这里容易让人误解,以为如果hidl CameraProviders初始化失败,
        // 将直接返回,不再遍历aidl的CameraProviders。
        // 实际并不是,只要registerForNotifications返回OK就可以。
        if (res != OK) {
            // Logging done in called function;
            return res;
        }
        // 遍历AIDL实现的CameraProviders
        res = tryToAddAidlProvidersLocked();
    
        IPCThreadState::self()->flushCommands();
    
        return res;
    }
    
    // 遍历HIDL和AIDL CameraProviders将在下面分别详解
    

    先记住下面这个类图,下面会用到。

    3.2.2 tryToInitAndAddHidlProvidersLocked

    先看tryToInitAndAddHidlProvidersLocked的实现

    status_t CameraProviderManager::tryToInitAndAddHidlProvidersLocked(
            HidlServiceInteractionProxy *hidlProxy) {
        mHidlServiceProxy = hidlProxy;
        // Registering will trigger notifications for all already-known providers
        // 这里是注册回调,当binder服务成功注册后,会回调onServiceRegistration方法 
        // 我们可以看到,这里的第二个参数是this,因为CameraProviderManager是继承了 
        // IServiceNotification的,也实现了onServiceRegistration方法
        bool success = mHidlServiceProxy->registerForNotifications(
            /* instance name, empty means no filter */ "",
            this);
        // 在Pixel5 Android13设备上,这里的success为true
        if (!success) {
            ALOGE("%s: Unable to register with hardware service manager for notifications "
                    "about camera providers", __FUNCTION__);
            return INVALID_OPERATION;
        }
        
        // 这里是核心,mHidlServiceProxy->listServices()是获取到所有HIDL实现
        // 的CameraProvider的服务名称的集合,然后通过addHidlProviderLocked进行保存
        // 在Pixel5 Android13设备上,这里的listServices为空,表示没有hidl类型的CameraProvider
        for (const auto& instance : mHidlServiceProxy->listServices()) {
            this->addHidlProviderLocked(instance);
        }
        
        // 即使上面没有找到HIDL方式实现的CameraProvider,但是这里还是会返回OK,
        // 以便进行下一步遍历AIDL方式实现的CameraProviders
        return OK;
    }
    
    // Hidl CameraProvider的流程先将这么多,其流程跟Aidl CameraProvider的流程基本一致,
    // 下面会针对Aidl CameraProvider流程进行详细讲解。
    

    3.2.3 tryToAddAidlProvidersLocked

    这部分主要查找使用AIDL方式实现的CameraProvider

    status_t CameraProviderManager::tryToAddAidlProvidersLocked() {
        // 这里的值是 android.hardware.camera.provider.ICameraProvider
        // 其赋值的地方在ICameraProvider.cpp中,注意这个文件是编译后生成在out目录下的。
        const char * aidlHalServiceDescriptor =
                aidl::android::hardware::camera::provider::ICameraProvider::descriptor;
        auto sm = defaultServiceManager();
        // 这里返回的是所有AIDL的CameraProvider服务的instance的名称集合。
        // 在pixel5上只有一个AIDL实现的CameraProvdier,其instance的名称是internal/0
        // 可以在如下文件找到:
        // hardware/google/camera/common/hal/aidl_service/aidl_service.cc
        // 其中定义了instance的名称,如下:
        // const std::string kProviderInstance = "/internal/0";
        auto aidlProviders = sm->getDeclaredInstances(
                String16(aidlHalServiceDescriptor));
        for (const auto &aidlInstance : aidlProviders) {
            // 在pixel5上这个循环执行一次,这里的aidlInstance为"/internal/0"
            // aidlServiceName是CameraProvider对应的binder服务名称
            // 也在aidl_service.cc中有定义,如下:
            // std::string instance =
            // std::string() + AidlCameraProvider::descriptor + kProviderInstance;
            // 其中AidlCameraProvider::descriptor是android.hardware.camera.provider.ICameraProvider
            // 所以服务名称为:
            // android.hardware.camera.provider.ICameraProvider/internal/0
            std::string aidlServiceName =
                    getFullAidlProviderName(std::string(String8(aidlInstance).c_str()));
            // 上面的操作其实就是拿到了CameraProvider进程的服务名称
            // 下面就要开始使用了
            // 这里是注册回调,当binder服务成功注册后,会回调onServiceRegistration方法
            // 我们可以看到,这里的第二个参数是this,因为CameraProviderManager是继承了
            // IServiceNotification的,也实现了onServiceRegistration方法,
            // 后面会看到其用法。
            auto res = sm->registerForNotifications(String16(aidlServiceName.c_str()), this);
            // 如果注册失败,则直接返回,可见这个函数的重要性。
            if (res != OK) {
                ALOGE("%s Unable to register for notifications with AIDL service manager",
                        __FUNCTION__);
                return res;
            }
            // 下面我们分析这个函数,注意这里的aidlServiceName
            // 是android.hardware.camera.provider.ICameraProvider/internal/0
            addAidlProviderLocked(aidlServiceName);
        }
        return OK;
    }
    
    status_t CameraProviderManager::addAidlProviderLocked(const std::string& newProvider) {
        // Several camera provider instances can be temporarily present.
        // Defer initialization of a new instance until the older instance is properly removed.
        // mProviderInstanceId初始值为0
        // 这里考虑到多个CameraProvider的场景,所以对每个CameraProvider添加了一个id
        // android.hardware.camera.provider.ICameraProvider/internal/0-0
        auto providerInstance = newProvider + "-" + std::to_string(mProviderInstanceId);
        bool providerPresent = false;
        // mAidlProviderWithBinders是一个string集合,用来保存provider实例
        bool preexisting =
                (mAidlProviderWithBinders.find(newProvider) != mAidlProviderWithBinders.end());
    
        // We need to use the extracted provider name here since 'newProvider' has
        // the fully qualified name of the provider service in case of AIDL. We want
        // just instance name.
        using aidl::android::hardware::camera::provider::ICameraProvider;
        // 这里拿到的是internal/0
        std::string extractedProviderName =
                newProvider.substr(std::string(ICameraProvider::descriptor).size() + 1);
        // mProviders是ProviderInfo的集合,初始为空
        // 第一次执行时mProviders肯定为空,所以不会执行下面的代码。
        for (const auto& providerInfo : mProviders) {
            // 如果mProviders中已经有了要要添加的provider
            if (providerInfo->mProviderName == extractedProviderName) {
                ALOGW("%s: Camera provider HAL with name '%s' already registered",
                        __FUNCTION__, newProvider.c_str());
                // Do not add new instances for lazy HAL external provider or aidl
                // binders previously seen.
                // 如果已经存在或者是lazy HAL external provider,则返回ALREADY_EXISTS
                if (preexisting || providerInfo->isExternalLazyHAL()) {
                    return ALREADY_EXISTS;
                } else {
                    // 这里想到的一个场景是,下面的tryToInitializeAidlProviderLocked
                    // 执行失败时preexisting就是false
                    ALOGW("%s: The new provider instance will get initialized immediately after the"
                            " currently present instance is removed!", __FUNCTION__);
                    providerPresent = true;
                    break;
                }
            }
        }
    
        // 构造AidlProviderInfo对象
        sp<AidlProviderInfo> providerInfo =
                new AidlProviderInfo(extractedProviderName, providerInstance, this);
        // 第一次添加provider时providerPresent肯定是false
        if (!providerPresent) {
            status_t res = tryToInitializeAidlProviderLocked(newProvider, providerInfo);
            if (res != OK) {
                return res;
            }
            // 上述初始化成功后加入mAidlProviderWithBinders集合
            mAidlProviderWithBinders.emplace(newProvider);
        }
    
        // 将providerInfo添加到mProviders
        mProviders.push_back(providerInfo);
        // mProviderInstanceId递增,下一个provider的instance id
        mProviderInstanceId++;
    
        return OK;
    } 
    

    下面看下tryToInitializeAidlProviderLocked的实现。

    status_t CameraProviderManager::tryToInitializeAidlProviderLocked(
            const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
        using aidl::android::hardware::camera::provider::ICameraProvider;
        // 获取CameraProvider服务的binder代理对象
        std::shared_ptr<ICameraProvider> interface =
                ICameraProvider::fromBinder(ndk::SpAIBinder(
                        AServiceManager_getService(providerName.c_str())));
    
        // 如果为空,说明无法获取CameraProvider服务,可能这时还未启动,也可能发生异常。
        // 在Pixel5上,执行到这里时为空,因为此时CameraProvider服务还未启动完成。
        if (interface == nullptr) {
            ALOGW("%s: AIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
                    providerName.c_str());
            return BAD_VALUE;
        }
    
    // 所以下面的代码第一次到这里时未执行到,但是我们上面说过,当CameraProvider服务注册成功后,
    // 会回调onServiceRegistration方法,在这个回调中会调用addAidlProviderLocked,然后
    // 还会走到这里来,所以第二次的时候才会真正执行下面的代码。
        AidlProviderInfo *aidlProviderInfo = static_cast<AidlProviderInfo *>(providerInfo.get());
        // 主要调用了initializeAidlProvider方法
        // mDeviceState初始值为0
        return aidlProviderInfo->initializeAidlProvider(interface, mDeviceState);
    }
    

    我们发现,当onServiceRegistration函数回调时,还会调用addAidlProviderLocked方法

    void CameraProviderManager::onServiceRegistration(const String16 &name, const sp<IBinder>&) {
        ALOGE("onServiceRegistration name:%s", String8(name).c_str());
        status_t res = OK;
        std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
        {
            std::lock_guard<std::mutex> lock(mInterfaceMutex);
    
            res = addAidlProviderLocked(String8(name).c_str());
        }
    
        sp<StatusListener> listener = getStatusListener();
        if (nullptr != listener.get() && res == OK) {
            listener->onNewProviderRegistered();
        }
    
        IPCThreadState::self()->flushCommands();
    }
    

    下面看下initializeAidlProvider

    // frameworks/av/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
    status_t AidlProviderInfo::initializeAidlProvider(
            std::shared_ptr<ICameraProvider>& interface, int64_t currentDeviceState) {
        // 这里的mProviderName是上面构造AidlProviderInfo的时候赋值的
        // 其值为:internal/0
        // 这里对mProviderName的名称进行了校验,看是否符合命名规则
        // 解析后mType=internal mId=0,也就是对mProviderName进行了拆分
        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(), interface->isRemote());
    
        // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
        // before setCallback returns
        mCallbacks =
                ndk::SharedRefBase::make<AidlProviderCallbacks>(this);
        // 这里设置一个callback到CameraProvider,回调的内容
        // 可以看下AidlProviderCallbacks的定义
        ndk::ScopedAStatus status =
                interface->setCallback(mCallbacks);
        if (!status.isOk()) {
            ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
                    __FUNCTION__, mProviderName.c_str(), status.getMessage());
            return mapToStatusT(status);
        }
    
        mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(binderDied));
        // CameraProvider服务死亡回调通知
        auto link = AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(), this);
        if (link != STATUS_OK) {
            ALOGW("%s: Unable to link to provider '%s' death notifications",
                    __FUNCTION__, mProviderName.c_str());
            return DEAD_OBJECT;
        }
    
        if (!kEnableLazyHal) {
            // Save HAL reference indefinitely
            mSavedInterface = interface;
        } else {
            mActiveInterface = interface;
        }
    
        ALOGV("%s: Setting device state for %s: 0x%" PRIx64,
                __FUNCTION__, mProviderName.c_str(), mDeviceState);
        // 这里调用的是interface->notifyDeviceStateChange(mDeviceState);
        // 通知CameraHal currentDeviceState状态
        notifyDeviceStateChange(currentDeviceState);
    
        res = setUpVendorTags();
        if (res != OK) {
            ALOGE("%s: Unable to set up vendor tags from provider '%s'",
                    __FUNCTION__, mProviderName.c_str());
            return res;
         }
    
        // Get initial list of camera devices, if any
        std::vector<std::string> devices;
        std::vector<std::string> retDevices;
        // 这里返回的是CameraDevice相关的信息,每个Camera id对应一个CameraDevice
        status = interface->getCameraIdList(&retDevices);
        if (!status.isOk()) {
            ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
                    __FUNCTION__, mProviderName.c_str(), status.getMessage());
            return mapToStatusT(status);
        }
    
        // 在pixel5上有两个摄像头,后摄和前摄,cameraid分别为0和1
        // 所以这里retDevices有两个,其值分别为
        // device@1.1/internal/0
        // device@1.1/internal/1
        // 其赋值的地方在
        // hardware/google/camera/common/hal/aidl_service/aidl_camera_provider.cc
        /*
          for (uint32_t i = 0; i < camera_ids_ret->size(); i++) {
            // camera ID is in the form of "device@<major>.<minor>/<type>/<id>"
            (*camera_ids_ret)[i] =
            "device@" + device::implementation::AidlCameraDevice::kDeviceVersion +
            "/" + kProviderName + "/" + std::to_string(camera_ids[i]);
          }
        */
        for (auto& name : retDevices) {
            uint16_t major, minor;
            std::string type, id;
            // 解析校验,其值为:
            // major:1, minor:1,type:internal,id:0
            // major:1, minor:1,type:internal,id:1
            status_t res = parseDeviceName(name, &major, &minor, &type, &id);
            if (res != OK) {
                ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
                return res;
            } else {
                // 保存信息
                devices.push_back(name);
                mProviderPublicCameraIds.push_back(id);
            }
        }
    
        // Get list of concurrent streaming camera device combinations
        // 这里查询和返回可以同时使用的cameradevice信息,
        // 笔者理解是可同时使用的camera集合,比如同时打开前置和后置摄像头
        res = getConcurrentCameraIdsInternalLocked(interface);
        if (res != OK) {
            return res;
        }
    
        mSetTorchModeSupported = true;
    
        mIsRemote = interface->isRemote();
    
        // 这个下面展开分析
        initializeProviderInfoCommon(devices);
        return OK;
    }
    

    我们继续分析initializeProviderInfoCommon

    void CameraProviderManager::ProviderInfo::initializeProviderInfoCommon(
            const std::vector<std::string> &devices) {
        for (auto& device : devices) {
            std::string id;
            // 这里最重要的是addDevice函数,我们下面展开讲
            status_t res = addDevice(device, CameraDeviceStatus::PRESENT, &id);
            if (res != OK) {
                ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
                        __FUNCTION__, device.c_str(), strerror(-res), res);
                continue;
            }
        }
    
        ALOGI("Camera provider %s ready with %zu camera devices",
                mProviderName.c_str(), mDevices.size());
    
        // 处理掉缓存的回调
        // Process cached status callbacks
        {
            std::lock_guard<std::mutex> lock(mInitLock);
    
            for (auto& statusInfo : mCachedStatus) {
                std::string id, physicalId;
                if (statusInfo.isPhysicalCameraStatus) {
                    physicalCameraDeviceStatusChangeLocked(&id, &physicalId,
                        statusInfo.cameraId, statusInfo.physicalCameraId, statusInfo.status);
                } else {
                    cameraDeviceStatusChangeLocked(&id, statusInfo.cameraId, statusInfo.status);
                }
            }
            mCachedStatus.clear();
    
            // 执行到这里AidlProviderInfo初始化成功
            mInitialized = true;
        }
    }
    

    下面我们看下addDevice的实现

    status_t CameraProviderManager::ProviderInfo::addDevice(
            const std::string& name, CameraDeviceStatus initialStatus,
            /*out*/ std::string* parsedId) {
    
        ALOGI("Enumerating new camera device: %s", name.c_str());
    
        uint16_t major, minor;
        std::string type, id;
        IPCTransport transport = getIPCTransport();
        
        // 这个函数之前已经执行过一次,这里还需要使用,所以又调用一次
        // major:1, minor:1,type:internal,id:0
        // major:1, minor:1,type:internal,id:1 
        status_t res = parseDeviceName(name, &major, &minor, &type, &id);
        if (res != OK) {
            return res;
        }
    
        // 这里的mType是parseProviderName函数执行时解析出来的是:internal
        // type是parseDeviceName的值,目前也是internal
        // 如果两者的type不一致的话这里直接返回。
        if (type != mType) {
            ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
                    type.c_str(), mType.c_str());
            return BAD_VALUE;
        }
        // 检查目前从cameradevice是否已经被使用
        if (mManager->isValidDeviceLocked(id, major, transport)) {
            ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
                    name.c_str(), id.c_str(), major);
            return BAD_VALUE;
        }
    
        std::unique_ptr<DeviceInfo> deviceInfo;
        switch (transport) {
            case IPCTransport::HIDL:
                switch (major) {
                    case 3:
                        break;
                    default:
                        ALOGE("%s: Device %s: Unsupported HIDL device HAL major version %d:",
                              __FUNCTION__,  name.c_str(), major);
                        return BAD_VALUE;
                }
                break;
            // 这里我们将的是Aidl CameraProvider,所以肯定走这里。
            // 目前大版本号是1,如果不是的话直接返回
            case IPCTransport::AIDL:
                if (major != 1) {
                    ALOGE("%s: Device %s: Unsupported AIDL device HAL major version %d:", __FUNCTION__,
                            name.c_str(), major);
                    return BAD_VALUE;
                }
                break;
            default:
                ALOGE("%s Invalid transport %d", __FUNCTION__, transport);
                return BAD_VALUE;
        }
    
        // 创建DeviceInfo对象,这个函数下面展开讲
        deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor);
        if (deviceInfo == nullptr) return BAD_VALUE;
        // 目前DeviceState为0
        deviceInfo->notifyDeviceStateChange(getDeviceState());
        // mStatus=CameraDeviceStatus::PRESENT
        deviceInfo->mStatus = initialStatus;
        bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
        // 保存到mDevices中
        mDevices.push_back(std::move(deviceInfo));
    
        mUniqueCameraIds.insert(id);
        if (isAPI1Compatible) {
            // addDevice can be called more than once for the same camera id if HAL
            // supports openLegacy.
            if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
                    id) == mUniqueAPI1CompatibleCameraIds.end()) {
                mUniqueAPI1CompatibleCameraIds.push_back(id);
            }
        }
    
        if (parsedId != nullptr) {
            *parsedId = id;
        }
        return OK;
    }
    

    我们具体看下initializeDeviceInfo

    std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
        AidlProviderInfo::initializeDeviceInfo(
            const std::string &name, const metadata_vendor_id_t tagId,
            const std::string &id, uint16_t minorVersion) {
        ::ndk::ScopedAStatus status;
        
        // 这里是获取CameraDevice对象的binder代理camera::device::ICameraDevice
        auto cameraInterface = startDeviceInterface(name);
        if (cameraInterface == nullptr) return nullptr;
    
        camera::common::CameraResourceCost resourceCost;
        // 获取CameraDevice对应的resourceCost,这个值在openCamera时会用到
        // 可以看另一篇open流程的讲解文章
        status = cameraInterface->getResourceCost(&resourceCost);
        if (!status.isOk()) {
            ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
                    name.c_str(), status.getMessage());
            return nullptr;
        }
    
        // 打印出与其有冲突的设备,这个是在Camera hal库中定义的
        for (auto& conflictName : resourceCost.conflictingDevices) {
            uint16_t major, minor;
            std::string type, id;
            status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id);
            if (res != OK) {
                ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());
                return nullptr;
            }
            conflictName = id;
        }
    
        // 创建AidlDeviceInfo3对象返回
        return std::unique_ptr<DeviceInfo3>(
            new AidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
                    this, mProviderPublicCameraIds, cameraInterface));
    }
    

    最后看下DeviceInfo的类图

    相关文章

      网友评论

          本文标题:[Android Camera精讲]CameraServer启动

          本文链接:https://www.haomeiwen.com/subject/wrfgndtx.html