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

xiaoxiao2021-02-28  46

通过前面文章的分析,我们知道,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类型。

转载请注明原文地址: https://www.6miu.com/read-2621351.html

最新回复(0)