一、Android CameraService服务启动

Android 开源项目简介
  Android 是一个适用于移动设备的开源操作系统,也是由 Google 主导的对应开源项目。此网站和 Android 开源项目 (AOSP) 代码库可为您提供所需信息和源代码,供您创建定制的 Android OS 版本,将设备和配件移植到 Android 平台,同时确保设备符合兼容性要求,从而让 Android 生态系统维持良好稳健的运行环境,以便更好地服务于数百万用户。
  作为一个开源项目,Android 的目标是避免出现任何集中瓶颈,即没有任何行业参与者可一手限制或控制其他任何参与者的创新。为此,Android 被打造成了一个适用于消费类产品的完整高品质操作系统,并配有可自定义并运用到几乎所有设备的源代码,以及所有用户均可访问的公开文档(英文网址:source.android.com;简体中文网址:source.android.google.cn)。
  正如您可以为 AOSP 贡献代码一样,您也可以为 AOSP 文档“添砖加瓦”,而且我们非常欢迎您提供宝贵意见!Android 的灵活性和不断变化的代码库意味着,此网站要想提供准确且与 Android 实现者息息相关的最新内容,离不开您的反馈。我们建议您查看更新日志,详细了解 AOSP 的最新动态,并使用每个页面底部的网站反馈(或通过访问 g.co/androidsourceissue)来报告 bug 或提供建议。
Alt

以上内容来自于 https://source.android.google.cn/?hl=zh-cn
图中内容可参考:https://source.android.google.cn/docs/core/architecture?hl=zh-cn


该文档是根据Android R代码进行CameraService服务启动流程介绍,在此之前先对android系统启动流程大概的了解一下。详情可以参考以下链接。 参考链接:
https://www.jianshu.com/p/3999842b7361
https://blog.csdn.net/yuanqiyuanluo2014/article/details/128041889


一、服务启动文件

cameraserver.rc

service cameraserver /system/bin/cameraserver // 该部分定义了一个名为cameraserver的服务,他的可执行文件路径为system/bin/cameraserver
    class main	// 类别为main
    user cameraserver // 在执行此服务之前,请更改为“cameraserver ”
    group audio camera input drmrpc // 在执行此服务之前,请更改为“groupname”。除了(必需的)第一个之外的其他组名用于设置进程的补充组(通过setgroups())。
    ioprio rt 4 // 通过ioprioset系统调用,为该服务设置IO优先级类别和IO优先级
    task_profiles CameraServiceCapacity MaxPerformance // 设置任务配置文件。在安卓U之前,配置文件应用于服务的主线程。对于Android U及更高版本,配置文件将应用于整个服务过程。这是为了取代使用writepid选项将进程移动到cgroup中。
    rlimit rtprio 10 10 // 他的将给定的rlimit应用于服务。rlimit由子进程继承,因此这将有效地将给定的rlimit应用于此服务启动的进程树。它的解析类似于下面指定的setrlimit命令。

rc文件语法参考文档路径 :

code\system\core\init\README.md

android系统启动init进程后,在init进程中会通过cameraserver.rc启动cameraserver进程;从frameworks\av\camera\cameraserver\Android.bp文件可以确认,cameraserver进程启动后会调用main_cameraserver.cpp中的main函数。

frameworks\av\camera\cameraserver\Android.bp

cc_binary {
  name: "cameraserver",

  srcs: ["main_cameraserver.cpp"],
  header_libs: [
      "libmedia_headers",
  ],

  shared_libs: [
      "libcameraservice",
      "liblog",
      "libutils",
      "libui",
      "libgui",
      "libbinder",
      "libhidlbase",
      "android.hardware.camera.common@1.0",
      "android.hardware.camera.provider@2.4",
      "android.hardware.camera.provider@2.5",
      "android.hardware.camera.provider@2.6",
      "android.hardware.camera.provider@2.7",
      "android.hardware.camera.device@1.0",
      "android.hardware.camera.device@3.2",
      "android.hardware.camera.device@3.4",
  ],
  compile_multilib: "first",
  cflags: [
      "-Wall",
      "-Wextra",
      "-Werror",
      "-Wno-unused-parameter",
  ],

  init_rc: ["cameraserver.rc"],

  vintf_fragments: [
      "manifest_android.frameworks.cameraservice.service@2.2.xml",
  ],
}

frameworks\av\camera\cameraserver\main_cameraserver.cpp

main_cameraserver.cpp中,主要介绍CameraService::instantiate();

1. main_cameraserver.cpp源码

#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();
}

2.CameraService类关系图及其instantiate方法流程

2.1 CameraService类关系图及其相关类路径
文件路径class name
\frameworks\native\libs\binder\include\binder\BinderService.htemplate <typename SERVICE> class BinderService
\frameworks\native\libs\binder\include\binder\IBinder.hIBinder::DeathRecipient
\frameworks\av\services\camera\libcameraservice\common\CameraProviderManager.hCameraProviderManager::StatusListener
\frameworks\av\camera\aidl\android\hardware\ICameraService.aidl::android::hardware::BnCameraService
virtual
virtual
virtual
BnCameraService
CameraService
DeathRecipient
StatusListener
«CameraService»
BinderService
+static int32_t publish(bool, int)
+static void instantiate()

在上述的表和图中,CameraService继承了BnCameraServiceDeathRecipientStatusListenerBinderService<CameraService>四个类, 其中继承的第四个类是以CameraService类为模板的BinderService类。BinderService类中包含了静态方法instantiate

2.2 BinderService类源码
template<typename SERVICE>
class BinderService
{
public:
   static status_t publish(bool allowIsolated = false,
                           int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
       sp<IServiceManager> sm(defaultServiceManager());
       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();
   }

   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();
   }
};

BinderService的类设计比较简单,包含了四个公有的静态方法publish、publishAndJoinThreadPool、instantiate、shutdown和一个私有的静态方法joinThreadPool

2.3 main_cameraserver中main函数的简单流程

以下是main_cameraserver中main函数的基本流程, 该流程会添加media.camera服务到系统服务中。同时在函数传参的时候,存在CameraService的sp引用,因此,在参数传递的过程中会调用CameraService中的onFirstRef函数,做camerasrver服务的初始化操作。然后调用到IServiceManager中的addService把media.camera服务添加到系统服务中。

status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
                                        bool allowIsolated, int dumpsysPriority)
{
    Status status = mTheRealServiceManager->addService(
        String8(name).c_str(), service, allowIsolated, dumpsysPriority);
    return status.exceptionCode();
}

以下是cameraserver服务启动的基本流程:

main_cameraserver BinderService IServiceManager CameraService CameraService::instantiate() publish defaultServiceManager 返回IServiceManager强指针 new CameraService() 返回CameraService指针对象 addService("media.camera", &CameraService,defult, default) 返回addService结果 CameraService::instantiate执行完成 main_cameraserver BinderService IServiceManager CameraService

二、CameraService服务初始化及其onFirstRef流程

1.onFirstRef调用流程及源码

1.1 onFirstRef调起流程

在上一节的中的2.3小节中有提过参数传递的过程中会调用CameraService中的onFirstRef函数,接下来让我们一起看下onFirstRef调用的流程。

\system\core\libutils\RefBase.cpp
\system\core\libutils\include\utils\RefBase.h

在RefBase类中,在incStrong的方法中会调用onFirstRef函数,而incStrong的方法是StrongPointer.h中sp初始化话的时候会调用。所以在BinderService类中的publish方法中函数中调用addService函数时,创建CameraService对象并赋值给sp<IBinder> & service;在赋值的过程中会调用到incStrong方法,同时,由于CameraService会继承RefBase类,所以在调用onFirstRef时会调用到CameraService中的onFirstRef函数, 开始初始化话CameraService服务。

void RefBase::onFirstRef()
{
}

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;
    }

    check_not_on_stack(this);

    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->onFirstRef();
}

code\system\core\libutils\include\utils\StrongPointer.h

incStrong的调用一般是在首次对象首次引用的时候会调用一次, 后续不会调用。

template <typename T>
sp<T>& sp<T>::operator=(T* other) {
    T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
    if (other) {
        other->incStrong(this);
    }
    if (oldPtr) oldPtr->decStrong(this);
    if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
    m_ptr = other;
    return *this;
}
1.2 CameraService onFirstRef函数源码

onFirstRef函数中, 主要是枚举设备enumerateProviders,UidPolicy的创建及注册和SensorPrivacyPolicy的创建及注册;其中最重要的是枚举设备的流程。

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;

    res = enumerateProviders();
    if (res == OK) {
        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");
}

2. CameraService服务初始化

2.1 枚举设备enumerateProviders

枚举设备的过程中先获取mServiceLock, 防止其他资源访问;在获取到锁资源时,首先对会创建CameraProviderManager对象并初始化,初始化后会设置vendorTags(相机静态能力),然后创建CameraFlashlight对象,最后通过初始化完成的CameraProvidermanager对象获取CameraID;获取cameraid后释放mServiceLock。
上报camera id到框架测,然后通过配置的ro.odm.build.media_performance_class决定是否需要过滤相机参数信息(过滤时依需获取mServiceLock锁资源)。

status_t CameraService::enumerateProviders() {
    status_t res;

    std::vector<std::string> deviceIds;
    {
        Mutex::Autolock l(mServiceLock);

        if (nullptr == mCameraProviderManager.get()) { // 首次创建及初始化
            mCameraProviderManager = new CameraProviderManager();
            res = mCameraProviderManager->initialize(this); // 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;
            }
        }


        // Setup vendor tags before we call get_camera_info the first time
        // because HAL might need to setup static vendor keys in get_camera_info
        // TODO: maybe put this into CameraProviderManager::initialize()?
        mCameraProviderManager->setUpVendorTags();

        if (nullptr == mFlashlight.get()) { // 首次创建CameraFlashlight
            mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
        }

        res = mFlashlight->findFlashUnits();
        if (res != OK) {
            ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
        }

        deviceIds = mCameraProviderManager->getCameraDeviceIds(); // 获取camera id
    }


    for (auto& cameraId : deviceIds) { // 遍历cameraId并通知到java框架测
        String8 id8 = String8(cameraId.c_str());
        if (getCameraState(id8) == nullptr) {
            onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT); 
        }
    }

    // Derive primary rear/front cameras, and filter their charactierstics.
    // This needs to be done after all cameras are enumerated and camera ids are sorted.
    if (SessionConfigurationUtils::IS_PERF_CLASS) { // 判断设置的media_performance_class,满足条件则过滤相机的参数
        // Assume internal cameras are advertised from the same
        // provider. If multiple providers are registered at different time,
        // and each provider contains multiple internal color cameras, the current
        // logic may filter the characteristics of more than one front/rear color
        // cameras.
        Mutex::Autolock l(mServiceLock);
        filterSPerfClassCharacteristicsLocked();
    }

    return OK;
}
2.2 CameraProviderManager创建及初始化
  1. CameraProviderManager中没有构造函数,使用默认构造函数

mCameraProviderManager = new CameraProviderManager();

  1. CameraProviderManager的初始化

res = mCameraProviderManager->initialize(this);

CameraProviderManager初始化源码如下:
主要分为两步,第一步是注册服务registerForNotifications,第二步是添加provider的addProviderLocked函数。现主要对第二步添加provider进行分析。

    static HardwareServiceInteractionProxy sHardwareServiceInteractionProxy;
    ...
    /**
     * Initialize the manager and give it a status listener; optionally accepts a service
     * interaction proxy.
     *
     * The default proxy communicates via the hardware service manager; alternate proxies can be
     * used for testing. The lifetime of the proxy must exceed the lifetime of the manager.
     */
    status_t initialize(wp<StatusListener> listener,
            ServiceInteractionProxy *proxy = &sHardwareServiceInteractionProxy);
CameraProviderManager::sHardwareServiceInteractionProxy{};
...
status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
        ServiceInteractionProxy* proxy) {
    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    if (proxy == nullptr) {
        ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
        return BAD_VALUE;
    }
    mListener = listener;
    mServiceProxy = proxy;
    mDeviceState = static_cast<hardware::hidl_bitfield<provider::V2_5::DeviceState>>(
        provider::V2_5::DeviceState::NORMAL);

    // Registering will trigger notifications for all already-known providers
    bool success = mServiceProxy->registerForNotifications(
        /* instance name, empty means no filter */ "",
        this);
    if (!success) {
        ALOGE("%s: Unable to register with hardware service manager for notifications "
                "about camera providers", __FUNCTION__);
        return INVALID_OPERATION;
    }


    for (const auto& instance : mServiceProxy->listServices()) {
        this->addProviderLocked(instance); 
    }

    IPCThreadState::self()->flushCommands();

    return OK;
}

addProviderLocked函数源码如下:

status_t CameraProviderManager::addProviderLocked(const std::string& newProvider,
        bool preexisting) {
    // Several camera provider instances can be temporarily present.
    // Defer initialization of a new instance until the older instance is properly removed.
    auto providerInstance = newProvider + "-" + std::to_string(mProviderInstanceId);
    bool providerPresent = false;
    for (const auto& providerInfo : mProviders) { // 首次初始化的时候,mProviders为空
        if (providerInfo->mProviderName == newProvider) {
            ALOGW("%s: Camera provider HAL with name '%s' already registered",
                    __FUNCTION__, newProvider.c_str());
            if (preexisting) {
                return ALREADY_EXISTS;
            } else{
                ALOGW("%s: The new provider instance will get initialized immediately after the"
                        " currently present instance is removed!", __FUNCTION__);
                providerPresent = true;
                break;
            }
        }
    }

    sp<ProviderInfo> providerInfo = new ProviderInfo(newProvider, providerInstance, this);
    if (!providerPresent) {
        status_t res = tryToInitializeProviderLocked(newProvider, providerInfo);
        if (res != OK) {
            return res;
        }
    }

    mProviders.push_back(providerInfo); // mProviders初始化
    mProviderInstanceId++;

    return OK;
}

根据源码分析,addProviderLocked时会先创建providerInfo, 然后根据provider name和providerInfo调用tryToInitializeProviderLocked初始化provider。tryToInitializeProviderLocked源码如下:

status_t CameraProviderManager::tryToInitializeProviderLocked(
        const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
    sp<provider::V2_4::ICameraProvider> interface;
    interface = mServiceProxy->tryGetService(providerName); 

    if (interface == nullptr) {
        // The interface may not be started yet. In that case, this is not a
        // fatal error.
        ALOGW("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
                providerName.c_str());
        return BAD_VALUE;
    }

    return providerInfo->initialize(interface, mDeviceState);
}

tryToInitializeProviderLocked主要内容有:1、根据provider name获取ICameraProvider服务;2、对providerInfo进行初始化;主要看第二部,源码如下:

status_t CameraProviderManager::ProviderInfo::initialize(
        sp<provider::V2_4::ICameraProvider>& interface,
        hardware::hidl_bitfield<provider::V2_5::DeviceState> currentDeviceState) {
    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());

    // Determine minor version
    mMinorVersion = 4;
    auto cast2_6 = provider::V2_6::ICameraProvider::castFrom(interface);
    sp<provider::V2_6::ICameraProvider> interface2_6 = nullptr;
    if (cast2_6.isOk()) {
        interface2_6 = cast2_6;
        if (interface2_6 != nullptr) {
            mMinorVersion = 6;
        }
    }
    // We need to check again since cast2_6.isOk() succeeds even if the provider
    // version isn't actually 2.6.
    if (interface2_6 == nullptr){
        auto cast2_5 =
                provider::V2_5::ICameraProvider::castFrom(interface);
        sp<provider::V2_5::ICameraProvider> interface2_5 = nullptr;
        if (cast2_5.isOk()) {
            interface2_5 = cast2_5;
            if (interface != nullptr) {
                mMinorVersion = 5;
            }
        }
    } else {
        auto cast2_7 = provider::V2_7::ICameraProvider::castFrom(interface);
        if (cast2_7.isOk()) {
            sp<provider::V2_7::ICameraProvider> interface2_7 = cast2_7;
            if (interface2_7 != nullptr) {
                mMinorVersion = 7;
            }
        }
    }

    // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
    // before setCallback returns
    hardware::Return<Status> status = interface->setCallback(this);
    if (!status.isOk()) {
        ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
                __FUNCTION__, mProviderName.c_str(), status.description().c_str());
        return DEAD_OBJECT;
    }
    if (status != Status::OK) {
        ALOGE("%s: Unable to register callbacks with camera provider '%s'",
                __FUNCTION__, mProviderName.c_str());
        return mapToStatusT(status);
    }

    hardware::Return<bool> linked = interface->linkToDeath(this, /*cookie*/ mId);
    if (!linked.isOk()) {
        ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
                __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
        return DEAD_OBJECT;
    } else if (!linked) {
        ALOGW("%s: Unable to link to provider '%s' death notifications",
                __FUNCTION__, mProviderName.c_str());
    }

    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);
    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;
    hardware::Return<void> ret = interface->getCameraIdList([&status, this, &devices](
            Status idStatus,
            const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
        status = idStatus;
        if (status == Status::OK) {
            for (auto& name : cameraDeviceNames) {
                uint16_t major, minor;
                std::string type, id;
                status_t res = parseDeviceName(name, &major, &minor, &type, &id);
                if (res != OK) {
                    ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
                    status = Status::INTERNAL_ERROR;
                } else {
                    devices.push_back(name);
                    mProviderPublicCameraIds.push_back(id);
                }
            }
        } });
    if (!ret.isOk()) {
        ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
                __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
        return DEAD_OBJECT;
    }
    if (status != Status::OK) {
        ALOGE("%s: Unable to query for camera devices from provider '%s'",
                __FUNCTION__, mProviderName.c_str());
        return mapToStatusT(status);
    }

    // Get list of concurrent streaming camera device combinations
    if (mMinorVersion >= 6) {
        res = getConcurrentCameraIdsInternalLocked(interface2_6);
        if (res != OK) {
            return res;
        }
    }

    ret = interface->isSetTorchModeSupported(
        [this](auto status, bool supported) {
            if (status == Status::OK) {
                mSetTorchModeSupported = supported;
            }
        });
    if (!ret.isOk()) {
        ALOGE("%s: Transaction error checking torch mode support '%s': %s",
                __FUNCTION__, mProviderName.c_str(), ret.description().c_str());
        return DEAD_OBJECT;
    }

    mIsRemote = interface->isRemote();

    sp<StatusListener> listener = mManager->getStatusListener();
    for (auto& device : devices) {
        std::string id;
        status_t res = addDevice(device, common::V1_0::CameraDeviceStatus::PRESENT, &id);
        if (res != OK) {
            ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
                    __FUNCTION__, device.c_str(), strerror(-res), res);
            continue;
        }
    }

    ALOGI("Camera provider %s ready with %zu camera devices",
            mProviderName.c_str(), mDevices.size());

    // Process cached status callbacks
    std::unique_ptr<std::vector<CameraStatusInfoT>> cachedStatus =
            std::make_unique<std::vector<CameraStatusInfoT>>();
    {
        std::lock_guard<std::mutex> lock(mInitLock);

        for (auto& statusInfo : mCachedStatus) {
            std::string id, physicalId;
            status_t res = OK;
            if (statusInfo.isPhysicalCameraStatus) {
                res = physicalCameraDeviceStatusChangeLocked(&id, &physicalId,
                    statusInfo.cameraId, statusInfo.physicalCameraId, statusInfo.status);
            } else {
                res = cameraDeviceStatusChangeLocked(&id, statusInfo.cameraId, statusInfo.status);
            }
            if (res == OK) {
                cachedStatus->emplace_back(statusInfo.isPhysicalCameraStatus,
                        id.c_str(), physicalId.c_str(), statusInfo.status);
            }
        }
        mCachedStatus.clear();

        mInitialized = true;
    }

    // The cached status change callbacks cannot be fired directly from this
    // function, due to same-thread deadlock trying to acquire mInterfaceMutex
    // twice.
    if (listener != nullptr) {
        mInitialStatusCallbackFuture = std::async(std::launch::async,
                &CameraProviderManager::ProviderInfo::notifyInitialStatusChange, this,
                listener, std::move(cachedStatus));
    }

    return OK;
}

函数代码比较长,主要有以下步骤:

  1. parseProviderName,解析provider name并校验;
  2. ICameraProvider接口选择(随着android的升级, ICameraProvider.hal的接口在不断的迭代升级,代码中会做兼容,对于不同的ICameraProvider的实现,调用不同的ICameraProvider接口,当前最新为2_7版本);
  3. 通过ICameraProvider接口设置在底层设置回调,setCallback(this);
  4. 设置死亡监听linkToDeath
  5. notifyDeviceStateChange通知设备状态
  6. 设置vendor tag(可以理解为底层上报的能力)setUpVendorTags,在setUpVendorTags会通过ICameraProvider接口获取vendor tag, 然后设置,此处不再详述;
  7. 获取camera id 列表getCameraIdList
// Get initial list of camera devices, if any
    std::vector<std::string> devices;
    hardware::Return<void> ret = interface->getCameraIdList([&status, this, &devices](
            Status idStatus,
            const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
        status = idStatus;
        if (status == Status::OK) {
            for (auto& name : cameraDeviceNames) {
                uint16_t major, minor;
                std::string type, id;
                status_t res = parseDeviceName(name, &major, &minor, &type, &id);
                if (res != OK) {
                    ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
                    status = Status::INTERNAL_ERROR;
                } else {
                    devices.push_back(name);
                    mProviderPublicCameraIds.push_back(id);
                }
            }
        } });
  1. 其他CameraProviderManager的成员初始化(其中包含了很多, 暂不详述);
  2. 通过回调函数上报相机状态
    // The cached status change callbacks cannot be fired directly from this
    // function, due to same-thread deadlock trying to acquire mInterfaceMutex
    // twice.
    if (listener != nullptr) {
        mInitialStatusCallbackFuture = std::async(std::launch::async,
                &CameraProviderManager::ProviderInfo::notifyInitialStatusChange, this,
                listener, std::move(cachedStatus));
    }

至此CameraProviderManager的初始化完成。

2.3 通过CameraProviderManager获取初始化后的设备id列表

源码如下:

std::vector<std::string> CameraProviderManager::getCameraDeviceIds() const {
    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    std::vector<std::string> deviceIds;
    for (auto& provider : mProviders) {
        for (auto& id : provider->mUniqueCameraIds) {
            deviceIds.push_back(id);
        }
    }
    return deviceIds;
}
2.4 设备状态通知

源码如下:

    for (auto& cameraId : deviceIds) {
        String8 id8 = String8(cameraId.c_str());
        if (getCameraState(id8) == nullptr) {
            onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
        }
    }
2.5 相机参数过滤
    // Derive primary rear/front cameras, and filter their charactierstics.
    // This needs to be done after all cameras are enumerated and camera ids are sorted.
    if (SessionConfigurationUtils::IS_PERF_CLASS) {
        // Assume internal cameras are advertised from the same
        // provider. If multiple providers are registered at different time,
        // and each provider contains multiple internal color cameras, the current
        // logic may filter the characteristics of more than one front/rear color
        // cameras.
        Mutex::Autolock l(mServiceLock);
        filterSPerfClassCharacteristicsLocked();
    }

至此, CameraService启动流程基本完成。

三、总结

CameraService服务启动相对简单, 重点在于和底层及其其他模块的交互。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值