Skip to content

Commit c370db4

Browse files
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
1 parent daa348c commit c370db4

8 files changed

Lines changed: 1017 additions & 37 deletions

File tree

libs/binder/IServiceManager.cpp

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,21 @@ class CppBackendShim : public IServiceManager {
157157

158158
class AccessorProvider {
159159
public:
160-
AccessorProvider(RpcAccessorProvider&& provider) : mProvider(std::move(provider)) {}
161-
sp<IBinder> provide(const String16& name) { return mProvider(name); }
160+
AccessorProvider(std::set<std::string>&& instances, RpcAccessorProvider&& provider)
161+
: mInstances(std::move(instances)), mProvider(std::move(provider)) {}
162+
sp<IBinder> provide(const String16& name) {
163+
if (mInstances.count(String8(name).c_str()) > 0) {
164+
return mProvider(name);
165+
} else {
166+
return nullptr;
167+
}
168+
}
169+
const std::set<std::string>& instances() { return mInstances; }
162170

163171
private:
164172
AccessorProvider() = delete;
165173

174+
std::set<std::string> mInstances;
166175
RpcAccessorProvider mProvider;
167176
};
168177

@@ -318,10 +327,32 @@ sp<IServiceManager> getServiceManagerShimFromAidlServiceManagerForTests(
318327
return sp<CppBackendShim>::make(sp<BackendUnifiedServiceManager>::make(sm));
319328
}
320329

321-
std::weak_ptr<AccessorProvider> addAccessorProvider(RpcAccessorProvider&& providerCallback) {
330+
// gAccessorProvidersMutex must be locked already
331+
static bool isInstanceProvidedLocked(const std::string& instance) {
332+
return gAccessorProviders.end() !=
333+
std::find_if(gAccessorProviders.begin(), gAccessorProviders.end(),
334+
[&instance](const AccessorProviderEntry& entry) {
335+
return entry.mProvider->instances().count(instance) > 0;
336+
});
337+
}
338+
339+
std::weak_ptr<AccessorProvider> addAccessorProvider(std::set<std::string>&& instances,
340+
RpcAccessorProvider&& providerCallback) {
341+
if (instances.empty()) {
342+
ALOGE("Set of instances is empty! Need a non empty set of instances to provide for.");
343+
return std::weak_ptr<AccessorProvider>();
344+
}
322345
std::lock_guard<std::mutex> lock(gAccessorProvidersMutex);
346+
for (const auto& instance : instances) {
347+
if (isInstanceProvidedLocked(instance)) {
348+
ALOGE("The instance %s is already provided for by a previously added "
349+
"RpcAccessorProvider.",
350+
instance.c_str());
351+
return std::weak_ptr<AccessorProvider>();
352+
}
353+
}
323354
std::shared_ptr<AccessorProvider> provider =
324-
std::make_shared<AccessorProvider>(std::move(providerCallback));
355+
std::make_shared<AccessorProvider>(std::move(instances), std::move(providerCallback));
325356
std::weak_ptr<AccessorProvider> receipt = provider;
326357
gAccessorProviders.push_back(AccessorProviderEntry(std::move(provider)));
327358

@@ -331,8 +362,9 @@ std::weak_ptr<AccessorProvider> addAccessorProvider(RpcAccessorProvider&& provid
331362
status_t removeAccessorProvider(std::weak_ptr<AccessorProvider> wProvider) {
332363
std::shared_ptr<AccessorProvider> provider = wProvider.lock();
333364
if (provider == nullptr) {
334-
ALOGE("The provider supplied to removeAccessorProvider has already been removed.");
335-
return NAME_NOT_FOUND;
365+
ALOGE("The provider supplied to removeAccessorProvider has already been removed or the "
366+
"argument to this function was nullptr.");
367+
return BAD_VALUE;
336368
}
337369
std::lock_guard<std::mutex> lock(gAccessorProvidersMutex);
338370
size_t sizeBefore = gAccessorProviders.size();

libs/binder/include/binder/IServiceManager.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <utils/String16.h>
2525
#include <utils/Vector.h>
2626
#include <optional>
27+
#include <set>
2728

2829
namespace android {
2930

@@ -224,20 +225,36 @@ LIBBINDER_EXPORTED bool checkPermission(const String16& permission, pid_t pid, u
224225
typedef std::function<status_t(const String16& name, sockaddr* outAddr, socklen_t addrSize)>
225226
RpcSocketAddressProvider;
226227

227-
typedef std::function<sp<IBinder>(const String16& name)> RpcAccessorProvider;
228+
/**
229+
* This callback provides a way for clients to get access to remote services by
230+
* providing an Accessor object from libbinder that can connect to the remote
231+
* service over sockets.
232+
*
233+
* \param instance name of the service that the callback will provide an
234+
* Accessor for. The provided accessor will be used to set up a client
235+
* RPC connection in libbinder in order to return a binder for the
236+
* associated remote service.
237+
*
238+
* \return IBinder of the Accessor object that libbinder implements.
239+
* nullptr if the provider callback doesn't know how to reach the
240+
* service or doesn't want to provide access for any other reason.
241+
*/
242+
typedef std::function<sp<IBinder>(const String16& instance)> RpcAccessorProvider;
228243

229244
class AccessorProvider;
230245

231246
/**
232-
* Register an accessor provider for the service manager APIs.
247+
* Register a RpcAccessorProvider for the service manager APIs.
233248
*
249+
* \param instances that the RpcAccessorProvider knows about and can provide an
250+
* Accessor for.
234251
* \param provider callback that generates Accessors.
235252
*
236253
* \return A pointer used as a recept for the successful addition of the
237254
* AccessorProvider. This is needed to unregister it later.
238255
*/
239256
[[nodiscard]] LIBBINDER_EXPORTED std::weak_ptr<AccessorProvider> addAccessorProvider(
240-
RpcAccessorProvider&& providerCallback);
257+
std::set<std::string>&& instances, RpcAccessorProvider&& providerCallback);
241258

242259
/**
243260
* Remove an accessor provider using the pointer provided by addAccessorProvider

libs/binder/ndk/Android.bp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ cc_library {
9595
"persistable_bundle.cpp",
9696
"process.cpp",
9797
"service_manager.cpp",
98+
"binder_rpc.cpp",
9899
],
99100

100101
static_libs: [

0 commit comments

Comments
 (0)