From 583685ed725d8e97aa99117b903b5453c871beef Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Wed, 2 Oct 2019 16:45:11 -0700 Subject: IServiceManager: no DECLARE_META_INTERFACE Since this is no longer implementing a binder interface. We declare functions required to avoid ABI breaking changes but otherwise minimize the API. Bug: 135768100 Test: boot Change-Id: I4dfbfdeaf981c1bcf6e5c5fba82b384f08bf4b76 --- libs/binder/IServiceManager.cpp | 251 ++++++++++++++++++++++------------------ 1 file changed, 138 insertions(+), 113 deletions(-) (limited to 'libs/binder/IServiceManager.cpp') 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& impl); + + sp getService(const String16& name) const override; + sp checkService(const String16& name) const override; + status_t addService(const String16& name, const sp& service, + bool allowIsolated, int dumpsysPriority) override; + Vector listServices(int dumpsysPriority) override; + sp 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 mTheRealServiceManager; +}; + sp defaultServiceManager() { static Mutex gDefaultServiceManagerLock; @@ -64,8 +94,9 @@ sp defaultServiceManager() { AutoMutex _l(gDefaultServiceManagerLock); while (gDefaultServiceManager == nullptr) { - gDefaultServiceManager = interface_cast( - ProcessState::self()->getContextObject(nullptr)); + gDefaultServiceManager = new ServiceManagerShim( + interface_cast( + 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 +ServiceManagerShim::ServiceManagerShim(const sp& impl) + : mTheRealServiceManager(impl) +{} + +sp ServiceManagerShim::getService(const String16& name) const { -public: - explicit BpServiceManager(const sp& impl) - : BpInterface(impl), - mTheRealServiceManager(interface_cast(impl)) - { + static bool gSystemBootCompleted = false; + + sp 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 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 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 svc = checkService(name); - if (svc != nullptr) return svc; - } - ALOGW("Service %s didn't start. Returning NULL", String8(name).string()); +sp ServiceManagerShim::checkService(const String16& name) const +{ + sp ret; + if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) { return nullptr; } + return ret; +} - sp checkService(const String16& name) const override { - sp ret; - if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) { - return nullptr; - } - return ret; +status_t ServiceManagerShim::addService(const String16& name, const sp& service, + bool allowIsolated, int dumpsysPriority) +{ + Status status = mTheRealServiceManager->addService( + String8(name).c_str(), service, allowIsolated, dumpsysPriority); + return status.exceptionCode(); +} + +Vector ServiceManagerShim::listServices(int dumpsysPriority) +{ + std::vector ret; + if (!mTheRealServiceManager->listServices(dumpsysPriority, &ret).isOk()) { + return {}; } - status_t addService(const String16& name, const sp& service, - bool allowIsolated, int dumpsysPriority) override { - Status status = mTheRealServiceManager->addService(String8(name).c_str(), service, allowIsolated, dumpsysPriority); - return status.exceptionCode(); + Vector res; + res.setCapacity(ret.size()); + for (const std::string& name : ret) { + res.push(String16(name.c_str())); } + return res; +} - virtual Vector listServices(int dumpsysPriority) { - std::vector ret; - if (!mTheRealServiceManager->listServices(dumpsysPriority, &ret).isOk()) { - return {}; +sp ServiceManagerShim::waitForService(const String16& name16) +{ + class Waiter : public android::os::BnServiceCallback { + Status onRegistration(const std::string& /*name*/, + const sp& binder) override { + std::unique_lock lock(mMutex); + mBinder = binder; + lock.unlock(); + mCv.notify_one(); + return Status::ok(); } + public: + sp mBinder; + std::mutex mMutex; + std::condition_variable mCv; + }; - Vector 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 out; + if (!mTheRealServiceManager->getService(name, &out).isOk()) { + return nullptr; } + if(out != nullptr) return out; - sp waitForService(const String16& name16) override { - class Waiter : public android::os::BnServiceCallback { - Status onRegistration(const std::string& /*name*/, - const sp& binder) override { - std::unique_lock lock(mMutex); - mBinder = binder; - lock.unlock(); - mCv.notify_one(); - return Status::ok(); - } - public: - sp mBinder; - std::mutex mMutex; - std::condition_variable mCv; - }; + sp waiter = new Waiter; + if (!mTheRealServiceManager->registerForNotifications( + name, waiter).isOk()) { + return nullptr; + } - const std::string name = String8(name16).c_str(); + while(true) { + { + std::unique_lock 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 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 = new Waiter; - if (!mTheRealServiceManager->registerForNotifications( - name, waiter).isOk()) { - return nullptr; - } - - while(true) { - { - std::unique_lock 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 mTheRealServiceManager; -}; - -IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager"); +} } // namespace android -- cgit v1.2.3-59-g8ed1b