第9讲 cameraserver进程启动之hidl cameraprovider初始化 -凯发k8旗舰厅

本讲是android camera native framework专题的第9讲,我们介绍cameraserver进程启动之hidl cameraprovider初始化。

更多资源:

资源 描述
在线课程
知识星球 星球名称:深入浅出android camera 星球id: 17296815
wechat 极客笔记圈

hidl camera provider初始化

hidl camera provider初始化流程如下:

hidl camera provider初始化

initializehidlprovider详解

代码基于android 13:

status_t hidlproviderinfo::initializehidlprovider(
        sp& interface,
        int64_t 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 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 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 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 = 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 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 devices;
    hardware::return ret = interface->getcameraidlist([&status, this, &devices](
            status idstatus,
            const hardware::hidl_vec& 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();
    initializeproviderinfocommon(devices);
    return ok;
}

解释:

  1. 通过castfrom来判断icameraprovider的mminorversion
  2. 调用setcallback方法,接收icameraprovidercallback的回调
  3. 调用linktodeath方法,在servicedied处理hal进程挂掉后的异常,remove掉provider
  4. 调用notifydevicestatechange通知camera hal进程,当前摄像头的状态(normal/back_covered/front_covered/folded,可以一次性通知多个状态),该功能在provider 2.5及之后的版本才有
  5. setupvendortags,调用icameraprovider的getvendortags方法拿到vendortagsection,然后创建vendortagdescriptor,通过vendortagdescriptor就能知道有哪些vendor tag了
  6. 调用icameraprovider的getcameraidlist方法获取到当前provider支持的camera device,解析出camera id存放在mproviderpubliccameraids(解析规则解读)
  7. 针对provider >= 2.6
    • 调用provider的getconcurrentstreamingcameraids获取哪些camera可以同时做configurestream,存放在mconcurrentcameraidcombinations
  8. 调用provider的issettorchmodesupported判断是否支持手电筒,存放在msettorchmodesupported
  9. 调用initializeproviderinfocommon,完成device的初始化

camera课程

python教程

java教程

web教程

数据库教程

图形图像教程

办公软件教程

linux教程

计算机教程

大数据教程

开发工具教程

网站地图