diff options
author | Steven Moreland <smoreland@google.com> | 2019-10-07 16:24:33 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2019-10-07 16:24:33 +0000 |
commit | b51de829b60b495518f0577aa1617284e6582e59 (patch) | |
tree | db1060121a15d2fec88dad1b0c6f2e587f3a3118 | |
parent | 409e34c8814334f1d9d9c5aaad465c3d905c374f (diff) | |
parent | 583685ed725d8e97aa99117b903b5453c871beef (diff) | |
download | native-b51de829b60b495518f0577aa1617284e6582e59.tar.gz |
Merge "IServiceManager: no DECLARE_META_INTERFACE"
-rw-r--r-- | libs/binder/IServiceManager.cpp | 251 | ||||
-rw-r--r-- | libs/binder/include/binder/IServiceManager.h | 12 |
2 files changed, 149 insertions, 114 deletions
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index 4bea217930..a30df14bd6 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -54,6 +54,36 @@ static_assert(AidlServiceManager::DUMP_FLAG_PRIORITY_DEFAULT == IServiceManager: static_assert(AidlServiceManager::DUMP_FLAG_PRIORITY_ALL == IServiceManager::DUMP_FLAG_PRIORITY_ALL); static_assert(AidlServiceManager::DUMP_FLAG_PROTO == IServiceManager::DUMP_FLAG_PROTO); +const String16& IServiceManager::getInterfaceDescriptor() const { + return AidlServiceManager::descriptor; +} +IServiceManager::IServiceManager() {} +IServiceManager::~IServiceManager() {} + +// From the old libbinder IServiceManager interface to IServiceManager. +class ServiceManagerShim : public IServiceManager +{ +public: + explicit ServiceManagerShim (const sp<AidlServiceManager>& impl); + + sp<IBinder> getService(const String16& name) const override; + sp<IBinder> checkService(const String16& name) const override; + status_t addService(const String16& name, const sp<IBinder>& service, + bool allowIsolated, int dumpsysPriority) override; + Vector<String16> listServices(int dumpsysPriority) override; + sp<IBinder> waitForService(const String16& name16) override; + + // for legacy ABI + const String16& getInterfaceDescriptor() const override { + return mTheRealServiceManager->getInterfaceDescriptor(); + } + IBinder* onAsBinder() override { + return IInterface::asBinder(mTheRealServiceManager).get(); + } +private: + sp<AidlServiceManager> mTheRealServiceManager; +}; + sp<IServiceManager> defaultServiceManager() { static Mutex gDefaultServiceManagerLock; @@ -64,8 +94,9 @@ sp<IServiceManager> defaultServiceManager() { AutoMutex _l(gDefaultServiceManagerLock); while (gDefaultServiceManager == nullptr) { - gDefaultServiceManager = interface_cast<IServiceManager>( - ProcessState::self()->getContextObject(nullptr)); + gDefaultServiceManager = new ServiceManagerShim( + interface_cast<AidlServiceManager>( + ProcessState::self()->getContextObject(nullptr))); if (gDefaultServiceManager == nullptr) sleep(1); } @@ -158,142 +189,136 @@ bool checkPermission(const String16& permission, pid_t pid, uid_t uid) // ---------------------------------------------------------------------- -class BpServiceManager : public BpInterface<IServiceManager> +ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl) + : mTheRealServiceManager(impl) +{} + +sp<IBinder> ServiceManagerShim::getService(const String16& name) const { -public: - explicit BpServiceManager(const sp<IBinder>& impl) - : BpInterface<IServiceManager>(impl), - mTheRealServiceManager(interface_cast<AidlServiceManager>(impl)) - { + static bool gSystemBootCompleted = false; + + sp<IBinder> svc = checkService(name); + if (svc != nullptr) return svc; + + const bool isVendorService = + strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0; + const long timeout = uptimeMillis() + 5000; + // Vendor code can't access system properties + if (!gSystemBootCompleted && !isVendorService) { +#ifdef __ANDROID__ + char bootCompleted[PROPERTY_VALUE_MAX]; + property_get("sys.boot_completed", bootCompleted, "0"); + gSystemBootCompleted = strcmp(bootCompleted, "1") == 0 ? true : false; +#else + gSystemBootCompleted = true; +#endif } + // retry interval in millisecond; note that vendor services stay at 100ms + const long sleepTime = gSystemBootCompleted ? 1000 : 100; - sp<IBinder> getService(const String16& name) const override - { - static bool gSystemBootCompleted = false; + int n = 0; + while (uptimeMillis() < timeout) { + n++; + ALOGI("Waiting for service '%s' on '%s'...", String8(name).string(), + ProcessState::self()->getDriverName().c_str()); + usleep(1000*sleepTime); sp<IBinder> svc = checkService(name); if (svc != nullptr) return svc; + } + ALOGW("Service %s didn't start. Returning NULL", String8(name).string()); + return nullptr; +} - const bool isVendorService = - strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0; - const long timeout = uptimeMillis() + 5000; - // Vendor code can't access system properties - if (!gSystemBootCompleted && !isVendorService) { -#ifdef __ANDROID__ - char bootCompleted[PROPERTY_VALUE_MAX]; - property_get("sys.boot_completed", bootCompleted, "0"); - gSystemBootCompleted = strcmp(bootCompleted, "1") == 0 ? true : false; -#else - gSystemBootCompleted = true; -#endif - } - // retry interval in millisecond; note that vendor services stay at 100ms - const long sleepTime = gSystemBootCompleted ? 1000 : 100; - - int n = 0; - while (uptimeMillis() < timeout) { - n++; - ALOGI("Waiting for service '%s' on '%s'...", String8(name).string(), - ProcessState::self()->getDriverName().c_str()); - usleep(1000*sleepTime); - - sp<IBinder> svc = checkService(name); - if (svc != nullptr) return svc; - } - ALOGW("Service %s didn't start. Returning NULL", String8(name).string()); +sp<IBinder> ServiceManagerShim::checkService(const String16& name) const +{ + sp<IBinder> ret; + if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) { return nullptr; } + return ret; +} - sp<IBinder> checkService(const String16& name) const override { - sp<IBinder> ret; - if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) { - return nullptr; - } - return ret; +status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service, + bool allowIsolated, int dumpsysPriority) +{ + Status status = mTheRealServiceManager->addService( + String8(name).c_str(), service, allowIsolated, dumpsysPriority); + return status.exceptionCode(); +} + +Vector<String16> ServiceManagerShim::listServices(int dumpsysPriority) +{ + std::vector<std::string> ret; + if (!mTheRealServiceManager->listServices(dumpsysPriority, &ret).isOk()) { + return {}; } - status_t addService(const String16& name, const sp<IBinder>& service, - bool allowIsolated, int dumpsysPriority) override { - Status status = mTheRealServiceManager->addService(String8(name).c_str(), service, allowIsolated, dumpsysPriority); - return status.exceptionCode(); + Vector<String16> res; + res.setCapacity(ret.size()); + for (const std::string& name : ret) { + res.push(String16(name.c_str())); } + return res; +} - virtual Vector<String16> listServices(int dumpsysPriority) { - std::vector<std::string> ret; - if (!mTheRealServiceManager->listServices(dumpsysPriority, &ret).isOk()) { - return {}; +sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) +{ + class Waiter : public android::os::BnServiceCallback { + Status onRegistration(const std::string& /*name*/, + const sp<IBinder>& binder) override { + std::unique_lock<std::mutex> lock(mMutex); + mBinder = binder; + lock.unlock(); + mCv.notify_one(); + return Status::ok(); } + public: + sp<IBinder> mBinder; + std::mutex mMutex; + std::condition_variable mCv; + }; - Vector<String16> res; - res.setCapacity(ret.size()); - for (const std::string& name : ret) { - res.push(String16(name.c_str())); - } - return res; + const std::string name = String8(name16).c_str(); + + sp<IBinder> out; + if (!mTheRealServiceManager->getService(name, &out).isOk()) { + return nullptr; } + if(out != nullptr) return out; - sp<IBinder> waitForService(const String16& name16) override { - class Waiter : public android::os::BnServiceCallback { - Status onRegistration(const std::string& /*name*/, - const sp<IBinder>& binder) override { - std::unique_lock<std::mutex> lock(mMutex); - mBinder = binder; - lock.unlock(); - mCv.notify_one(); - return Status::ok(); - } - public: - sp<IBinder> mBinder; - std::mutex mMutex; - std::condition_variable mCv; - }; + sp<Waiter> waiter = new Waiter; + if (!mTheRealServiceManager->registerForNotifications( + name, waiter).isOk()) { + return nullptr; + } - const std::string name = String8(name16).c_str(); + while(true) { + { + std::unique_lock<std::mutex> lock(waiter->mMutex); + using std::literals::chrono_literals::operator""s; + waiter->mCv.wait_for(lock, 1s, [&] { + return waiter->mBinder != nullptr; + }); + if (waiter->mBinder != nullptr) return waiter->mBinder; + } - sp<IBinder> out; + // Handle race condition for lazy services. Here is what can happen: + // - the service dies (not processed by init yet). + // - sm processes death notification. + // - sm gets getService and calls init to start service. + // - init gets the start signal, but the service already appears + // started, so it does nothing. + // - 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 (!mTheRealServiceManager->getService(name, &out).isOk()) { return nullptr; } if(out != nullptr) return out; - sp<Waiter> waiter = new Waiter; - if (!mTheRealServiceManager->registerForNotifications( - name, waiter).isOk()) { - return nullptr; - } - - while(true) { - { - std::unique_lock<std::mutex> lock(waiter->mMutex); - using std::literals::chrono_literals::operator""s; - waiter->mCv.wait_for(lock, 1s, [&] { - return waiter->mBinder != nullptr; - }); - if (waiter->mBinder != nullptr) return waiter->mBinder; - } - - // Handle race condition for lazy services. Here is what can happen: - // - the service dies (not processed by init yet). - // - sm processes death notification. - // - sm gets getService and calls init to start service. - // - init gets the start signal, but the service already appears - // started, so it does nothing. - // - 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 (!mTheRealServiceManager->getService(name, &out).isOk()) { - return nullptr; - } - if(out != nullptr) return out; - - ALOGW("Waited one second for %s", name.c_str()); - } + ALOGW("Waited one second for %s", name.c_str()); } - -private: - sp<AidlServiceManager> mTheRealServiceManager; -}; - -IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager"); +} } // namespace android diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h index cd63a58bce..a675513793 100644 --- a/libs/binder/include/binder/IServiceManager.h +++ b/libs/binder/include/binder/IServiceManager.h @@ -26,10 +26,20 @@ namespace android { // ---------------------------------------------------------------------- +/** + * Service manager for C++ services. + * + * IInterface is only for legacy ABI compatibility + */ class IServiceManager : public IInterface { public: - DECLARE_META_INTERFACE(ServiceManager) + // for ABI compatibility + virtual const String16& getInterfaceDescriptor() const; + + IServiceManager(); + virtual ~IServiceManager(); + /** * Must match values in IServiceManager.aidl */ |