summaryrefslogtreecommitdiff
path: root/libs/binder/IServiceManager.cpp
diff options
context:
space:
mode:
author Devin Moore <devinmoore@google.com> 2024-08-09 23:18:05 +0000
committer Devin Moore <devinmoore@google.com> 2024-09-24 21:52:14 +0000
commitc370db498194e22bf1499cb5d1c834a79e3ee776 (patch)
treea0019eb9aada15130ae93d6178af79baa680322f /libs/binder/IServiceManager.cpp
parentdaa348c072c8454966f67f430e83c6774c59d8e6 (diff)
Add libbinder_ndk systemapi support for injecting RPC binder accessors
This allows libbinder_ndk to set up client connections to binder RPC services underneath the libbinder_ndk service manager APIs. It requires callbacks to be added to the local process to get connection information that the client is responsible for obtaining. Once these callbacks are added to libbinder, any client elswhere in the process using the service manager APIs will be able to get and use a binder for the service in the same way they do for kernel binder services. Test: atest binderRpcTest vm_accessor_test Bug: 358427181 Change-Id: I528e84bac40efe13884a68ed851ecfb14dd27daa
Diffstat (limited to 'libs/binder/IServiceManager.cpp')
-rw-r--r--libs/binder/IServiceManager.cpp44
1 files changed, 38 insertions, 6 deletions
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 88761d772f..77b80ef3de 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -157,12 +157,21 @@ protected:
class AccessorProvider {
public:
- AccessorProvider(RpcAccessorProvider&& provider) : mProvider(std::move(provider)) {}
- sp<IBinder> provide(const String16& name) { return mProvider(name); }
+ AccessorProvider(std::set<std::string>&& instances, RpcAccessorProvider&& provider)
+ : mInstances(std::move(instances)), mProvider(std::move(provider)) {}
+ sp<IBinder> provide(const String16& name) {
+ if (mInstances.count(String8(name).c_str()) > 0) {
+ return mProvider(name);
+ } else {
+ return nullptr;
+ }
+ }
+ const std::set<std::string>& instances() { return mInstances; }
private:
AccessorProvider() = delete;
+ std::set<std::string> mInstances;
RpcAccessorProvider mProvider;
};
@@ -318,10 +327,32 @@ sp<IServiceManager> getServiceManagerShimFromAidlServiceManagerForTests(
return sp<CppBackendShim>::make(sp<BackendUnifiedServiceManager>::make(sm));
}
-std::weak_ptr<AccessorProvider> addAccessorProvider(RpcAccessorProvider&& providerCallback) {
+// gAccessorProvidersMutex must be locked already
+static bool isInstanceProvidedLocked(const std::string& instance) {
+ return gAccessorProviders.end() !=
+ std::find_if(gAccessorProviders.begin(), gAccessorProviders.end(),
+ [&instance](const AccessorProviderEntry& entry) {
+ return entry.mProvider->instances().count(instance) > 0;
+ });
+}
+
+std::weak_ptr<AccessorProvider> addAccessorProvider(std::set<std::string>&& instances,
+ RpcAccessorProvider&& providerCallback) {
+ if (instances.empty()) {
+ ALOGE("Set of instances is empty! Need a non empty set of instances to provide for.");
+ return std::weak_ptr<AccessorProvider>();
+ }
std::lock_guard<std::mutex> lock(gAccessorProvidersMutex);
+ for (const auto& instance : instances) {
+ if (isInstanceProvidedLocked(instance)) {
+ ALOGE("The instance %s is already provided for by a previously added "
+ "RpcAccessorProvider.",
+ instance.c_str());
+ return std::weak_ptr<AccessorProvider>();
+ }
+ }
std::shared_ptr<AccessorProvider> provider =
- std::make_shared<AccessorProvider>(std::move(providerCallback));
+ std::make_shared<AccessorProvider>(std::move(instances), std::move(providerCallback));
std::weak_ptr<AccessorProvider> receipt = provider;
gAccessorProviders.push_back(AccessorProviderEntry(std::move(provider)));
@@ -331,8 +362,9 @@ std::weak_ptr<AccessorProvider> addAccessorProvider(RpcAccessorProvider&& provid
status_t removeAccessorProvider(std::weak_ptr<AccessorProvider> wProvider) {
std::shared_ptr<AccessorProvider> provider = wProvider.lock();
if (provider == nullptr) {
- ALOGE("The provider supplied to removeAccessorProvider has already been removed.");
- return NAME_NOT_FOUND;
+ ALOGE("The provider supplied to removeAccessorProvider has already been removed or the "
+ "argument to this function was nullptr.");
+ return BAD_VALUE;
}
std::lock_guard<std::mutex> lock(gAccessorProvidersMutex);
size_t sizeBefore = gAccessorProviders.size();