diff options
author | 2021-06-04 16:04:42 -0700 | |
---|---|---|
committer | 2021-06-25 00:29:49 -0700 | |
commit | f7760016d3519ce324100ad0e3419baed008ffe5 (patch) | |
tree | 710e40f0fe94f253e5d374e885945b32d119cd1a /libs/binder/IServiceManager.cpp | |
parent | f2acc8dc6149e11fbf63e92977b7451417c66be3 (diff) |
Implement host service manager
On the host, after
setDefaultServiceManager(createRpcDelegateServiceManager())
is called, defaultServiceManager() will return
a service manager delegate that calls into the service
manager on the device.
Test: binderHostDeviceTest with servicedispatcher installed
Bug: 190233850
Change-Id: I44f9d2e2419883e242fea0472d702f559dd0b283
Diffstat (limited to 'libs/binder/IServiceManager.cpp')
-rw-r--r-- | libs/binder/IServiceManager.cpp | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index d421060aec..2175fd441f 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -35,6 +35,8 @@ #ifdef __ANDROID__ #include <cutils/properties.h> +#else +#include "ServiceManagerHost.h" #endif #include "Static.h" @@ -84,8 +86,19 @@ public: IBinder* onAsBinder() override { return IInterface::asBinder(mTheRealServiceManager).get(); } -private: + +protected: sp<AidlServiceManager> mTheRealServiceManager; + + // Directly get the service in a way that, for lazy services, requests the service to be started + // if it is not currently started. This way, calls directly to ServiceManagerShim::getService + // will still have the 5s delay that is expected by a large amount of Android code. + // + // When implementing ServiceManagerShim, use realGetService instead of + // mTheRealServiceManager->getService so that it can be overridden in ServiceManagerHostShim. + virtual Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) { + return mTheRealServiceManager->getService(name, _aidl_return); + } }; [[clang::no_destroy]] static std::once_flag gSmOnce; @@ -319,7 +332,7 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) const std::string name = String8(name16).c_str(); sp<IBinder> out; - if (Status status = mTheRealServiceManager->getService(name, &out); !status.isOk()) { + if (Status status = realGetService(name, &out); !status.isOk()) { ALOGW("Failed to getService in waitForService for %s: %s", name.c_str(), status.toString8().c_str()); return nullptr; @@ -363,7 +376,7 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) // - init gets death signal, but doesn't know it needs to restart // the service // - we need to request service again to get it to start - if (Status status = mTheRealServiceManager->getService(name, &out); !status.isOk()) { + if (Status status = realGetService(name, &out); !status.isOk()) { ALOGW("Failed to getService in waitForService on later try for %s: %s", name.c_str(), status.toString8().c_str()); return nullptr; @@ -412,4 +425,38 @@ std::optional<String16> ServiceManagerShim::updatableViaApex(const String16& nam return declared ? std::optional<String16>(String16(declared.value().c_str())) : std::nullopt; } +#ifndef __ANDROID__ +// ServiceManagerShim for host. Implements the old libbinder android::IServiceManager API. +// The internal implementation of the AIDL interface android::os::IServiceManager calls into +// on-device service manager. +class ServiceManagerHostShim : public ServiceManagerShim { +public: + using ServiceManagerShim::ServiceManagerShim; + // ServiceManagerShim::getService is based on checkService, so no need to override it. + sp<IBinder> checkService(const String16& name) const override { + return getDeviceService({String8(name).c_str()}); + } + +protected: + // Override realGetService for ServiceManagerShim::waitForService. + Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) { + *_aidl_return = getDeviceService({"-g", name}); + return Status::ok(); + } +}; +sp<IServiceManager> createRpcDelegateServiceManager() { + auto binder = getDeviceService({"manager"}); + if (binder == nullptr) { + ALOGE("getDeviceService(\"manager\") returns null"); + return nullptr; + } + auto interface = AidlServiceManager::asInterface(binder); + if (interface == nullptr) { + ALOGE("getDeviceService(\"manager\") returns non service manager"); + return nullptr; + } + return sp<ServiceManagerHostShim>::make(interface); +} +#endif + } // namespace android |