Android Codec2 CCodec (七)IConfigurable

上一篇文章我们了解了接口参数的定义,这一节我们简单梳理一下参数获取、配置以及参数反射过程。

1、IConfigurable

通过之前的介绍我们了解到,Codec2模块的功能实现与配置实现是相互分离的,Codec2框架设计了一组API用于获取与模块关联的配置对象。

Codec2给ComponentStore设计了名为getConfigurable的API,用于获取Store中的参数对象:

struct ComponentStore : public IComponentStore {
    virtual Return<sp<IConfigurable>> getConfigurable() override;
}

给Component设计的API是getInterface:

struct Component : public IComponent {
    virtual Return<sp<IComponentInterface>> getInterface() override;
}

两个API看似不一样,实则是一样的。IComponentInterface内部有一个接口getConfigurable:

struct ComponentInterface : public IComponentInterface {
    virtual Return<sp<IConfigurable>> getConfigurable() override;
}

所以,调用组件的getInterface方法拿到IComponentInterface对象后,还要再调用一次getConfigurable才能拿到与组件相关联的参数配置。

IConfigurable有四个与参数配置相关的接口:

virtual Return<void> query(
        const hidl_vec<uint32_t>& indices,
        bool mayBlock,
        query_cb _hidl_cb) override;

virtual Return<void> config(
        const hidl_vec<uint8_t>& inParams,
        bool mayBlock,
        config_cb _hidl_cb) override;

virtual Return<void> querySupportedParams(
        uint32_t start,
        uint32_t count,
        querySupportedParams_cb _hidl_cb) override;

virtual Return<void> querySupportedValues(
        const hidl_vec<FieldSupportedValuesQuery>& inFields,
        bool mayBlock,
        querySupportedValues_cb _hidl_cb) override;
  • query:请求指定index参数的值;
  • config:修改指定index参数的值,
  • querySupportedParams:请求支持的参数,start为开始索引,count为选择范围;
  • querySupportedValues:请求字段支持的值。

后续用的最多的是query和config方法,接下来我们将以C2Store为例,对他俩的调用流程进行梳理。为了能将调用流程看得更清楚,这里要再贴一遍C2Store的UML类图:
在这里插入图片描述

2、query

Return<void> CachedConfigurable::query(
        const hidl_vec<uint32_t>& indices,
        bool mayBlock,
        query_cb _hidl_cb) {
    typedef C2Param::Index Index;
    std::vector<Index> c2heapParamIndices(
            (Index*)indices.data(),
            (Index*)indices.data() + indices.size());
    std::vector<std::unique_ptr<C2Param>> c2heapParams;
    c2_status_t c2res = mIntf->query(
            c2heapParamIndices,
            mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
            &c2heapParams);

    hidl_vec<uint8_t> params;
    if (!createParamsBlob(&params, c2heapParams)) {
        LOG(WARNING) << "query -- invalid output params.";
    }
    _hidl_cb(static_cast<Status>(c2res), params);
    return Void();
}

query方法传入参数是一个hidl_vec,可以一次请求一个参数的值,也可以一次请求多个参数的值。hidl_vec元素类型为uint32_t。

  • Index里存储的是一个uint32_t,所以拿到参数可以直接将hidl_vec转换为标准库的vector;
  • 调用ConfigurableIntf的query方法,由StoreIntf最终调用到C2PlatformComponentStore的query_sm方法;
  • 拿到返回值后,需要将C2Param重新转换为hidl_vec,最后通过hidl callback将结果返回。
struct StoreIntf : public ConfigurableC2Intf {
    virtual c2_status_t query(
            const std::vector<C2Param::Index> &indices,
            c2_blocking_t mayBlock,
            std::vector<std::unique_ptr<C2Param>> *const params) const override {
        if (mayBlock == C2_DONT_BLOCK && indices.size() != 0) {
            return C2_BLOCKING;
        }
        return mStore->query_sm({}, indices, params);
    }
}

c2_status_t C2PlatformComponentStore::query_sm(
        const std::vector<C2Param*> &stackParams,
        const std::vector<C2Param::Index> &heapParamIndices,
        std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
    return mInterface.query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
}

通过上一节的学习我们可以知道,mInterface是继承于C2InterfaceHelper的,因此最终调用的是C2InterfaceHelper的query方法。

c2_status_t C2InterfaceHelper::query(
        const std::vector<C2Param*> &stackParams,
        const std::vector<C2Param::Index> &heapParamIndices,
        c2_blocking_t mayBlock __unused /* TODO */,
        std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
    std::lock_guard<std::mutex> lock(mMutex);
    bool paramWasInvalid = false;
    bool paramNotFound = false;
    bool paramDidNotFit = false;
    bool paramNoMemory = false;
    // ...
    // 遍历要获取参数的索引
    for (const C2Param::Index ix : heapParamIndices) {
        // 调用Factory的getParamValue方法
        std::shared_ptr<C2Param> value = _mFactory->getParamValue(ix);
        if (value) {
            // 如果value不为null,则拷贝一份C2Param
            std::unique_ptr<C2Param> p = C2Param::Copy(*value);
            if (p != nullptr) {
                heapParams->push_back(std::move(p));
            } else {
                heapParams->push_back(nullptr);
                paramNoMemory = true;
            }
        } else {
            heapParams->push_back(nullptr);
            paramNotFound = true;
        }
    }

    return paramNoMemory ? C2_NO_MEMORY :
           paramNotFound ? C2_BAD_INDEX :
           // the following errors are not marked in the return value
           paramDidNotFit ? C2_OK :
           paramWasInvalid ? C2_OK : C2_OK;
}

3、config

4、getStructDescriptors

关注公众号《青山渺渺》阅读完整内容

请添加图片描述

  • 24
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青山渺渺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值