From 18f63759c833fe73c2323a5f2c5637b8c93ac8a3 Mon Sep 17 00:00:00 2001 From: Devin Moore Date: Thu, 8 Aug 2024 21:01:24 +0000 Subject: Add support for injecting RPC binder accessors to libbinder This allows libbinder to set up client connections to binder RPC services underneath the libbinder 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: Iec27d30a669e0673bd66c99fded1edc335f7dff1 --- libs/binder/BackendUnifiedServiceManager.cpp | 46 +++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 8 deletions(-) (limited to 'libs/binder/BackendUnifiedServiceManager.cpp') diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp index 54f687b280..fee36da911 100644 --- a/libs/binder/BackendUnifiedServiceManager.cpp +++ b/libs/binder/BackendUnifiedServiceManager.cpp @@ -46,7 +46,9 @@ binder::Status BackendUnifiedServiceManager::getService2(const ::std::string& na os::Service* _out) { os::Service service; binder::Status status = mTheRealServiceManager->getService2(name, &service); - toBinderService(service, _out); + if (status.isOk()) { + return toBinderService(name, service, _out); + } return status; } @@ -54,15 +56,38 @@ binder::Status BackendUnifiedServiceManager::checkService(const ::std::string& n os::Service* _out) { os::Service service; binder::Status status = mTheRealServiceManager->checkService(name, &service); - toBinderService(service, _out); + if (status.isOk()) { + return toBinderService(name, service, _out); + } return status; } -void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Service* _out) { +binder::Status BackendUnifiedServiceManager::toBinderService(const ::std::string& name, + const os::Service& in, + os::Service* _out) { switch (in.getTag()) { case os::Service::Tag::binder: { + if (in.get() == nullptr) { + // failed to find a service. Check to see if we have any local + // injected Accessors for this service. + os::Service accessor; + binder::Status status = getInjectedAccessor(name, &accessor); + if (!status.isOk()) { + *_out = os::Service::make(nullptr); + return status; + } + if (accessor.getTag() == os::Service::Tag::accessor && + accessor.get() != nullptr) { + ALOGI("Found local injected service for %s, will attempt to create connection", + name.c_str()); + // Call this again using the accessor Service to get the real + // service's binder into _out + return toBinderService(name, accessor, _out); + } + } + *_out = in; - break; + return binder::Status::ok(); } case os::Service::Tag::accessor: { sp accessorBinder = in.get(); @@ -70,7 +95,7 @@ void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Se if (accessor == nullptr) { ALOGE("Service#accessor doesn't have accessor. VM is maybe starting..."); *_out = os::Service::make(nullptr); - break; + return binder::Status::ok(); } auto request = [=] { os::ParcelFileDescriptor fd; @@ -83,10 +108,15 @@ void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Se } }; auto session = RpcSession::make(); - session->setupPreconnectedClient(base::unique_fd{}, request); + status_t status = session->setupPreconnectedClient(base::unique_fd{}, request); + if (status != OK) { + ALOGE("Failed to set up preconnected binder RPC client: %s", + statusToString(status).c_str()); + return binder::Status::fromStatusT(status); + } session->setSessionSpecificRoot(accessorBinder); *_out = os::Service::make(session->getRootObject()); - break; + return binder::Status::ok(); } default: { LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag()); @@ -177,4 +207,4 @@ sp getBackendUnifiedServiceManager() { return gUnifiedServiceManager; } -} // namespace android \ No newline at end of file +} // namespace android -- cgit v1.2.3-59-g8ed1b