registerClientCallback: immediate notification

If there is an existing service, registerClientCallback should
immediately send onClients(true). This is part of the IServiceManager
contract.

Fixes: 123318663
Test: hwservicemanager_test
    HidlServiceLazyTest NotificationSentForNewClientCallback (now passes)
Test: internal 'lazy_hidl_test' fuzzing health storage HAL, health
    storage HAL no longer reports double-de-acquisition of clients.

Change-Id: If83b162262d33de59179b95dbb7175aaafb0f050
diff --git a/HidlService.cpp b/HidlService.cpp
index ddc0f1a..6d020a4 100644
--- a/HidlService.cpp
+++ b/HidlService.cpp
@@ -105,6 +105,12 @@
 }
 
 void HidlService::addClientCallback(const sp<IClientCallback>& callback) {
+    handleClientCallbacks(false /* isCalledOnInterval */);
+
+    if (mHasClients) {
+        sendClientCallbackNotification(callback, true /*hasClients*/);
+    }
+
     mClientCallbacks.push_back(callback);
 }
 
@@ -212,16 +218,20 @@
     LOG(INFO) << "Notifying " << string() << " they have clients: " << hasClients;
 
     for (const auto& cb : mClientCallbacks) {
-        Return<void> ret = cb->onClients(getService(), hasClients);
-        if (!ret.isOk()) {
-            LOG(WARNING) << "onClients callback failed for " << string() << ": " << ret.description();
-        }
+        sendClientCallbackNotification(cb, hasClients);
     }
 
     mNoClientsCounter = 0;
     mHasClients = hasClients;
 }
 
+void HidlService::sendClientCallbackNotification(const sp<IClientCallback>& callback, bool hasClients) {
+    Return<void> ret = callback->onClients(getService(), hasClients);
+    if (!ret.isOk()) {
+        LOG(WARNING) << "onClients callback failed for " << string() << ": " << ret.description();
+    }
+}
+
 
 }  // namespace implementation
 }  // namespace manager
diff --git a/HidlService.h b/HidlService.h
index 7256b52..426df8e 100644
--- a/HidlService.h
+++ b/HidlService.h
@@ -67,6 +67,7 @@
     bool removeListener(const wp<IBase> &listener);
     void registerPassthroughClient(pid_t pid);
 
+    // also sends onClients(true) if we have clients
     void addClientCallback(const sp<IClientCallback>& callback);
     bool removeClientCallback(const sp<IClientCallback>& callback);
 
@@ -86,8 +87,13 @@
 
 private:
     void sendRegistrationNotifications();
+
+    // Also updates mHasClients (of what the last callback was)
     void sendClientCallbackNotifications(bool hasClients);
 
+    // Only sends notification
+    void sendClientCallbackNotification(const sp<IClientCallback>& callback, bool hasClients);
+
     const std::string                     mInterfaceName; // e.x. "android.hidl.manager@1.0::IServiceManager"
     const std::string                     mInstanceName;  // e.x. "manager"
     sp<IBase>                             mService;
diff --git a/ServiceManager.cpp b/ServiceManager.cpp
index a4f99ce..ac142f5 100644
--- a/ServiceManager.cpp
+++ b/ServiceManager.cpp
@@ -565,7 +565,6 @@
     }
 
     registered->addClientCallback(cb);
-    registered->handleClientCallbacks(false /* isCalledOnInterval */);
 
     return true;
 }
diff --git a/test_lazy.cpp b/test_lazy.cpp
index 542bf53..df42329 100644
--- a/test_lazy.cpp
+++ b/test_lazy.cpp
@@ -170,3 +170,30 @@
     service->handleClientCallbacks(true /*onInterval*/);
     ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
 }
+
+TEST_F(HidlServiceLazyTest, NotificationSentForNewClientCallback) {
+    sp<RecordingClientCallback> cb = new RecordingClientCallback;
+
+    std::unique_ptr<HidlService> service = makeService();
+    service->addClientCallback(cb);
+
+    setReportedClientCount(2);
+    service->handleClientCallbacks(false /*onInterval*/);
+    ASSERT_THAT(cb->stream, ElementsAre(true));
+
+    sp<RecordingClientCallback> laterCb = new RecordingClientCallback;
+    service->addClientCallback(laterCb);
+
+    ASSERT_THAT(cb->stream, ElementsAre(true));
+    ASSERT_THAT(laterCb->stream, ElementsAre(true));
+
+    setReportedClientCount(1);
+
+    service->handleClientCallbacks(true /*onInterval*/);
+    ASSERT_THAT(cb->stream, ElementsAre(true));
+    ASSERT_THAT(laterCb->stream, ElementsAre(true));
+
+    service->handleClientCallbacks(true /*onInterval*/);
+    ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
+    ASSERT_THAT(laterCb->stream, ElementsAre(true, false)); // reported only after two intervals
+}