Add debugDump() to IServiceManager.

Also clean up ServiceManager by adding forEachExistingService()
method.

Bug: 34642756
Bug: 34712252

Test: adb shell lshal
Change-Id: Ie4320083ee836c1fd7cfe56b2e4761c012a7351f
diff --git a/HidlService.cpp b/HidlService.cpp
index 2898411..532d426 100644
--- a/HidlService.cpp
+++ b/HidlService.cpp
@@ -66,6 +66,10 @@
     }
 }
 
+size_t HidlService::getServiceStrongCount() const {
+    return mService->getStrongCount();
+}
+
 }  // namespace implementation
 }  // namespace V1_0
 }  // namespace manager
diff --git a/HidlService.h b/HidlService.h
index f76e784..16688e8 100644
--- a/HidlService.h
+++ b/HidlService.h
@@ -39,6 +39,9 @@
 
     std::string string() const; // e.x. "android.hidl.manager@1.0::IServiceManager/manager"
 
+    /* for debugging purposes only. */
+    size_t getServiceStrongCount() const;
+
 private:
     void sendRegistrationNotifications();
 
diff --git a/ServiceManager.cpp b/ServiceManager.cpp
index c7d69a1..15f31e5 100644
--- a/ServiceManager.cpp
+++ b/ServiceManager.cpp
@@ -13,6 +13,27 @@
 namespace V1_0 {
 namespace implementation {
 
+size_t ServiceManager::countExistingService() const {
+    size_t total = 0;
+    forEachExistingService([&] (const HidlService *) {
+        ++total;
+    });
+    return total;
+}
+
+void ServiceManager::forEachExistingService(std::function<void(const HidlService *)> f) const {
+    for (const auto &interfaceMapping : mServiceMap) {
+        const auto &instanceMap = interfaceMapping.second.getInstanceMap();
+
+        for (const auto &instanceMapping : instanceMap) {
+            const std::unique_ptr<HidlService> &service = instanceMapping.second;
+            if (service->getService() == nullptr) continue;
+
+            f(service.get());
+        }
+    }
+}
+
 void ServiceManager::serviceDied(uint64_t /*cookie*/, const wp<IBase>& who) {
     // TODO(b/32837397)
     remove(who);
@@ -128,33 +149,14 @@
 }
 
 Return<void> ServiceManager::list(list_cb _hidl_cb) {
-    size_t total = 0;
-
-    for (const auto &interfaceMapping : mServiceMap) {
-        const auto &instanceMap = interfaceMapping.second.getInstanceMap();
-
-        for (const auto &instanceMapping : instanceMap) {
-            const std::unique_ptr<HidlService> &service = instanceMapping.second;
-            if (service->getService() == nullptr) continue;
-
-            ++total;
-        }
-    }
 
     hidl_vec<hidl_string> list;
-    list.resize(total);
+    list.resize(countExistingService());
 
     size_t idx = 0;
-    for (const auto &interfaceMapping : mServiceMap) {
-        const auto &instanceMap = interfaceMapping.second.getInstanceMap();
-
-        for (const auto &instanceMapping : instanceMap) {
-            const std::unique_ptr<HidlService> &service = instanceMapping.second;
-            if (service->getService() == nullptr) continue;
-
-            list[idx++] = service->string();
-        }
-    }
+    forEachExistingService([&] (const HidlService *service) {
+        list[idx++] = service->string();
+    });
 
     _hidl_cb(list);
     return Void();
@@ -222,6 +224,24 @@
     return true;
 }
 
+Return<void> ServiceManager::debugDump(debugDump_cb _cb) {
+
+    hidl_vec<IServiceManager::InstanceDebugInfo> list;
+    list.resize(countExistingService());
+
+    size_t idx = 0;
+    forEachExistingService([&] (const HidlService *service) {
+        list[idx++] = {
+            .interfaceName = service->getInterfaceName(),
+            .instanceName = service->getInstanceName(),
+            .refCount = service->getServiceStrongCount(),
+        };
+    });
+
+    _cb(list);
+    return Void();
+}
+
 bool ServiceManager::remove(const wp<IBase>& who) {
     bool found = false;
     for (auto &interfaceMapping : mServiceMap) {
@@ -237,6 +257,7 @@
     }
     return found;
 }
+
 } // namespace implementation
 }  // namespace V1_0
 }  // namespace manager
diff --git a/ServiceManager.h b/ServiceManager.h
index 8278696..73dace4 100644
--- a/ServiceManager.h
+++ b/ServiceManager.h
@@ -41,9 +41,13 @@
                                           const hidl_string& name,
                                           const sp<IServiceNotification>& callback) override;
 
+    Return<void> debugDump(debugDump_cb _cb) override;
+
     virtual void serviceDied(uint64_t cookie, const wp<IBase>& who);
 private:
     bool remove(const wp<IBase>& who);
+    size_t countExistingService() const;
+    void forEachExistingService(std::function<void(const HidlService *)> f) const;
 
     using InstanceMap = std::map<
             std::string, // instance name e.x. "manager"