diff options
author | 2021-09-09 22:36:33 +0000 | |
---|---|---|
committer | 2021-09-21 21:34:52 +0000 | |
commit | 5e4c2f1f0958d29b549f08e2c8e7ee7f5b493384 (patch) | |
tree | 8c993bed71975a43a342291febd77d5e687245e7 /cmds/servicemanager/ServiceManager.cpp | |
parent | 20f5a270658bcdff7a4cc4f9f0059c572ca123eb (diff) |
Add getConnectionInfo API to service manager
This gets connection info from the vintf manifest for AIDL hals that
report it.
The hals will have new "ip" and "port" fields in their entries if they
are serving the interface from a remote device at that ip address/port
combo.
Test: tested the IServiceManager API with an internal POC using a remote HAL
Test: atest binderStabilityTest
Bug: 198207801
Change-Id: I334bebe62afb40e9710b57257f95e37a9c2b8226
Diffstat (limited to 'cmds/servicemanager/ServiceManager.cpp')
-rw-r--r-- | cmds/servicemanager/ServiceManager.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp index 90db5091e1..4e44ac7323 100644 --- a/cmds/servicemanager/ServiceManager.cpp +++ b/cmds/servicemanager/ServiceManager.cpp @@ -121,6 +121,35 @@ static std::optional<std::string> getVintfUpdatableApex(const std::string& name) return updatableViaApex; } +static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) { + AidlName aname; + if (!AidlName::fill(name, &aname)) return std::nullopt; + + std::optional<std::string> ip; + std::optional<uint64_t> port; + forEachManifest([&](const ManifestWithDescription& mwd) { + mwd.manifest->forEachInstance([&](const auto& manifestInstance) { + if (manifestInstance.format() != vintf::HalFormat::AIDL) return true; + if (manifestInstance.package() != aname.package) return true; + if (manifestInstance.interface() != aname.iface) return true; + if (manifestInstance.instance() != aname.instance) return true; + ip = manifestInstance.ip(); + port = manifestInstance.port(); + return false; // break (libvintf uses opposite convention) + }); + return false; // continue + }); + + if (ip.has_value() && port.has_value()) { + ConnectionInfo info; + info.ipAddress = *ip; + info.port = *port; + return std::make_optional<ConnectionInfo>(info); + } else { + return std::nullopt; + } +} + static std::vector<std::string> getVintfInstances(const std::string& interface) { size_t lastDot = interface.rfind('.'); if (lastDot == std::string::npos) { @@ -437,6 +466,22 @@ Status ServiceManager::updatableViaApex(const std::string& name, return Status::ok(); } +Status ServiceManager::getConnectionInfo(const std::string& name, + std::optional<ConnectionInfo>* outReturn) { + auto ctx = mAccess->getCallingContext(); + + if (!mAccess->canFind(ctx, name)) { + return Status::fromExceptionCode(Status::EX_SECURITY); + } + + *outReturn = std::nullopt; + +#ifndef VENDORSERVICEMANAGER + *outReturn = getVintfConnectionInfo(name); +#endif + return Status::ok(); +} + void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who, ServiceCallbackMap::iterator* it, bool* found) { |