Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5e4c2f1f authored by Devin Moore's avatar Devin Moore
Browse files

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
parent 20f5a270
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ class ServiceManagerMock : public IServiceManager {
    MOCK_METHOD1(isDeclared, bool(const String16&));
    MOCK_METHOD1(getDeclaredInstances, Vector<String16>(const String16&));
    MOCK_METHOD1(updatableViaApex, std::optional<String16>(const String16&));
    MOCK_METHOD1(getConnectionInfo, std::optional<ConnectionInfo>(const String16&));
  protected:
    MOCK_METHOD0(onAsBinder, IBinder*());
};
+45 −0
Original line number Diff line number Diff line
@@ -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) {
+3 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

namespace android {

using os::ConnectionInfo;
using os::IClientCallback;
using os::IServiceCallback;
using os::ServiceDebugInfo;
@@ -48,6 +49,8 @@ public:
    binder::Status getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) override;
    binder::Status updatableViaApex(const std::string& name,
                                    std::optional<std::string>* outReturn) override;
    binder::Status getConnectionInfo(const std::string& name,
                                     std::optional<ConnectionInfo>* outReturn) override;
    binder::Status registerClientCallback(const std::string& name, const sp<IBinder>& service,
                                          const sp<IClientCallback>& cb) override;
    binder::Status tryUnregisterService(const std::string& name, const sp<IBinder>& binder) override;
+1 −0
Original line number Diff line number Diff line
@@ -284,6 +284,7 @@ cc_library_static {
filegroup {
    name: "libbinder_aidl",
    srcs: [
        "aidl/android/os/ConnectionInfo.aidl",
        "aidl/android/os/IClientCallback.aidl",
        "aidl/android/os/IServiceCallback.aidl",
        "aidl/android/os/IServiceManager.aidl",
+16 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ public:
    bool isDeclared(const String16& name) override;
    Vector<String16> getDeclaredInstances(const String16& interface) override;
    std::optional<String16> updatableViaApex(const String16& name) override;
    std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override;

    // for legacy ABI
    const String16& getInterfaceDescriptor() const override {
@@ -426,6 +427,21 @@ std::optional<String16> ServiceManagerShim::updatableViaApex(const String16& nam
    return declared ? std::optional<String16>(String16(declared.value().c_str())) : std::nullopt;
}

std::optional<IServiceManager::ConnectionInfo> ServiceManagerShim::getConnectionInfo(
        const String16& name) {
    std::optional<os::ConnectionInfo> connectionInfo;
    if (Status status =
                mTheRealServiceManager->getConnectionInfo(String8(name).c_str(), &connectionInfo);
        !status.isOk()) {
        ALOGW("Failed to get ConnectionInfo for %s: %s", String8(name).c_str(),
              status.toString8().c_str());
    }
    return connectionInfo.has_value()
            ? std::make_optional<IServiceManager::ConnectionInfo>(
                      {connectionInfo->ipAddress, static_cast<unsigned int>(connectionInfo->port)})
            : std::nullopt;
}

#ifndef __ANDROID__
// ServiceManagerShim for host. Implements the old libbinder android::IServiceManager API.
// The internal implementation of the AIDL interface android::os::IServiceManager calls into
Loading