[Android Camera精讲]CameraServer启动流程

这篇具有很好参考价值的文章主要介绍了[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打开、预览等流程时就会很懵,有很多东西不知道哪里来的,其实就是开
机时,进程启动过程初始化的,所以这个很重要。

[Android Camera精讲]CameraServer启动流程,Android系统开发,# Android Camera,# Android车载开发,android,framework,camera,cameraserver,cameraservice,cameraprovider,CameraProvider

3、启动流程

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

[Android Camera精讲]CameraServer启动流程,Android系统开发,# Android Camera,# Android车载开发,android,framework,camera,cameraserver,cameraservice,cameraprovider,CameraProvider

3.1 入口

代码目录

frameworks/av/camera/cameraserver/

这里包含如下四个文件

[Android Camera精讲]CameraServer启动流程,Android系统开发,# Android Camera,# Android车载开发,android,framework,camera,cameraserver,cameraservice,cameraprovider,CameraProvider

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

init_rc: ["cameraserver.rc"],

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

编译完成之后的out目录

[Android Camera精讲]CameraServer启动流程,Android系统开发,# Android Camera,# Android车载开发,android,framework,camera,cameraserver,cameraservice,cameraprovider,CameraProvider

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 Camera精讲]CameraServer启动流程,Android系统开发,# Android Camera,# Android车载开发,android,framework,camera,cameraserver,cameraservice,cameraprovider,CameraProvider

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

[Android Camera精讲]CameraServer启动流程,Android系统开发,# Android Camera,# Android车载开发,android,framework,camera,cameraserver,cameraservice,cameraprovider,CameraProvider

从上图可以看出,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将在下面分别详解

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

[Android Camera精讲]CameraServer启动流程,Android系统开发,# Android Camera,# Android车载开发,android,framework,camera,cameraserver,cameraservice,cameraprovider,CameraProvider

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启动流程,Android系统开发,# Android Camera,# Android车载开发,android,framework,camera,cameraserver,cameraservice,cameraprovider,CameraProvider文章来源地址https://www.toymoban.com/news/detail-824928.html

到了这里,关于[Android Camera精讲]CameraServer启动流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android系统启动流程 源码解析

    本文链接:https://blog.csdn.net/feather_wch/article/details/132518105 有道云脑图:https://note.youdao.com/s/GZ9d8vzO 1、整体流程 Boot Room BootLoader idle kthread init init ServiceManager zygote zygote SystemServer app 1、kernel/common/init/main.c 2、andorid.mk-android.bp编译 3、init是用户空间鼻祖 属于C、C++ Framework 1.1 启动源

    2024年02月11日
    浏览(51)
  • Android T 远程动画显示流程其二——系统侧动画启动流程

    接着上篇文章分析 Android T 远程动画显示流程其一 下面,我们以从桌面点击一个应用启动的场景来分析远程动画的流程,窗口添加的流程见Android T WMS窗口相关流程 这里我们从AppTransitionController.handleAppTransitionReady方法开始跟踪代码流程 代码路径:framework/services/core/java/com/and

    2024年03月28日
    浏览(46)
  • Android Camera2-预览、拍照、录像流程

    一、Camera2实现预览、拍照、录像三大基础功能的流程框架图 Camera2关键几个类: CameraManager 管理手机上的所有摄像头设备。管理手机上的所有摄像头设备,它的作用主要是获取摄像头列表和打开(openCamera)指定的摄像头。 它其实是一个系统服务,通过getSystemService(Context.CAM

    2024年02月16日
    浏览(54)
  • 基于Android13的系统启动流程分析(四)之SecondStageMain阶段

    Android13系统启动阶段大致分为FirstStageMain阶段和SecondStageMain,此章主要讲SecondStageMain阶段 (若分析有误敬请指教) 在基于Android13的系统启动流程分析(三)之FirstStageMain阶段已经讲解过android系统启动的基本介绍了,这里不再单独介绍了 我们先看是怎么进入该阶段的,仍然是

    2023年04月24日
    浏览(49)
  • Android 12系统源码_窗口管理(一)WindowManagerService的启动流程

    WindowManagerService是Android系统中重要的服务,它是WindowManager的管理者,WindowManagerService无论对于应用开发还是Framework开发都是重要的知识点,究其原因是因为WindowManagerService有很多职责,每个职责都会涉及重要且复杂的系统,这使得WindowManagerService就像一个十字路口的交通灯一样

    2024年02月11日
    浏览(46)
  • 基于Android13的系统启动流程分析(三)之FirstStageMain阶段

    Android13系统启动阶段大致分为FirstStageMain阶段和SecondStageMain,此章主要讲FirstStageMain阶段 (若分析有误敬请指教) 本章讲解的方向和你将收获的知识: 用户空间进程的调用流程 当进程挂掉后该如何处理 何时挂载上的基本文件系统和文件系统小知识 FirstStageMain阶段会挂载上什

    2024年02月10日
    浏览(58)
  • Android studio Camera2实现的详细流程

    前提 TextureView.SurfaceTextureListener是一个接口,用于监听TextureView中的SurfaceTexture的状态更改。在使用相机时,您可以使用TextureView来显示相机预览。通过实现SurfaceTextureListener接口,您可以在SurfaceTexture准备好时开始相机预览,并在SurfaceTexture销毁时停止预览。 注意 : 必须是在

    2024年02月05日
    浏览(42)
  • 基于Android13的系统启动流程分析(一)之SeLinux权限介绍

    学习Android系统启动流程之前先学习一下SeLinux权限系统,步入正题 本章讲解的方向和你将收获的知识: 什么是SeLinux系统,SeLinux的简介和介绍 SeLinux系统的主要作用和存在的意义,是基于哪个版本开始推行该方案的 如果遇到了SeLinux权限问题该如何解决,有几种解决方案 SeLi

    2024年02月04日
    浏览(90)
  • Android Camera开发入门(4):USB/UVC Camera的使用

    本文基于开源项目https://github.com/saki4510t/UVCCamera之上进行二次封装和使用 在前几篇文章中,我们介绍了Camera到CameraX的基础功能应用,同时附上了相关代码,需要的源码的大佬们可以滑到最底部获取。 本篇我们一起来了解 USB/UVC 相机是什么以及它们与传统相机的区别,并按照

    2024年02月06日
    浏览(46)
  • Android Camera开发入门(3):CameraX的使用

    CameraX API简介 在前两篇博客中,我们介绍了Camera基础知识和Camera2 API的使用。为了进一步简化相机应用开发,Google推出了CameraX API,它提供了一个更加简洁、易于使用的接口,帮助开发者快速实现高质量的相机功能。本篇博客将带领你了解CameraX的使用方法,并提供相应的示例

    2024年02月11日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包