diff options
Diffstat (limited to 'cmds/servicemanager/ServiceManager.cpp')
| -rw-r--r-- | cmds/servicemanager/ServiceManager.cpp | 56 | 
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  |