diff options
Diffstat (limited to 'libs/binder/BackendUnifiedServiceManager.cpp')
-rw-r--r-- | libs/binder/BackendUnifiedServiceManager.cpp | 46 |
1 files changed, 38 insertions, 8 deletions
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<os::Service::Tag::binder>() == 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<os::Service::Tag::binder>(nullptr); + return status; + } + if (accessor.getTag() == os::Service::Tag::accessor && + accessor.get<os::Service::Tag::accessor>() != 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<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>(); @@ -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<os::Service::Tag::binder>(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<os::Service::Tag::binder>(session->getRootObject()); - break; + return binder::Status::ok(); } default: { LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag()); @@ -177,4 +207,4 @@ sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() { return gUnifiedServiceManager; } -} // namespace android
\ No newline at end of file +} // namespace android |