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,