[Android Camera精讲]CameraServer启动流程

1、环境

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

欢迎关注微信公众号"ZZH的Android",关注后点击"交流群"菜单加入交流群。

2、Camera架构

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

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

3、启动流程

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

3.1 入口

代码目录

bash 复制代码
frameworks/av/camera/cameraserver/

这里包含如下四个文件

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

vbnet 复制代码
init_rc: ["cameraserver.rc"],

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

编译完成之后的out目录

cameraserver.rc内容如下:

css 复制代码
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里有如下内容

arduino 复制代码
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()方法。

arduino 复制代码
// 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中的方法

arduino 复制代码
// 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方法 这里有一个神奇的地方,所以拿出来提一下,讲清楚。

arduino 复制代码
// 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的实现

scss 复制代码
// 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++对象的基类。

scss 复制代码
// 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中有一个空实现,当子类未重新该方法时,将调用基类的这个空实现的方法。

javascript 复制代码
void RefBase::onFirstRef()
{
}

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

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

scss 复制代码
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

scss 复制代码
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()函数的实现

c 复制代码
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方法

scss 复制代码
// 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的实现

arduino 复制代码
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

c 复制代码
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的实现。

c 复制代码
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方法

ini 复制代码
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

scss 复制代码
// 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

c 复制代码
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的实现

c 复制代码
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

c 复制代码
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的类图

相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui