CameraService啓動流程分析

和你一起終身學習,這裏是程序員 Android

經典好文推薦,通過閱讀本文,您將收穫以下知識點:

一、CameraService 流程概覽
二、CS進程啓動流程時序圖
三、CameraService進程的啓動流程
四、總結

一、CameraService 流程概覽

二、CS進程啓動流程時序圖

2.1 CS進程的類圖
2.2 進程啓動時序圖

三、CameraService進程的啓動流程

CameraService和上層APP是通過IPC機制進行通信的,這裏會用到aidl - cpp(AIDL文件會編譯生成native binder所需的c文件--IXXX.h BpXXX.cpp BnXXX.cpp以及java層所需的 IXXX.java文件)這裏CameraService是ICameraService.aidl 的服務端,framwork中android.hardware.camera2下面提供的CameraManager就是ICameraService.adil 的客戶端代理。

AIDL文件 服務端 客戶端 BinderName
ICameraService.aidl CameraService進程(CameraService.cpp) CameraManager(Framework API) media.camera
ICameraServiceProxy.aidl CameraServiceProxy(Java層的系統服務) CameraService進程中使用 media.camera.proxy
ICameraDeviceCallbacks.aidl CameraDeviceImpl.CameraDeviceCallbacks CameraService進程中使用 匿名Binder
ICameraDeviceUser.aidl CameraService進程(CameraDeviceClient.cpp) ICameraDeviceUserWrapper(API) 匿名Binder

1、程序的入口

frameworks\av\camera\cameraserver\main_cameraserver.cpp

int main(int argc __unused, char** argv __unused)
{
    signal(SIGPIPE, SIG_IGN);
    // Set 3 threads for HIDL calls
    hardware::configureRpcThreadpool(3, /*willjoin*/ false);
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p", sm.get());
    CameraService::instantiate();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

上面的代碼CameraService::instantiate()調用到了frameworks\av\services\camera\libcameraservice\CameraService.cpp裏面

2、開始ICameraService服務端Binder的創建和註冊流程

class CameraService :
    public BinderService<CameraService>, //模板類 主要是封裝了將Binder 添加到ServiceManager進程中
    public virtual ::android::hardware::BnCameraService, // ICameraService的服務端需要繼承BnCameraService(native binder的寫法)
    public virtual IBinder::DeathRecipient,  //Binder死亡監聽  監聽客戶端進程的死亡情況
    public virtual CameraProviderManager::StatusListener{}

// CameraService::instantiate(); 調用這裏的instantiate()  主要是向sm註冊了ICameraService的服務端binder
template<typename SERVICE>
class BinderService
{
public:
    static status_t publish(bool allowIsolated = false,int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        sp<IServiceManager> sm(defaultServiceManager());
        // 這裏就是向sm進程中註冊Binder  這裏的Binder的名稱是 "media.camera"
        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();
    }
};

上面的new SERVIDE() 讓程序流程來到了CameraService() 構造函數裏面,CameraService繼承額BnCameraService(這個是AIDL--cpp生成的代碼)所以CameraService.cpp是ICameraService.adil的IPC機制的服務端。

3 CameraService的構造函數

CameraService::CameraService() :
        mEventLog(DEFAULT_EVENT_LOG_LENGTH), //初始化用來打印Log的圓形Buffer的長度-100
        mNumberOfCameras(0),//初始化Camera的數量爲0
        mSoundRef(0), 
        mInitialized(false) //標識CameraService 是否被初始化了
{
    ALOGI("CameraService started (pid=%d)", getpid());
    mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
}

構造函數執行完成之後,sm裏面也註冊了該服務的binder。然後因爲CamerService繼承了RefBase所以CamerService對象在第一次被創建的時候會調用到onFirstRef()函數:

4、CameraService的onFirstRef()

void CameraService::onFirstRef()
{
    ALOGI("CameraService process starting");
    BnCameraService::onFirstRef(); // 調用它的父類的onFirstRef()函數
    // Update battery life tracking if service is restarting
    BatteryNotifier& notifier(BatteryNotifier::getInstance());
    notifier.noteResetCamera();
    notifier.noteResetFlashlight();
    status_t res = INVALID_OPERATION;
    //主要是調用 enumerateProviders() 函數獲取CameraProvider信息。
    res = enumerateProviders();
    if (res == OK) {
        mInitialized = true;
    }
    //連接CameraServiceProxy服務,也就是"media.camera.proxy"服務,此服務由SystemServer註冊到ServiceManager中
    CameraService::pingCameraServiceProxy();
    mUidPolicy = new UidPolicy(this);
    mUidPolicy->registerSelf();
}

前面主要是和電源相關的一些信息,這裏不做分析。最主要的是在這裏調用到了enumerateProviders()函數裏面,所以

5、CameraService::enumerateProviders()

status_t CameraService::enumerateProviders() {
    status_t res;
    std::vector<std::string> deviceIds;
    {
        Mutex::Autolock l(mServiceLock);
        //這裏就是對mCameraProviderManager創建然後調用它的初始化函數
        if (nullptr == mCameraProviderManager.get()) { 
             // 創建一個 CameraProviderManager 對象之後調用 initialize(),
             // 其實就是將CameraService設置爲 CameraProviderManager 的監聽者  
            mCameraProviderManager = new CameraProviderManager();
            // 傳入的參數是 this 指針,指向當前 CameraService 實例的地址
            res = mCameraProviderManager->initialize(this); 
            if (res != OK) {
                ALOGE("%s: Unable to initialize camera provider manager: %s (%d)" __FUNCTION__, strerror(-res), res);
                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();
        //創建mFlashlight對象
        if (nullptr == mFlashlight.get()) {
            mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
        }
        res = mFlashlight->findFlashUnits();
        if (res != OK) {
            ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
        }
        //獲取攝像頭設備ID的向量集合
        deviceIds = mCameraProviderManager->getCameraDeviceIds();
    }

    for (auto& cameraId : deviceIds) {
        String8 id8 = String8(cameraId.c_str());
        onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
    }

    return OK;
}

上面創建了一個CameraProviderManager對象並將對象保存在CameraService中mCameraProviderManager 。繼續執行 mCameraProviderManager->initialize(this)。這裏的this指向的就是當前的CameraService對象(因爲CameraService繼承了CameraProviderManager::StatusListener)這裏可以通過這個StatusListener將信息從CameraProviderManager中回調給CameraService。

6、CameraProviderManager創建和初始化

// CameraProviderManager::StatusListener
struct StatusListener : virtual public RefBase {
      ~StatusListener() {}
      //  攝像頭設備的狀態發生
      virtual void onDeviceStatusChanged(const String8 &cameraId, hardware::camera::common::V1_0::CameraDeviceStatus newStatus) = 0;
      // 手電筒狀態發生變化
      virtual void onTorchStatusChanged(const String8 &cameraId, hardware::camera::common::V1_0::TorchModeStatus newStatus) = 0;
      virtual void onNewProviderRegistered() = 0;
};

//第二個參數就是遠程代理類。這個參數已經是默認賦值了,實際類HardwareServiceInteractionProxy
status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
        ServiceInteractionProxy* proxy) //proxy---HardwareServiceInteractionProxy 
{ 
    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    if (proxy == nullptr) {
        ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
        return BAD_VALUE;
    }
    mListener = listener;  //mListener的實現是在CameraService中(類似java中的回調機制)
    mServiceProxy = proxy;
    // 這裏調用到CameraProviderAll.cpp 裏面 然後調用到了defaultServiceManager()->registerForNotifications(),
    // 從notification 是android::hidl::manager::V1_0::IServiceNotification來看應該是老API的兼容處理
    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;
    }

    // 這裏主要是和CameraProvider和ExternalCameraProvider建立聯繫,並把對應的代理(Interface)保存到ProviderInfo中
    // 所以這兩個方法執行完成之後這裏有兩個ProviderInfo對象(保存在mProviders中)。
    addProviderLocked(kLegacyProviderName, /*expected*/ false); //"legacy/0"
    addProviderLocked(kExternalProviderName, /*expected*/ false); //"external/0"
    return OK;
}

將傳遞過來的StatusListener 賦值給mListener。然後執行到 addProviderLocked(kLegacyProviderName, /expected/ false);這裏傳遞的兩個name分別是const std::string kLegacyProviderName("legacy/0"); const std::string kExternalProviderName("external/0"); 這裏的name和之前分析CameraProvider進程啓動的時候註冊的Binder服務的名稱對應上了。然後繼續分析:

7、CameraProviderManager::addProviderLocked() 和CameraProvider進程建立聯繫

 // 首先通過getService方法獲取ICameraProvider代理。
 // 隨後實例化了一個ProviderInfo對象,之後調用其initialize方法進行初始化。
 // 最後將ProviderInfo加入到一個內部容器中進行管理。
status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
    //檢查已知的 Provider 中是否已有名爲 legacy/0 的 
    for (const auto& providerInfo : mProviders) {
        if (providerInfo->mProviderName == newProvider) {
            ALOGW("%s: Camera provider HAL with name '%s' already registered",__FUNCTION__,newProvider.c_str());
            return ALREADY_EXISTS;
        }
    }
    //這裏是通過服務端Binder的名字來獲取hal的ICameraProvider對象
    sp<provider::V2_4::ICameraProvider> interface;  //HIDL的服務端對象
   // 這裏的mServiceProxy就是HardwareServiceInteractionProxy 
    interface = mServiceProxy->getService(newProvider);
    if (interface == nullptr) {
        if (expected) {
            ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,newProvider.c_str());
            return BAD_VALUE;
        } else {
            return OK;
        }
    }

    //通過ProviderInfo保存得到的CameraHal進程的代理對象ICameraProvider
    sp<ProviderInfo> providerInfo =
            new ProviderInfo(newProvider, interface, this);
    status_t res = providerInfo->initialize();
    if (res != OK) {
        return res;
    }

    //將providerInfo添加到一個內部容器進行管理
    mProviders.push_back(providerInfo);

    return OK;
}

首先mServiceProxy->getService(newProvider)這個mServiceProxy就是HardwareServiceInteractionProxy對象。這裏會調用到ICameraProvider::getService(serviceName)。

7.1、獲取CameraProvider的代理對象

struct HardwareServiceInteractionProxy : public ServiceInteractionProxy {
        virtual bool registerForNotifications(const std::string &serviceName,
                const sp<hidl::manager::V1_0::IServiceNotification>&notification) override {
            return hardware::camera::provider::V2_4::ICameraProvider::registerForNotifications(
                    serviceName, notification);
        }
       //這裏的ICameraProvider對象就是ICameraProvider.hal 文件生成的ICameraProvider.h裏面去
        virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
                const std::string &serviceName) override {
            return hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName);
        }
    };

//ICameraProvider.h 是編譯生成的文件
//out\soong.intermediates\hardware\interfaces\camera\provider\2.4\[email protected]_genc++_header\gen\android\hardware\camera\provider\2.4
static ::android::sp<ICameraProvider> getService(const std::string &serviceName="default", bool getStub=false);

##ICameraProvider.h 是頭文件它cpp文件就是CameraProviderAll.cpp(它還是BpHwCameraProvider.h  BnHwCameraProvider.h的cpp文件 )
// 這個函數返回的是BpHwCameraProvider  BpHwCameraProvider是繼承的ICameraProvider
::android::sp<ICameraProvider> ICameraProvider::getService(const std::string &serviceName, const bool getStub) {
    return ::android::hardware::details::getServiceInternal<BpHwCameraProvider>(serviceName, true, getStub);
}

##繼續會調用到HidlTransportSupport.h中的getServiceInternal()函數
##  system/libhidl/transport/include/hidl/HidlTransportSupport.h
template <typename BpType, typename IType = typename BpType::Pure,
          typename = std::enable_if_t<std::is_same<i_tag, typename IType::_hidl_tag>::value>,
          typename = std::enable_if_t<std::is_same<bphw_tag, typename BpType::_hidl_tag>::value>>
// instatnce  這裏是傳遞來的 "legacy/0"  或者 "external/0"  retry--true getStub--false
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
    using ::android::hidl::base::V1_0::IBase;
    //IType::descriptor --- ICameraProvider::descriptor("[email protected]::ICameraProvider")
    sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);
    if (base == nullptr) {
        return nullptr;
    }
    if (base->isRemote()) {
        // getRawServiceInternal guarantees we get the proper class
        return sp<IType>(new BpType(toBinder<IBase>(base)));
    }
    return IType::castFrom(base);
}

上面代碼中執行到getRawServiceInternal(IType::descriptor, instance, retry, getStub)這裏會接着調用到ServiceManagement.cpp裏面去

sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,const std::string& instance,bool retry, bool getStub) {
    using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
    using ::android::hidl::base::V1_0::IBase;
    using ::android::hidl::manager::V1_0::IServiceManager;
    sp<Waiter> waiter;
    // 獲取 hwservicemanager 服務, 用於獲取Service的client端即BpXXX代理類
    const sp<IServiceManager1_1> sm = defaultServiceManager1_1();
    if (sm == nullptr) {
        ALOGE("getService: defaultServiceManager() is null");
        return nullptr;
    }
    Return<Transport> transportRet = sm->getTransport(descriptor, instance);
    if (!transportRet.isOk()) {
        ALOGE("getService: defaultServiceManager()->getTransport returns %s",transportRet.description().c_str());
        return nullptr;
    }
    Transport transport = transportRet;
    const bool vintfHwbinder = (transport == Transport::HWBINDER);
    const bool vintfPassthru = (transport == Transport::PASSTHROUGH);

    ........
    // 從CameraService過來的getStub  爲false  會走到這個分支來。獲取 cameraprovider時,
   // 拿到<sp<IBase>>,之後會New BpHwCameraProvider, 通過 BpHwCameraProvider類調用HIDL通信
    for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
        if (waiter == nullptr && tries > 0) {
            waiter = new Waiter(descriptor, instance, sm);
        }
        if (waiter != nullptr) {
            waiter->reset();  // don't reorder this -- see comments on reset()
        }
        //調用 ServiceManager::get()  返回的是 CameraProvider 代理類(BpHwCameraProvider)
        Return<sp<IBase>> ret = sm->get(descriptor, instance);
        if (!ret.isOk()) {
            ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.", ret.description().c_str(), descriptor.c_str(), instance.c_str());
            break;
        }
        sp<IBase> base = ret;  //ICameraProvider是IBase的子類
        if (base != nullptr) {
            Return<bool> canCastRet =details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);
            if (canCastRet.isOk() && canCastRet) {
                if (waiter != nullptr) { waiter->done(); }
                return base; // still needs to be wrapped by Bp class.
            }
            if (!handleCastError(canCastRet, descriptor, instance)) break;
        }

        // In case of legacy or we were not asked to retry, don't.
        if (vintfLegacy || !retry) break;
        if (waiter != nullptr) {
            ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
            waiter->wait(true /* timeout */);
        }
    }
    if (waiter != nullptr) {
        waiter->done();
    }
     // getStub 爲true  也就是之前的CameraProvider啓動時走的流程用於服務啓動
    if (getStub || vintfPassthru || vintfLegacy) {
        const sp<IServiceManager> pm = getPassthroughServiceManager();
        if (pm != nullptr) {
            sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
            if (!getStub || trebleTestingOverride) {
                base = wrapPassthrough(base);
            }
            return base;
        }
    }
    return nullptr;
}

上面代碼首先就是獲取hwservicemanager 對象。然後 hwservicemanager.get()函數從該服務中獲取CameraProvider進程的代理。 Return<sp<IBase>> ret = sm->get(descriptor, instance)這裏返回的BpCameraProvider繼承了ICameraProvider而後者繼承了IBase。這裏獲取CameraProvider服務端的代碼到此就結束了。在CameraService進程中也可以根據獲取的代理和CameraProvider進程進行數據傳輸。

7、保存CameraProvider服務端的代理BpHwCameraProvider

前面獲取到的Interface(BpHWCameraProvider)會被保存在新建的一個ProviderInfo對象中,然後調用ProviderInfo::initialize()進行一些初始化。初始化完成過後,會將該providerInfo 對象存儲在全局變量mProviders中。下面看看初始化中做了哪些操作

status_t CameraProviderManager::ProviderInfo::initialize() {
    status_t res = parseProviderName(mProviderName, &mType, &mId);
    if (res != OK) {
        ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
        return BAD_VALUE;
    }
    ALOGI("Connecting to new camera provider: %s, isRemote? %d",mProviderName.c_str(), mInterface->isRemote());
     // mInterface是在ProviderInfo的構造函數中賦值的,也就是上面獲取到的BpHwCameraProvider
    // ProviderInfo實現了ICameraProviderCallback接口,所以緊接着調用了ICameraProvider的setCallback將自身註冊到Camera Provider中,
    // 接收來自CameraProvider進程的事件回調。
    hardware::Return<Status> status = mInterface->setCallback(this);
    if (!status.isOk()) {
        ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",__FUNCTION__, mProviderName.c_str(), status.description().c_str());
        return DEAD_OBJECT;
    }
    if (status != Status::OK) {
        ALOGE("%s: Unable to register callbacks with camera provider '%s'",  __FUNCTION__, mProviderName.c_str());
        return mapToStatusT(status);
    }
    //設置死亡監聽
    hardware::Return<bool> linked = mInterface->linkToDeath(this, /*cookie*/ mId);
    if (!linked.isOk()) {
        ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",__FUNCTION__, mProviderName.c_str(), linked.description().c_str());
        return DEAD_OBJECT;
    } else if (!linked) {
        ALOGW("%s: Unable to link to provider '%s' death notifications", __FUNCTION__, mProviderName.c_str());
    }

    // 可用攝像頭列表  裏面存放的是CameraId
    std::vector<std::string> devices;
    //getCameraIdList()參數是一個回調函數,等着Provider進程回調過來準備按來接收數據。主要是將狀態OK的攝像的id存取到devices列表裏面
    hardware::Return<void> ret = mInterface->getCameraIdList([&status, &devices]
            (Status idStatus,const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
                status = idStatus;
                if (status == Status::OK) {
                     for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
                         devices.push_back(cameraDeviceNames[i]);
                     }
                } 
            });
    if (!ret.isOk()) {
        ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s", __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
        return DEAD_OBJECT;
    }
    if (status != Status::OK) {
        ALOGE("%s: Unable to query for camera devices from provider '%s'", __FUNCTION__, mProviderName.c_str());
        return mapToStatusT(status);
    }

    sp<StatusListener> listener = mManager->getStatusListener(); //好像是多餘的代碼
    for (auto& device : devices) { //遍歷Provider進程給過來的攝像頭設備名稱列表
        std::string id;
        // 將設備名和狀態(在這裏初始成PRESENT狀態)保存起來
        status_t res = addDevice(device, hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
        if (res != OK) {
            ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",  __FUNCTION__, device.c_str(), strerror(-res), res);
            continue;
        }
    }
    ALOGI("Camera provider %s ready with %zu camera devices",mProviderName.c_str(), mDevices.size());
    mInitialized = true; //標識是否初始化了
    return OK;
}

mInterface->setCallback(this) 這個會調用到CameraProvider裏面去,然後這裏的this是因爲ProviderInfo繼承了hardware::camera::provider::V2_4::ICameraProviderCallback(這裏ProviderInfo是ICameraProviderCallback的匿名Binder的服務端)。CameraProvider可以通過ICameraProviderCallback傳遞消息到CameraService進程的ProviderInfo中。mInterface->getCameraIdList() 這是主動調用獲取攝像頭列表,這裏是通過函數回調形式傳遞數據。得到攝像頭名稱的列表之後,就對這個列表進行遍歷,根據攝像頭的name屬性獲取攝像頭的基本信息並保存起來。

8、 保存ProviderInfo初始化時獲取攝像頭的名稱信息

上面的代碼會繼續走到 addDevice(device, hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id)

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;
    // 將傳遞過來的name(設備名)解析 得到major  minor  type  id等值
   // name--"[email protected]/internal/1"  majo--3  minor--4 type--"internal" id-- 1
    status_t res = parseDeviceName(name, &major, &minor, &type, &id);
    if (res != OK) {
        return res;
    }
    if (type != mType) {
        ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,type.c_str(), mType.c_str());
        return BAD_VALUE;
    }
    if (mManager->isValidDeviceLocked(id, major)) { //檢查攝像頭設備是否已經添加了ProviderInfo->mDevices中
        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 (major) {  //這裏我們分析的是Camera2的API,所以是3這個分支
        case 1:
            deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, mProviderTagid,  id, minor);
            break;
        case 3: 
            //根據上面的信息去創建一個DeviceInfo3的對象
            deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid, id, minor);
            break;
        default:
            ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,name.c_str(), major);
            return BAD_VALUE;
    }
    if (deviceInfo == nullptr) return BAD_VALUE;
    deviceInfo->mStatus = initialStatus;// 將傳遞過來的CameraDeviceStatus::PRESENT狀態賦值給創建的DeviceInfo對象
    bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
    mDevices.push_back(std::move(deviceInfo));// 將創建的DeviceInfo對象保存到ProviderInfo的mDevices中
    mUniqueCameraIds.insert(id); //將CameraId存放到mUniqueCameraIds
    if (isAPI1Compatible) { //這個表明該攝像頭設備支持camera api1
        mUniqueAPI1CompatibleCameraIds.push_back(id);
    }
    if (parsedId != nullptr) {
        *parsedId = id;
    }
    return OK;
}

根據攝像頭的設備名稱信息獲取到攝像頭的major minor type id等值後做了一些基本的校驗,然後根據這些信息調用initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid, id, minor) 創建一個DeviceInfo3對象

9、CameraProviderManager::ProviderInfo::initializeDeviceInfo() 創建DeviceInfo3對象

 //DeviceInfoT DeviceInfo3
template<class DeviceInfoT>
std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo> CameraProviderManager::ProviderInfo::initializeDeviceInfo(
        const std::string &name, const metadata_vendor_id_t tagId,
        const std::string &id, uint16_t minorVersion) const {
    Status status;
    // DeviceInfo3 中 typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT;
    // cameraInterface -- ICameDevice的代理和provider進程來通信  這裏的模板是device::V3_2::ICameraDevice在Provider進程中的device/3.2/ICameraDevice.hal 
    auto cameraInterface = getDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
    if (cameraInterface == nullptr) return nullptr;
    CameraResourceCost resourceCost;
    //調用到provider進程中的CameraDevice 然後通過回調接收數據
    cameraInterface->getResourceCost([&status, &resourceCost]
           ( Status s, CameraResourceCost cost) {
                status = s;
                resourceCost = cost;
            });
    if (status != Status::OK) {
        ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
                name.c_str(), statusToString(status));
        return nullptr;
    }
    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;
    }
    return std::unique_ptr<DeviceInfo>(new DeviceInfoT(name, tagId, id, minorVersion, resourceCost,cameraInterface));
}

獲取CameraProvider進程中的的ICameraDevice.hal的代理--cameraInterface,這裏的 getDeviceInterface<typename DeviceInfoT::InterfaceT>(name)函數中的模板是hardware::camera::device::V3_2::ICameraDevice所以會調用到對應版的函數如下:
然後通過cameraInterface->getResourceCost()獲取攝像頭設備的一些屬性信息(也就是前面CameraProvider進程中的camera_info)。

9.1、首先看看如何得到ICameraDevice的代理

ICameraDevice.hal 會生成ICameraDevice.h 文件

template<>
sp<device::V3_2::ICameraDevice>
CameraProviderManager::ProviderInfo::getDeviceInterface <device::V3_2::ICameraDevice>(const std::string &name) const {
    Status status;
    sp<device::V3_2::ICameraDevice> cameraInterface;
    hardware::Return<void> ret;
    //這裏主要是調用CameraProvider中的getCameraDeviceInterface_V3_x(name)函數 這裏的name 就是前面獲取到的設備名稱
    ret = mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
        Status s, sp<device::V3_2::ICameraDevice> interface) {
                status = s;
                cameraInterface = interface;
            });
    if (!ret.isOk()) {
        ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s", __FUNCTION__, name.c_str(), ret.description().c_str());
        return nullptr;
    }
    if (status != Status::OK) {
        ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__, name.c_str(), statusToString(status));
        return nullptr;
    }
    return cameraInterface; // 返回Provider進程中ICameraDevice的代理 
}

這個主要是用到了前面獲取到的ICameraProvider的代理(mInterface)之後調用其getCameraDeviceInterface_V3_x(name)函數,然後通過回調的形式收到ICameraDevice的代理(可以看出這裏也使用到了匿名Binder)。

9.2、CameraProvider::getCameraDeviceInterface_V3_x(name)。

//cameraDeviceName --  "[email protected]/internal/1"
Return<void> CameraProvider::getCameraDeviceInterface_V3_x(const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb)  {
    std::string cameraId, deviceVersion;
    bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId); //根據deviceName從中獲取version和cameraId的值
    if (!match) { // 判斷傳遞過來的CameraDeviceName是否能和本地的正則表達式匹配
        _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
        return Void();
    }
    std::string deviceName(cameraDeviceName.c_str());
    ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
    if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
        Status status = Status::OK;
        ssize_t idx = mCameraIds.indexOf(cameraId);
        if (idx == NAME_NOT_FOUND) {
            ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
            status = Status::ILLEGAL_ARGUMENT;
        } else { // invalid version
            ALOGE("%s: camera device %s does not support version %s!", __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
            status = Status::OPERATION_NOT_SUPPORTED;
        }
        _hidl_cb(status, nullptr);
        return Void();
    }
    if (mCameraStatusMap.count(cameraId) == 0 || mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
        _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
        return Void();
    }
    sp<android::hardware::camera::device::V3_2::ICameraDevice> device;
    if (deviceVersion == kHAL3_4) {  // kHAL3_4 == 3.4  所以流程會走到這裏面來
        ALOGV("Constructing v3.4 camera device");
        // 這裏會創建ICameraDevice.hal 的服務端的對象,並將mModule 傳遞給這個對象(CameraDevice)
       // 這裏的mModule對象就是CameraModule 這個對象裏面有一個camera_module_t 用來調用CameraHAL.so來操作攝像頭
        sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
            new android::hardware::camera::device::V3_4::implementation::CameraDevice(mModule, cameraId, mCameraDeviceNames);
        if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
            ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
            device = nullptr;
            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
            return Void();
        }

        device = deviceImpl;
        _hidl_cb (Status::OK, device);
        return Void();
    }

    // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
    // to the newest possible Treble HAL revision, but allow for override if needed via
    // system property.
    switch (mPreferredHal3MinorVersion) {
        case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
            ALOGV("Constructing v3.2 camera device");
            sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
                    new android::hardware::camera::device::V3_2::implementation::CameraDevice(
                    mModule, cameraId, mCameraDeviceNames);
            if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
                ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
                device = nullptr;
                _hidl_cb(Status::INTERNAL_ERROR, nullptr);
                return Void();
            }
            device = deviceImpl;
            break;
        }
        case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
            ALOGV("Constructing v3.3 camera device");
            sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
                    new android::hardware::camera::device::V3_3::implementation::CameraDevice(
                    mModule, cameraId, mCameraDeviceNames);
            if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
                ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
                device = nullptr;
                _hidl_cb(Status::INTERNAL_ERROR, nullptr);
                return Void();
            }
            device = deviceImpl;
            break;
        }
        default:
            ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion);
            device = nullptr;
            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
            return Void();
    }
    _hidl_cb (Status::OK, device);
    return Void();
}

在initializeDeviceInfo() 中 cameraInterface->getResourceCost()會調用到CameraProvider進程中的CameraDevice.cpp裏面

四、總結

到此CameraService進程的啓動流程就分析完了。大致總結一下這個啓動流程做了什麼:
1、創建了一個CameraProviderManager對象來負責管理和CP進程的IPC。
2、在CameraProviderManager裏面會創建一個ProviderInfo對象來保存和CP進程通信的ICameraProvider.hal的代理。
3、通過ICameraProvider獲取攝像頭的數量,然後遍歷攝像頭個數,通過調用ICameraProvider中的getCameraDeviceInterface_V3_x()函數創建ICameraDevice的服務端實例,並將其代理作爲參數來創建DeviceInfo3對象
CameraService 1 --- 1 CameraProviderManager 1 --- 1 ProviderInfo 1 --- M DeviceInfo3
其中ProviderInfo 持有CP進程中CameraProvider的代理
DeviceInfo3 持有CP進程中的CameraDevice的代理

原文鏈接:https://www.jianshu.com/p/b16c8c2b8921

至此,本篇已結束。轉載網絡的文章,小編覺得很優秀,歡迎點擊閱讀原文,支持原創作者,如有侵權,懇請聯繫小編刪除,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章