From c370db498194e22bf1499cb5d1c834a79e3ee776 Mon Sep 17 00:00:00 2001 From: Devin Moore Date: Fri, 9 Aug 2024 23:18:05 +0000 Subject: 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 --- libs/binder/IServiceManager.cpp | 44 +++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) (limited to 'libs/binder/IServiceManager.cpp') 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 provide(const String16& name) { return mProvider(name); } + AccessorProvider(std::set&& instances, RpcAccessorProvider&& provider) + : mInstances(std::move(instances)), mProvider(std::move(provider)) {} + sp provide(const String16& name) { + if (mInstances.count(String8(name).c_str()) > 0) { + return mProvider(name); + } else { + return nullptr; + } + } + const std::set& instances() { return mInstances; } private: AccessorProvider() = delete; + std::set mInstances; RpcAccessorProvider mProvider; }; @@ -318,10 +327,32 @@ sp getServiceManagerShimFromAidlServiceManagerForTests( return sp::make(sp::make(sm)); } -std::weak_ptr 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 addAccessorProvider(std::set&& 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(); + } std::lock_guard 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(); + } + } std::shared_ptr provider = - std::make_shared(std::move(providerCallback)); + std::make_shared(std::move(instances), std::move(providerCallback)); std::weak_ptr receipt = provider; gAccessorProviders.push_back(AccessorProviderEntry(std::move(provider))); @@ -331,8 +362,9 @@ std::weak_ptr addAccessorProvider(RpcAccessorProvider&& provid status_t removeAccessorProvider(std::weak_ptr wProvider) { std::shared_ptr 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 lock(gAccessorProvidersMutex); size_t sizeBefore = gAccessorProviders.size(); -- cgit v1.2.3-59-g8ed1b