summaryrefslogtreecommitdiff
path: root/libs/binder/BackendUnifiedServiceManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/binder/BackendUnifiedServiceManager.cpp')
-rw-r--r--libs/binder/BackendUnifiedServiceManager.cpp46
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