Loading cmds/servicemanager/ServiceManager.cpp +15 −11 Original line number Original line Diff line number Diff line Loading @@ -423,11 +423,12 @@ ssize_t ServiceManager::Service::getNodeStrongRefCount() { void ServiceManager::handleClientCallbacks() { void ServiceManager::handleClientCallbacks() { for (const auto& [name, service] : mNameToService) { for (const auto& [name, service] : mNameToService) { handleServiceClientCallback(name); handleServiceClientCallback(name, true); } } } } ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName) { ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName, bool isCalledOnInterval) { auto serviceIt = mNameToService.find(serviceName); auto serviceIt = mNameToService.find(serviceName); if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) { if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) { return -1; return -1; Loading @@ -451,6 +452,8 @@ ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceNa service.guaranteeClient = false; service.guaranteeClient = false; } } // only send notifications if this was called via the interval checking workflow if (isCalledOnInterval) { if (hasClients && !service.hasClients) { if (hasClients && !service.hasClients) { // client was retrieved in some other way // client was retrieved in some other way sendClientCallbackNotifications(serviceName, true); sendClientCallbackNotifications(serviceName, true); Loading @@ -460,6 +463,7 @@ ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceNa if (!hasClients && service.hasClients) { if (!hasClients && service.hasClients) { sendClientCallbackNotifications(serviceName, false); sendClientCallbackNotifications(serviceName, false); } } } return count; return count; } } Loading Loading @@ -518,7 +522,7 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } } int clients = handleServiceClientCallback(name); int clients = handleServiceClientCallback(name, false); // clients < 0: feature not implemented or other error. Assume clients. // clients < 0: feature not implemented or other error. Assume clients. // Otherwise: // Otherwise: Loading @@ -527,7 +531,7 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB // So, if clients > 2, then at least one other service on the system must hold a refcount. // So, if clients > 2, then at least one other service on the system must hold a refcount. 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; return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } } Loading cmds/servicemanager/ServiceManager.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -75,7 +75,7 @@ private: void removeRegistrationCallback(const wp<IBinder>& who, void removeRegistrationCallback(const wp<IBinder>& who, ServiceCallbackMap::iterator* it, ServiceCallbackMap::iterator* it, bool* found); bool* found); ssize_t handleServiceClientCallback(const std::string& serviceName); ssize_t handleServiceClientCallback(const std::string& serviceName, bool isCalledOnInterval); // Also updates mHasClients (of what the last callback was) // Also updates mHasClients (of what the last callback was) void sendClientCallbackNotifications(const std::string& serviceName, bool hasClients); void sendClientCallbackNotifications(const std::string& serviceName, bool hasClients); // removes a callback from mNameToClientCallback, deleting the entry if the vector is empty // removes a callback from mNameToClientCallback, deleting the entry if the vector is empty Loading libs/binder/LazyServiceRegistrar.cpp +17 −12 Original line number Original line Diff line number Diff line Loading @@ -53,14 +53,13 @@ private: struct Service { struct Service { sp<IBinder> service; sp<IBinder> service; std::string name; bool allowIsolated; bool allowIsolated; int dumpFlags; int dumpFlags; }; }; /** /** * Number of services that have been registered. * Map of registered names and services */ */ std::vector<Service> mRegisteredServices; std::map<std::string, Service> mRegisteredServices; }; }; bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name, bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name, Loading @@ -68,20 +67,24 @@ bool ClientCounterCallback::registerService(const sp<IBinder>& service, const st auto manager = interface_cast<AidlServiceManager>( auto manager = interface_cast<AidlServiceManager>( ProcessState::self()->getContextObject(nullptr)); ProcessState::self()->getContextObject(nullptr)); ALOGI("Registering service %s", name.c_str()); bool reRegister = mRegisteredServices.count(name) > 0; std::string regStr = (reRegister) ? "Re-registering" : "Registering"; ALOGI("%s service %s", regStr.c_str(), name.c_str()); if (!manager->addService(name.c_str(), service, allowIsolated, dumpFlags).isOk()) { if (!manager->addService(name.c_str(), service, allowIsolated, dumpFlags).isOk()) { ALOGE("Failed to register service %s", name.c_str()); ALOGE("Failed to register service %s", name.c_str()); return false; return false; } } if (!manager->registerClientCallback(name, service, this).isOk()) if (!manager->registerClientCallback(name, service, this).isOk()) { { ALOGE("Failed to add client callback for service %s", name.c_str()); ALOGE("Failed to add client callback for service %s", name.c_str()); return false; return false; } } mRegisteredServices.push_back({service, name, allowIsolated, dumpFlags}); if (!reRegister) { // Only add this when a service is added for the first time, as it is not removed mRegisteredServices[name] = {service, allowIsolated, dumpFlags}; } return true; return true; } } Loading Loading @@ -119,10 +122,11 @@ void ClientCounterCallback::tryShutdown() { for (; unRegisterIt != mRegisteredServices.end(); ++unRegisterIt) { for (; unRegisterIt != mRegisteredServices.end(); ++unRegisterIt) { auto& entry = (*unRegisterIt); auto& entry = (*unRegisterIt); bool success = manager->tryUnregisterService(entry.name, entry.service).isOk(); bool success = manager->tryUnregisterService(entry.first, entry.second.service).isOk(); if (!success) { if (!success) { ALOGI("Failed to unregister service %s", entry.name.c_str()); ALOGI("Failed to unregister service %s", entry.first.c_str()); break; break; } } } } Loading @@ -137,7 +141,8 @@ void ClientCounterCallback::tryShutdown() { auto& entry = (*reRegisterIt); auto& entry = (*reRegisterIt); // re-register entry // re-register entry if (!registerService(entry.service, entry.name, entry.allowIsolated, entry.dumpFlags)) { if (!registerService(entry.second.service, entry.first, entry.second.allowIsolated, entry.second.dumpFlags)) { // Must restart. Otherwise, clients will never be able to get a hold of this service. // Must restart. Otherwise, clients will never be able to get a hold of this service. ALOGE("Bad state: could not re-register services"); ALOGE("Bad state: could not re-register services"); } } Loading Loading
cmds/servicemanager/ServiceManager.cpp +15 −11 Original line number Original line Diff line number Diff line Loading @@ -423,11 +423,12 @@ ssize_t ServiceManager::Service::getNodeStrongRefCount() { void ServiceManager::handleClientCallbacks() { void ServiceManager::handleClientCallbacks() { for (const auto& [name, service] : mNameToService) { for (const auto& [name, service] : mNameToService) { handleServiceClientCallback(name); handleServiceClientCallback(name, true); } } } } ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName) { ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName, bool isCalledOnInterval) { auto serviceIt = mNameToService.find(serviceName); auto serviceIt = mNameToService.find(serviceName); if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) { if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) { return -1; return -1; Loading @@ -451,6 +452,8 @@ ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceNa service.guaranteeClient = false; service.guaranteeClient = false; } } // only send notifications if this was called via the interval checking workflow if (isCalledOnInterval) { if (hasClients && !service.hasClients) { if (hasClients && !service.hasClients) { // client was retrieved in some other way // client was retrieved in some other way sendClientCallbackNotifications(serviceName, true); sendClientCallbackNotifications(serviceName, true); Loading @@ -460,6 +463,7 @@ ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceNa if (!hasClients && service.hasClients) { if (!hasClients && service.hasClients) { sendClientCallbackNotifications(serviceName, false); sendClientCallbackNotifications(serviceName, false); } } } return count; return count; } } Loading Loading @@ -518,7 +522,7 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } } int clients = handleServiceClientCallback(name); int clients = handleServiceClientCallback(name, false); // clients < 0: feature not implemented or other error. Assume clients. // clients < 0: feature not implemented or other error. Assume clients. // Otherwise: // Otherwise: Loading @@ -527,7 +531,7 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB // So, if clients > 2, then at least one other service on the system must hold a refcount. // So, if clients > 2, then at least one other service on the system must hold a refcount. 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; return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } } Loading
cmds/servicemanager/ServiceManager.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -75,7 +75,7 @@ private: void removeRegistrationCallback(const wp<IBinder>& who, void removeRegistrationCallback(const wp<IBinder>& who, ServiceCallbackMap::iterator* it, ServiceCallbackMap::iterator* it, bool* found); bool* found); ssize_t handleServiceClientCallback(const std::string& serviceName); ssize_t handleServiceClientCallback(const std::string& serviceName, bool isCalledOnInterval); // Also updates mHasClients (of what the last callback was) // Also updates mHasClients (of what the last callback was) void sendClientCallbackNotifications(const std::string& serviceName, bool hasClients); void sendClientCallbackNotifications(const std::string& serviceName, bool hasClients); // removes a callback from mNameToClientCallback, deleting the entry if the vector is empty // removes a callback from mNameToClientCallback, deleting the entry if the vector is empty Loading
libs/binder/LazyServiceRegistrar.cpp +17 −12 Original line number Original line Diff line number Diff line Loading @@ -53,14 +53,13 @@ private: struct Service { struct Service { sp<IBinder> service; sp<IBinder> service; std::string name; bool allowIsolated; bool allowIsolated; int dumpFlags; int dumpFlags; }; }; /** /** * Number of services that have been registered. * Map of registered names and services */ */ std::vector<Service> mRegisteredServices; std::map<std::string, Service> mRegisteredServices; }; }; bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name, bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name, Loading @@ -68,20 +67,24 @@ bool ClientCounterCallback::registerService(const sp<IBinder>& service, const st auto manager = interface_cast<AidlServiceManager>( auto manager = interface_cast<AidlServiceManager>( ProcessState::self()->getContextObject(nullptr)); ProcessState::self()->getContextObject(nullptr)); ALOGI("Registering service %s", name.c_str()); bool reRegister = mRegisteredServices.count(name) > 0; std::string regStr = (reRegister) ? "Re-registering" : "Registering"; ALOGI("%s service %s", regStr.c_str(), name.c_str()); if (!manager->addService(name.c_str(), service, allowIsolated, dumpFlags).isOk()) { if (!manager->addService(name.c_str(), service, allowIsolated, dumpFlags).isOk()) { ALOGE("Failed to register service %s", name.c_str()); ALOGE("Failed to register service %s", name.c_str()); return false; return false; } } if (!manager->registerClientCallback(name, service, this).isOk()) if (!manager->registerClientCallback(name, service, this).isOk()) { { ALOGE("Failed to add client callback for service %s", name.c_str()); ALOGE("Failed to add client callback for service %s", name.c_str()); return false; return false; } } mRegisteredServices.push_back({service, name, allowIsolated, dumpFlags}); if (!reRegister) { // Only add this when a service is added for the first time, as it is not removed mRegisteredServices[name] = {service, allowIsolated, dumpFlags}; } return true; return true; } } Loading Loading @@ -119,10 +122,11 @@ void ClientCounterCallback::tryShutdown() { for (; unRegisterIt != mRegisteredServices.end(); ++unRegisterIt) { for (; unRegisterIt != mRegisteredServices.end(); ++unRegisterIt) { auto& entry = (*unRegisterIt); auto& entry = (*unRegisterIt); bool success = manager->tryUnregisterService(entry.name, entry.service).isOk(); bool success = manager->tryUnregisterService(entry.first, entry.second.service).isOk(); if (!success) { if (!success) { ALOGI("Failed to unregister service %s", entry.name.c_str()); ALOGI("Failed to unregister service %s", entry.first.c_str()); break; break; } } } } Loading @@ -137,7 +141,8 @@ void ClientCounterCallback::tryShutdown() { auto& entry = (*reRegisterIt); auto& entry = (*reRegisterIt); // re-register entry // re-register entry if (!registerService(entry.service, entry.name, entry.allowIsolated, entry.dumpFlags)) { if (!registerService(entry.second.service, entry.first, entry.second.allowIsolated, entry.second.dumpFlags)) { // Must restart. Otherwise, clients will never be able to get a hold of this service. // Must restart. Otherwise, clients will never be able to get a hold of this service. ALOGE("Bad state: could not re-register services"); ALOGE("Bad state: could not re-register services"); } } Loading