summaryrefslogtreecommitdiff
path: root/cmds/servicemanager/ServiceManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/servicemanager/ServiceManager.cpp')
-rw-r--r--cmds/servicemanager/ServiceManager.cpp56
1 files changed, 36 insertions, 20 deletions
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index b3aa342a19..463d67f945 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -17,8 +17,10 @@
#include "ServiceManager.h"
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <cutils/android_filesystem_config.h>
#include <cutils/multiuser.h>
+#include <thread>
using ::android::binder::Status;
@@ -41,39 +43,44 @@ ServiceManager::~ServiceManager() {
}
Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
- // Servicemanager is single-threaded and cannot block. This method exists for legacy reasons.
- return checkService(name, outBinder);
+ *outBinder = tryGetService(name, true);
+ // returns ok regardless of result for legacy reasons
+ return Status::ok();
}
Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
- auto ctx = mAccess->getCallingContext();
+ *outBinder = tryGetService(name, false);
+ // returns ok regardless of result for legacy reasons
+ return Status::ok();
+}
- auto it = mNameToService.find(name);
- if (it == mNameToService.end()) {
- *outBinder = nullptr;
- return Status::ok();
- }
+sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
+ auto ctx = mAccess->getCallingContext();
- const Service& service = it->second;
+ sp<IBinder> out;
+ if (auto it = mNameToService.find(name); it != mNameToService.end()) {
+ const Service& service = it->second;
- if (!service.allowIsolated) {
- uid_t appid = multiuser_get_app_id(ctx.uid);
- bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
+ if (!service.allowIsolated) {
+ uid_t appid = multiuser_get_app_id(ctx.uid);
+ bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
- if (isIsolated) {
- *outBinder = nullptr;
- return Status::ok();
+ if (isIsolated) {
+ return nullptr;
+ }
}
+ out = service.binder;
}
if (!mAccess->canFind(ctx, name)) {
- // returns ok and null for legacy reasons
- *outBinder = nullptr;
- return Status::ok();
+ return nullptr;
}
- *outBinder = service.binder;
- return Status::ok();
+ if (!out && startIfNotFound) {
+ tryStartService(name);
+ }
+
+ return out;
}
bool isValidServiceName(const std::string& name) {
@@ -253,4 +260,13 @@ void ServiceManager::binderDied(const wp<IBinder>& who) {
}
}
+void ServiceManager::tryStartService(const std::string& name) {
+ ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service",
+ name.c_str());
+
+ std::thread([=] {
+ (void)base::SetProperty("ctl.interface_start", "aidl/" + name);
+ }).detach();
+}
+
} // namespace android