Merge "Add debugDump() to IServiceManager."
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index 9a6a3b5..5795b02 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -16,26 +16,33 @@
 
 #define LOG_TAG "ServiceManagement"
 
+#include <condition_variable>
+#include <dlfcn.h>
+#include <dirent.h>
+#include <unistd.h>
+
+#include <mutex>
+#include <regex>
+
 #include <hidl/HidlBinderSupport.h>
 #include <hidl/ServiceManagement.h>
 #include <hidl/Static.h>
 #include <hidl/Status.h>
 
 #include <android-base/logging.h>
-#include <condition_variable>
-#include <dlfcn.h>
-#include <dirent.h>
 #include <hidl-util/FQName.h>
 #include <hidl-util/StringHelper.h>
 #include <hwbinder/IPCThreadState.h>
 #include <hwbinder/Parcel.h>
-#include <mutex>
-#include <unistd.h>
 
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <android/hidl/manager/1.0/BpHwServiceManager.h>
 #include <android/hidl/manager/1.0/BnHwServiceManager.h>
 
+#define RE_COMPONENT    "[a-zA-Z_][a-zA-Z_0-9]*"
+#define RE_PATH         RE_COMPONENT "(?:[.]" RE_COMPONENT ")*"
+static const std::regex gLibraryFileNamePattern("(" RE_PATH "@[0-9]+[.][0-9]+)-impl(.*?).so");
+
 using android::hidl::manager::V1_0::IServiceManager;
 using android::hidl::manager::V1_0::IServiceNotification;
 using android::hidl::manager::V1_0::BpHwServiceManager;
@@ -86,6 +93,15 @@
     return results;
 }
 
+bool matchPackageName(const std::string &lib, std::string *matchedName) {
+    std::smatch match;
+    if (std::regex_match(lib, match, gLibraryFileNamePattern)) {
+        *matchedName = match.str(1) + "::I*";
+        return true;
+    }
+    return false;
+}
+
 struct PassthroughServiceManager : IServiceManager {
     Return<sp<IBase>> get(const hidl_string& fqName,
                      const hidl_string& name) override {
@@ -170,6 +186,27 @@
         return false;
     }
 
+    Return<void> debugDump(debugDump_cb _cb) override {
+        std::vector<InstanceDebugInfo> vec;
+        for (const std::string &path : {
+            HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, HAL_LIBRARY_PATH_SYSTEM
+        }) {
+            std::vector<std::string> libs = search(path, "", ".so");
+            for (const std::string &lib : libs) {
+                std::string matchedName;
+                if (matchPackageName(lib, &matchedName)) {
+                    vec.push_back({
+                        .interfaceName = matchedName,
+                        .instanceName = "",
+                        .refCount = 0,
+                    });
+                }
+            }
+        }
+        _cb(vec);
+        return Void();
+    }
+
 };
 
 sp<IServiceManager> getPassthroughServiceManager() {
diff --git a/transport/manager/1.0/IServiceManager.hal b/transport/manager/1.0/IServiceManager.hal
index 321ee21..ff7201e 100644
--- a/transport/manager/1.0/IServiceManager.hal
+++ b/transport/manager/1.0/IServiceManager.hal
@@ -107,4 +107,17 @@
                              string name,
                              IServiceNotification callback)
         generates (bool success);
-};
\ No newline at end of file
+
+    struct InstanceDebugInfo {
+        string interfaceName;
+        string instanceName;
+        uint64_t refCount;
+    };
+
+    /*
+     * Similar to list, but contains more information for each instance.
+     * @return info a vector where each item contains debug information for each
+     *         instance.
+     */
+    debugDump() generates (vec<InstanceDebugInfo> info);
+};