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
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 88761d7..77b80ef 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -157,12 +157,21 @@
 
 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 @@
     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 @@
 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();