Loading cmds/servicemanager/ServiceManager.cpp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -532,6 +532,8 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB if (clients < 0 || clients > 2) { if (clients < 0 || clients > 2) { // client callbacks are either disabled or there are other clients // client callbacks are either disabled or there are other clients LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients; LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients; // Set this flag to ensure the clients are acknowledged in the next callback serviceIt->second.guaranteeClient = true; return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } } Loading libs/binder/LazyServiceRegistrar.cpp +31 −5 Original line number Original line Diff line number Diff line Loading @@ -31,11 +31,16 @@ using AidlServiceManager = android::os::IServiceManager; class ClientCounterCallback : public ::android::os::BnClientCallback { class ClientCounterCallback : public ::android::os::BnClientCallback { public: public: ClientCounterCallback() : mNumConnectedServices(0) {} ClientCounterCallback() : mNumConnectedServices(0), mForcePersist(false) {} bool registerService(const sp<IBinder>& service, const std::string& name, bool registerService(const sp<IBinder>& service, const std::string& name, bool allowIsolated, int dumpFlags); bool allowIsolated, int dumpFlags); /** * Set a flag to prevent services from automatically shutting down */ void forcePersist(bool persist); protected: protected: Status onClients(const sp<IBinder>& service, bool clients) override; Status onClients(const sp<IBinder>& service, bool clients) override; Loading @@ -60,6 +65,8 @@ private: * Map of registered names and services * Map of registered names and services */ */ std::map<std::string, Service> mRegisteredServices; std::map<std::string, Service> mRegisteredServices; bool mForcePersist; }; }; bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name, bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name, Loading Loading @@ -88,6 +95,14 @@ bool ClientCounterCallback::registerService(const sp<IBinder>& service, const st return true; return true; } } void ClientCounterCallback::forcePersist(bool persist) { mForcePersist = persist; if(!mForcePersist) { // Attempt a shutdown in case the number of clients hit 0 while the flag was on tryShutdown(); } } /** /** * onClients is oneway, so no need to worry about multi-threading. Note that this means multiple * onClients is oneway, so no need to worry about multi-threading. Note that this means multiple * invocations could occur on different threads however. * invocations could occur on different threads however. Loading @@ -103,14 +118,21 @@ Status ClientCounterCallback::onClients(const sp<IBinder>& service, bool clients mNumConnectedServices, mRegisteredServices.size(), mNumConnectedServices, mRegisteredServices.size(), String8(service->getInterfaceDescriptor()).string(), clients); String8(service->getInterfaceDescriptor()).string(), clients); if (mNumConnectedServices == 0) { tryShutdown(); tryShutdown(); } return Status::ok(); return Status::ok(); } } void ClientCounterCallback::tryShutdown() { void ClientCounterCallback::tryShutdown() { if(mNumConnectedServices > 0) { // Should only shut down if there are no clients return; } if(mForcePersist) { ALOGI("Shutdown prevented by forcePersist override flag."); return; } ALOGI("Trying to shut down the service. No clients in use for any service in process."); ALOGI("Trying to shut down the service. No clients in use for any service in process."); auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager())); auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager())); Loading Loading @@ -165,5 +187,9 @@ status_t LazyServiceRegistrar::registerService(const sp<IBinder>& service, const return OK; return OK; } } void LazyServiceRegistrar::forcePersist(bool persist) { mClientCC->forcePersist(persist); } } // namespace hardware } // namespace hardware } // namespace android } // namespace android No newline at end of file libs/binder/include/binder/LazyServiceRegistrar.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -34,6 +34,12 @@ class LazyServiceRegistrar { const std::string& name = "default", const std::string& name = "default", bool allowIsolated = false, bool allowIsolated = false, int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT); int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT); /** * Force the service to persist, even when it has 0 clients. * If setting this flag from the server side, make sure to do so before calling registerService, * or there may be a race with the default dynamic shutdown. */ void forcePersist(bool persist); private: private: std::shared_ptr<internal::ClientCounterCallback> mClientCC; std::shared_ptr<internal::ClientCounterCallback> mClientCC; Loading Loading
cmds/servicemanager/ServiceManager.cpp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -532,6 +532,8 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB if (clients < 0 || clients > 2) { if (clients < 0 || clients > 2) { // client callbacks are either disabled or there are other clients // client callbacks are either disabled or there are other clients LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients; LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients; // Set this flag to ensure the clients are acknowledged in the next callback serviceIt->second.guaranteeClient = true; return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } } Loading
libs/binder/LazyServiceRegistrar.cpp +31 −5 Original line number Original line Diff line number Diff line Loading @@ -31,11 +31,16 @@ using AidlServiceManager = android::os::IServiceManager; class ClientCounterCallback : public ::android::os::BnClientCallback { class ClientCounterCallback : public ::android::os::BnClientCallback { public: public: ClientCounterCallback() : mNumConnectedServices(0) {} ClientCounterCallback() : mNumConnectedServices(0), mForcePersist(false) {} bool registerService(const sp<IBinder>& service, const std::string& name, bool registerService(const sp<IBinder>& service, const std::string& name, bool allowIsolated, int dumpFlags); bool allowIsolated, int dumpFlags); /** * Set a flag to prevent services from automatically shutting down */ void forcePersist(bool persist); protected: protected: Status onClients(const sp<IBinder>& service, bool clients) override; Status onClients(const sp<IBinder>& service, bool clients) override; Loading @@ -60,6 +65,8 @@ private: * Map of registered names and services * Map of registered names and services */ */ std::map<std::string, Service> mRegisteredServices; std::map<std::string, Service> mRegisteredServices; bool mForcePersist; }; }; bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name, bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name, Loading Loading @@ -88,6 +95,14 @@ bool ClientCounterCallback::registerService(const sp<IBinder>& service, const st return true; return true; } } void ClientCounterCallback::forcePersist(bool persist) { mForcePersist = persist; if(!mForcePersist) { // Attempt a shutdown in case the number of clients hit 0 while the flag was on tryShutdown(); } } /** /** * onClients is oneway, so no need to worry about multi-threading. Note that this means multiple * onClients is oneway, so no need to worry about multi-threading. Note that this means multiple * invocations could occur on different threads however. * invocations could occur on different threads however. Loading @@ -103,14 +118,21 @@ Status ClientCounterCallback::onClients(const sp<IBinder>& service, bool clients mNumConnectedServices, mRegisteredServices.size(), mNumConnectedServices, mRegisteredServices.size(), String8(service->getInterfaceDescriptor()).string(), clients); String8(service->getInterfaceDescriptor()).string(), clients); if (mNumConnectedServices == 0) { tryShutdown(); tryShutdown(); } return Status::ok(); return Status::ok(); } } void ClientCounterCallback::tryShutdown() { void ClientCounterCallback::tryShutdown() { if(mNumConnectedServices > 0) { // Should only shut down if there are no clients return; } if(mForcePersist) { ALOGI("Shutdown prevented by forcePersist override flag."); return; } ALOGI("Trying to shut down the service. No clients in use for any service in process."); ALOGI("Trying to shut down the service. No clients in use for any service in process."); auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager())); auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager())); Loading Loading @@ -165,5 +187,9 @@ status_t LazyServiceRegistrar::registerService(const sp<IBinder>& service, const return OK; return OK; } } void LazyServiceRegistrar::forcePersist(bool persist) { mClientCC->forcePersist(persist); } } // namespace hardware } // namespace hardware } // namespace android } // namespace android No newline at end of file
libs/binder/include/binder/LazyServiceRegistrar.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -34,6 +34,12 @@ class LazyServiceRegistrar { const std::string& name = "default", const std::string& name = "default", bool allowIsolated = false, bool allowIsolated = false, int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT); int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT); /** * Force the service to persist, even when it has 0 clients. * If setting this flag from the server side, make sure to do so before calling registerService, * or there may be a race with the default dynamic shutdown. */ void forcePersist(bool persist); private: private: std::shared_ptr<internal::ClientCounterCallback> mClientCC; std::shared_ptr<internal::ClientCounterCallback> mClientCC; Loading