Merge ab/7061308 into stage.
Bug: 180401296
Merged-In: I703d82abf612d2a0c7f0d440da6a3e54eadab302
Change-Id: I88635f0220ad359f57d7bb7e78abb6e35382ab60
diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp
index 68ea8a6..f96b6bb 100644
--- a/libs/binder/LazyServiceRegistrar.cpp
+++ b/libs/binder/LazyServiceRegistrar.cpp
@@ -48,6 +48,22 @@
Status onClients(const sp<IBinder>& service, bool clients) override;
private:
+ struct Service {
+ sp<IBinder> service;
+ bool allowIsolated;
+ int dumpFlags;
+
+ // whether, based on onClients calls, we know we have a client for this
+ // service or not
+ bool clients = false;
+ bool registered = true;
+ };
+
+ /**
+ * Looks up a service guaranteed to be registered (service from onClients).
+ */
+ std::map<std::string, Service>::iterator assertRegisteredService(const sp<IBinder>& service);
+
/**
* Unregisters all services that we can. If we can't unregister all, re-register other
* services.
@@ -62,24 +78,13 @@
*/
void maybeTryShutdown();
- /*
- * Counter of the number of services that currently have at least one client.
- */
+ // count of services with clients
size_t mNumConnectedServices;
// previous value passed to the active services callback
std::optional<bool> mPreviousHasClients;
- struct Service {
- sp<IBinder> service;
- bool allowIsolated;
- int dumpFlags;
-
- bool registered = true;
- };
- /**
- * Map of registered names and services
- */
+ // map of registered names and services
std::map<std::string, Service> mRegisteredServices;
bool mForcePersist;
@@ -124,18 +129,34 @@
}
if (!reRegister) {
- 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());
return false;
}
// Only add this when a service is added for the first time, as it is not removed
- mRegisteredServices[name] = {service, allowIsolated, dumpFlags};
+ mRegisteredServices[name] = {
+ .service = service,
+ .allowIsolated = allowIsolated,
+ .dumpFlags = dumpFlags
+ };
}
return true;
}
+std::map<std::string, ClientCounterCallbackImpl::Service>::iterator ClientCounterCallbackImpl::assertRegisteredService(const sp<IBinder>& service) {
+ LOG_ALWAYS_FATAL_IF(service == nullptr, "Got onClients callback for null service");
+ for (auto it = mRegisteredServices.begin(); it != mRegisteredServices.end(); ++it) {
+ auto const& [name, registered] = *it;
+ (void) name;
+ if (registered.service != service) continue;
+ return it;
+ }
+ LOG_ALWAYS_FATAL("Got callback on service which we did not register: %s", String8(service->getInterfaceDescriptor()).c_str());
+ __builtin_unreachable();
+}
+
void ClientCounterCallbackImpl::forcePersist(bool persist) {
mForcePersist = persist;
if (!mForcePersist) {
@@ -205,15 +226,25 @@
* invocations could occur on different threads however.
*/
Status ClientCounterCallbackImpl::onClients(const sp<IBinder>& service, bool clients) {
- if (clients) {
- mNumConnectedServices++;
- } else {
- mNumConnectedServices--;
+ auto & [name, registered] = *assertRegisteredService(service);
+ if (registered.clients == clients) {
+ LOG_ALWAYS_FATAL("Process already thought %s had clients: %d but servicemanager has "
+ "notified has clients: %d", name.c_str(), registered.clients, clients);
+ }
+ registered.clients = clients;
+
+ // update cache count of clients
+ {
+ size_t numWithClients = 0;
+ for (const auto& [name, registered] : mRegisteredServices) {
+ (void) name;
+ if (registered.clients) numWithClients++;
+ }
+ mNumConnectedServices = numWithClients;
}
ALOGI("Process has %zu (of %zu available) client(s) in use after notification %s has clients: %d",
- mNumConnectedServices, mRegisteredServices.size(),
- String8(service->getInterfaceDescriptor()).string(), clients);
+ mNumConnectedServices, mRegisteredServices.size(), name.c_str(), clients);
maybeTryShutdown();
return Status::ok();
@@ -236,7 +267,7 @@
}
ClientCounterCallback::ClientCounterCallback() {
- mImpl = new ClientCounterCallbackImpl();
+ mImpl = sp<ClientCounterCallbackImpl>::make();
}
bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name,