Merge "Add getConnectionInfo API to service manager"
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index fa63db5..677d6c7 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -60,6 +60,7 @@
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*());
};
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 90db509..4e44ac7 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -121,6 +121,35 @@
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 @@
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) {
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 4f23c21..5e40319 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -24,6 +24,7 @@
namespace android {
+using os::ConnectionInfo;
using os::IClientCallback;
using os::IServiceCallback;
using os::ServiceDebugInfo;
@@ -48,6 +49,8 @@
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;
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 6cb45ca..aff9e25 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -287,6 +287,7 @@
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",
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 6e318ea..aff9e0d 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -78,6 +78,7 @@
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 @@
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
diff --git a/libs/binder/aidl/android/os/ConnectionInfo.aidl b/libs/binder/aidl/android/os/ConnectionInfo.aidl
new file mode 100644
index 0000000..160c9ea
--- /dev/null
+++ b/libs/binder/aidl/android/os/ConnectionInfo.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+/**
+ * Remote connection info associated with a declared service
+ * @hide
+ */
+parcelable ConnectionInfo {
+ /**
+ * IP address that the service is listening on.
+ */
+ @utf8InCpp String ipAddress;
+ /**
+ * Port number that the service is listening on. Actual value is an unsigned integer.
+ */
+ int port;
+}
+
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 75c4092..5880c0a 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -19,6 +19,7 @@
import android.os.IClientCallback;
import android.os.IServiceCallback;
import android.os.ServiceDebugInfo;
+import android.os.ConnectionInfo;
/**
* Basic interface for finding and publishing system services.
@@ -113,6 +114,11 @@
@nullable @utf8InCpp String updatableViaApex(@utf8InCpp String name);
/**
+ * If connection info is available for the given instance, returns the ConnectionInfo
+ */
+ @nullable ConnectionInfo getConnectionInfo(@utf8InCpp String name);
+
+ /**
* Request a callback when the number of clients of the service changes.
* Used by LazyServiceRegistrar to dynamically stop services that have no clients.
*/
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index d152005..a48075d 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -15,11 +15,9 @@
*/
#pragma once
-
#include <binder/IInterface.h>
#include <utils/Vector.h>
#include <utils/String16.h>
-
#include <optional>
namespace android {
@@ -107,6 +105,16 @@
* this can be updated.
*/
virtual std::optional<String16> updatableViaApex(const String16& name) = 0;
+
+ /**
+ * If this instance has declared remote connection information, returns
+ * the ConnectionInfo.
+ */
+ struct ConnectionInfo {
+ std::string ipAddress;
+ unsigned int port;
+ };
+ virtual std::optional<ConnectionInfo> getConnectionInfo(const String16& name) = 0;
};
sp<IServiceManager> defaultServiceManager();
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
index 9811cdf..23e34aa 100644
--- a/libs/binder/servicedispatcher.cpp
+++ b/libs/binder/servicedispatcher.cpp
@@ -157,6 +157,11 @@
std::optional<std::string>* _aidl_return) override {
return mImpl->updatableViaApex(name, _aidl_return);
}
+ android::binder::Status getConnectionInfo(
+ const std::string& name,
+ std::optional<android::os::ConnectionInfo>* _aidl_return) override {
+ return mImpl->getConnectionInfo(name, _aidl_return);
+ }
android::binder::Status registerClientCallback(
const std::string&, const android::sp<android::IBinder>&,
const android::sp<android::os::IClientCallback>&) override {
diff --git a/libs/binder/tests/binderStabilityTest.cpp b/libs/binder/tests/binderStabilityTest.cpp
index 6c3b3d9..2398e1e 100644
--- a/libs/binder/tests/binderStabilityTest.cpp
+++ b/libs/binder/tests/binderStabilityTest.cpp
@@ -197,6 +197,14 @@
}
}
+TEST(BinderStability, ConnectionInfoRequiresManifestEntries) {
+ sp<IServiceManager> sm = android::defaultServiceManager();
+ sp<IBinder> systemBinder = BadStableBinder::system();
+ EXPECT_EQ(OK, sm->addService(String16("no.connection.foo"), systemBinder));
+ std::optional<android::IServiceManager::ConnectionInfo> connectionInfo;
+ connectionInfo = sm->getConnectionInfo(String16("no.connection.foo"));
+ EXPECT_EQ(connectionInfo, std::nullopt);
+}
TEST(BinderStability, CantCallVendorBinderInSystemContext) {
sp<IBinder> serverBinder = android::defaultServiceManager()->getService(kSystemStabilityServer);
auto server = interface_cast<IBinderStabilityTest>(serverBinder);
diff --git a/libs/fakeservicemanager/ServiceManager.cpp b/libs/fakeservicemanager/ServiceManager.cpp
index 761e45c..9f0754b 100644
--- a/libs/fakeservicemanager/ServiceManager.cpp
+++ b/libs/fakeservicemanager/ServiceManager.cpp
@@ -78,4 +78,10 @@
return std::nullopt;
}
+std::optional<IServiceManager::ConnectionInfo> ServiceManager::getConnectionInfo(
+ const String16& name) {
+ (void)name;
+ return std::nullopt;
+}
+
} // namespace android
diff --git a/libs/fakeservicemanager/ServiceManager.h b/libs/fakeservicemanager/ServiceManager.h
index e26c21b..b1496ba 100644
--- a/libs/fakeservicemanager/ServiceManager.h
+++ b/libs/fakeservicemanager/ServiceManager.h
@@ -51,6 +51,8 @@
std::optional<String16> updatableViaApex(const String16& name) override;
+ std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override;
+
private:
std::map<String16, sp<IBinder>> mNameToService;
};