AndroidO Treble架构下Tranport类型查询过程

通过前面文章的分析,我们知道,Client进程在查询hidl服务接口对象时,会根据该hidl服务的Tranport类型选择加载方式,如果是HWBINDER,那么就从hwservicemanager中查询,如果是PASSTHROUGH,那么就通过PassthroughServiceManager将hal实现库dlopen到当前进程地址空间。那么hidl服务的Tranport类型是如何得到的呢?

 

    const sp<::android::hidl::manager::V1_0::IServiceManager> sm = defaultServiceManager();
    if (sm == nullptr) {
        ALOGE("getService: defaultServiceManager() is null");
        return nullptr;
    }

    Return<Transport> transportRet = sm->getTransport(IComposer::descriptor, serviceName);

是调用hwservicemanager的getTransport函数来得到Tranport类型,这里其实就是IPC进入hwservicemanager进程空间,执行ServiceManager对象的getTransport函数:

system\hwservicemanager\ServiceManager.cpp

Return<ServiceManager::Transport> ServiceManager::getTransport(const hidl_string& fqName,
                                                               const hidl_string& name) {
    using ::android::hardware::getTransport;

    pid_t pid = IPCThreadState::self()->getCallingPid();
    if (!mAcl.canGet(fqName, pid)) {
        return Transport::EMPTY;
    }

    switch (getTransport(fqName, name)) {
        case vintf::Transport::HWBINDER:
             return Transport::HWBINDER;
        case vintf::Transport::PASSTHROUGH:
             return Transport::PASSTHROUGH;
        case vintf::Transport::EMPTY:
        default:
             return Transport::EMPTY;
    }
}

system\hwservicemanager\Vintf.cpp

vintf::Transport getTransport(const std::string &interfaceName, const std::string &instanceName) {
    FQName fqName(interfaceName);
    if (!fqName.isValid()) {
        LOG(DEBUG) << "getTransport: " << interfaceName << " is not a valid fully-qualified name.";
        return vintf::Transport::EMPTY;
    }
    if (!fqName.hasVersion()) {
        LOG(DEBUG) << "getTransport: " << fqName.string()
                   << " does not specify a version. Using default transport.";
        return vintf::Transport::EMPTY;
    }
    if (fqName.name().empty()) {
        LOG(DEBUG) << "getTransport: " << fqName.string()
                   << " does not specify an interface name. Using default transport.";
        return vintf::Transport::EMPTY;
    }

    vintf::Transport tr = getTransportFromManifest(fqName, instanceName,
            vintf::VintfObject::GetFrameworkHalManifest());
    if (tr != vintf::Transport::EMPTY) {
        return tr;
    }
    tr = getTransportFromManifest(fqName, instanceName,
            vintf::VintfObject::GetDeviceHalManifest());
    if (tr != vintf::Transport::EMPTY) {
        return tr;
    }

    LOG(WARNING) << "getTransportFromManifest: Cannot find entry "
                 << fqName.string()
                 << " in either framework or device manifest, using default transport.";
    return vintf::Transport::EMPTY;
}

首先校验接口包名是否合法,然后调用getTransportFromManifest函数分别从/system/manifest.xml和/vendor/manifest.xml文件中读取当前hidl服务的Transport类型。GetFrameworkHalManifest函数将读取/system/manifest.xml文件,GetDeviceHalManifest函数将读取/vendor/manifest.xml文件。这些manifest.xml定义了每个hidl的传输类型。

system\libvintf\VintfObject.cpp

// static
const HalManifest *VintfObject::GetDeviceHalManifest(bool skipCache) {
    return Get(&gDeviceManifest, skipCache,
            std::bind(&HalManifest::fetchAllInformation, std::placeholders::_1,
                "/vendor/manifest.xml"));
}

// static
const HalManifest *VintfObject::GetFrameworkHalManifest(bool skipCache) {
    return Get(&gFrameworkManifest, skipCache,
            std::bind(&HalManifest::fetchAllInformation, std::placeholders::_1,
                "/system/manifest.xml"));
}

这里就是xml的读取解析,具体过程不在展开分析。

system\hwservicemanager\Vintf.cpp

vintf::Transport getTransportFromManifest(
        const FQName &fqName, const std::string &instanceName,
        const vintf::HalManifest *vm) {
    if (vm == nullptr) {
        return vintf::Transport::EMPTY;
    }
    return vm->getTransport(fqName.package(),
            vintf::Version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()},
            fqName.name(), instanceName);
}

system\libvintf\HalManifest.cpp

Transport HalManifest::getTransport(const std::string &package, const Version &v,
            const std::string &interfaceName, const std::string &instanceName) const {

    for (const ManifestHal *hal : getHals(package)) {
        bool found = false;
        for (auto& ver : hal->versions) {
            if (ver.majorVer == v.majorVer && ver.minorVer >= v.minorVer) {
                found = true;
                break;
            }
        }
        if (!found) {
            LOG(DEBUG) << "HalManifest::getTransport(" << to_string(mType) << "): Cannot find "
                      << to_string(v) << " in supported versions of " << package;
            continue;
        }
        auto it = hal->interfaces.find(interfaceName);
        if (it == hal->interfaces.end()) {
            LOG(DEBUG) << "HalManifest::getTransport(" << to_string(mType) << "): Cannot find interface '"
                      << interfaceName << "' in " << package << "@" << to_string(v);
            continue;
        }
        const auto &instances = it->second.instances;
        if (instances.find(instanceName) == instances.end()) {
            LOG(DEBUG) << "HalManifest::getTransport(" << to_string(mType) << "): Cannot find instance '"
                      << instanceName << "' in "
                      << package << "@" << to_string(v) << "::" << interfaceName;
            continue;
        }
        return hal->transportArch.transport;
    }
    LOG(DEBUG) << "HalManifest::getTransport(" << to_string(mType) << "): Cannot get transport for "
                 << package << "@" << v << "::" << interfaceName << "/" << instanceName;
    return Transport::EMPTY;

}

这里就是读取解析manifest.xml,并从manifest.xml中查找对应hidl服务的transport类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值