Loading cmds/cmd/cmd.cpp +12 −4 Original line number Diff line number Diff line Loading @@ -185,7 +185,7 @@ int cmdMain(const std::vector<std::string_view>& argv, TextOutput& outputLog, Te int argc = argv.size(); if (argc == 0) { errorLog << "cmd: No service specified; use -l to list all services" << endl; errorLog << "cmd: No service specified; use -l to list all running services. Use -w to start and wait for a service." << endl; return 20; } Loading @@ -203,14 +203,22 @@ int cmdMain(const std::vector<std::string_view>& argv, TextOutput& outputLog, Te return 0; } const auto cmd = argv[0]; bool waitForService = ((argc > 1) && (argv[0] == "-w")); int serviceIdx = (waitForService) ? 1 : 0; const auto cmd = argv[serviceIdx]; Vector<String16> args; String16 serviceName = String16(cmd.data(), cmd.size()); for (int i = 1; i < argc; i++) { for (int i = serviceIdx + 1; i < argc; i++) { args.add(String16(argv[i].data(), argv[i].size())); } sp<IBinder> service = sm->checkService(serviceName); sp<IBinder> service; if(waitForService) { service = sm->waitForService(serviceName); } else { service = sm->checkService(serviceName); } if (service == nullptr) { if (runMode == RunMode::kStandalone) { ALOGW("Can't find service %.*s", static_cast<int>(cmd.size()), cmd.data()); Loading cmds/servicemanager/ServiceManager.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -522,6 +522,11 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } if (serviceIt->second.guaranteeClient) { LOG(INFO) << "Tried to unregister " << name << ", but there is about to be a client."; return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } int clients = handleServiceClientCallback(name, false); // clients < 0: feature not implemented or other error. Assume clients. Loading @@ -532,6 +537,8 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB if (clients < 0 || clients > 2) { // client callbacks are either disabled or there are other 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); } Loading libs/binder/LazyServiceRegistrar.cpp +31 −5 Original line number Diff line number Diff line Loading @@ -31,11 +31,16 @@ using AidlServiceManager = android::os::IServiceManager; class ClientCounterCallback : public ::android::os::BnClientCallback { public: ClientCounterCallback() : mNumConnectedServices(0) {} ClientCounterCallback() : mNumConnectedServices(0), mForcePersist(false) {} bool registerService(const sp<IBinder>& service, const std::string& name, bool allowIsolated, int dumpFlags); /** * Set a flag to prevent services from automatically shutting down */ void forcePersist(bool persist); protected: Status onClients(const sp<IBinder>& service, bool clients) override; Loading @@ -60,6 +65,8 @@ private: * Map of registered names and services */ std::map<std::string, Service> mRegisteredServices; bool mForcePersist; }; 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; } 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 * invocations could occur on different threads however. Loading @@ -103,14 +118,21 @@ Status ClientCounterCallback::onClients(const sp<IBinder>& service, bool clients mNumConnectedServices, mRegisteredServices.size(), String8(service->getInterfaceDescriptor()).string(), clients); if (mNumConnectedServices == 0) { tryShutdown(); } return Status::ok(); } 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."); auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager())); Loading Loading @@ -165,5 +187,9 @@ status_t LazyServiceRegistrar::registerService(const sp<IBinder>& service, const return OK; } void LazyServiceRegistrar::forcePersist(bool persist) { mClientCC->forcePersist(persist); } } // namespace hardware } // namespace android No newline at end of file libs/binder/include/binder/LazyServiceRegistrar.h +6 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,12 @@ class LazyServiceRegistrar { const std::string& name = "default", bool allowIsolated = false, 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: std::shared_ptr<internal::ClientCounterCallback> mClientCC; Loading Loading
cmds/cmd/cmd.cpp +12 −4 Original line number Diff line number Diff line Loading @@ -185,7 +185,7 @@ int cmdMain(const std::vector<std::string_view>& argv, TextOutput& outputLog, Te int argc = argv.size(); if (argc == 0) { errorLog << "cmd: No service specified; use -l to list all services" << endl; errorLog << "cmd: No service specified; use -l to list all running services. Use -w to start and wait for a service." << endl; return 20; } Loading @@ -203,14 +203,22 @@ int cmdMain(const std::vector<std::string_view>& argv, TextOutput& outputLog, Te return 0; } const auto cmd = argv[0]; bool waitForService = ((argc > 1) && (argv[0] == "-w")); int serviceIdx = (waitForService) ? 1 : 0; const auto cmd = argv[serviceIdx]; Vector<String16> args; String16 serviceName = String16(cmd.data(), cmd.size()); for (int i = 1; i < argc; i++) { for (int i = serviceIdx + 1; i < argc; i++) { args.add(String16(argv[i].data(), argv[i].size())); } sp<IBinder> service = sm->checkService(serviceName); sp<IBinder> service; if(waitForService) { service = sm->waitForService(serviceName); } else { service = sm->checkService(serviceName); } if (service == nullptr) { if (runMode == RunMode::kStandalone) { ALOGW("Can't find service %.*s", static_cast<int>(cmd.size()), cmd.data()); Loading
cmds/servicemanager/ServiceManager.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -522,6 +522,11 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } if (serviceIt->second.guaranteeClient) { LOG(INFO) << "Tried to unregister " << name << ", but there is about to be a client."; return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } int clients = handleServiceClientCallback(name, false); // clients < 0: feature not implemented or other error. Assume clients. Loading @@ -532,6 +537,8 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB if (clients < 0 || clients > 2) { // client callbacks are either disabled or there are other 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); } Loading
libs/binder/LazyServiceRegistrar.cpp +31 −5 Original line number Diff line number Diff line Loading @@ -31,11 +31,16 @@ using AidlServiceManager = android::os::IServiceManager; class ClientCounterCallback : public ::android::os::BnClientCallback { public: ClientCounterCallback() : mNumConnectedServices(0) {} ClientCounterCallback() : mNumConnectedServices(0), mForcePersist(false) {} bool registerService(const sp<IBinder>& service, const std::string& name, bool allowIsolated, int dumpFlags); /** * Set a flag to prevent services from automatically shutting down */ void forcePersist(bool persist); protected: Status onClients(const sp<IBinder>& service, bool clients) override; Loading @@ -60,6 +65,8 @@ private: * Map of registered names and services */ std::map<std::string, Service> mRegisteredServices; bool mForcePersist; }; 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; } 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 * invocations could occur on different threads however. Loading @@ -103,14 +118,21 @@ Status ClientCounterCallback::onClients(const sp<IBinder>& service, bool clients mNumConnectedServices, mRegisteredServices.size(), String8(service->getInterfaceDescriptor()).string(), clients); if (mNumConnectedServices == 0) { tryShutdown(); } return Status::ok(); } 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."); auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager())); Loading Loading @@ -165,5 +187,9 @@ status_t LazyServiceRegistrar::registerService(const sp<IBinder>& service, const return OK; } void LazyServiceRegistrar::forcePersist(bool persist) { mClientCC->forcePersist(persist); } } // namespace hardware } // namespace android No newline at end of file
libs/binder/include/binder/LazyServiceRegistrar.h +6 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,12 @@ class LazyServiceRegistrar { const std::string& name = "default", bool allowIsolated = false, 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: std::shared_ptr<internal::ClientCounterCallback> mClientCC; Loading