Update for listManifestByInterface.

See addition of this API in system/libhidl.

This is to support libvintf not being in the VNDK, provide an
alternative to listByInterface which makes more sense with lazy HALs,
and also, help code be consistent with the manifest.

Fixes: 76108617
Test: hidl_test
Change-Id: Ia45263f429d11c31cc34cdfa54193485da119f95
diff --git a/ServiceManager.cpp b/ServiceManager.cpp
index 94bb7c6..03ec4bc 100644
--- a/ServiceManager.cpp
+++ b/ServiceManager.cpp
@@ -572,6 +572,21 @@
     return addImpl(name, service, chain, context, pid);
 }
 
+Return<void> ServiceManager::listManifestByInterface(const hidl_string& fqName,
+                                                     listManifestByInterface_cb _hidl_cb) {
+    pid_t pid = IPCThreadState::self()->getCallingPid();
+    if (!mAcl.canGet(fqName, pid)) {
+        _hidl_cb({});
+        return Void();
+    }
+
+    std::set<std::string> instances = getInstances(fqName);
+    hidl_vec<hidl_string> ret(instances.begin(), instances.end());
+
+    _hidl_cb(ret);
+    return Void();
+}
+
 Return<void> ServiceManager::debugDump(debugDump_cb _cb) {
     pid_t pid = IPCThreadState::self()->getCallingPid();
     if (!mAcl.canList(pid)) {
diff --git a/ServiceManager.h b/ServiceManager.h
index 44936d5..8cfaeb7 100644
--- a/ServiceManager.h
+++ b/ServiceManager.h
@@ -60,6 +60,8 @@
     Return<bool> addWithChain(const hidl_string& name,
                               const sp<IBase>& service,
                               const hidl_vec<hidl_string>& chain) override;
+    Return<void> listManifestByInterface(const hidl_string& fqInstanceName,
+                                         listManifestByInterface_cb _hidl_cb) override;
 
     void handleClientCallbacks();
 
diff --git a/Vintf.cpp b/Vintf.cpp
index 989adc0..263f9a4 100644
--- a/Vintf.cpp
+++ b/Vintf.cpp
@@ -4,7 +4,6 @@
 #include "Vintf.h"
 
 #include <android-base/logging.h>
-#include <hidl-util/FQName.h>
 #include <vintf/parse_string.h>
 #include <vintf/VintfObject.h>
 
@@ -27,7 +26,7 @@
 
     if (!FQName::parse(interfaceName, &fqName)) {
         LOG(ERROR) << __FUNCTION__ << ": " << interfaceName
-                   << " is not a valid fully-qualified name ";
+                   << " is not a valid fully-qualified name.";
         return vintf::Transport::EMPTY;
     }
     if (!fqName.hasVersion()) {
@@ -58,5 +57,33 @@
     return vintf::Transport::EMPTY;
 }
 
+std::set<std::string> getInstances(const std::string& interfaceName) {
+    FQName fqName;
+    if (!FQName::parse(interfaceName, &fqName) || !fqName.isFullyQualified() ||
+            fqName.isValidValueName() || !fqName.isInterfaceName()) {
+        LOG(ERROR) << __FUNCTION__ << ": " << interfaceName
+                   << " is not a valid fully-qualified name.";
+        return {};
+    }
+
+    std::set<std::string> ret;
+
+    auto deviceManifest = vintf::VintfObject::GetDeviceHalManifest();
+    auto frameworkManifest = vintf::VintfObject::GetFrameworkHalManifest();
+
+    vintf::Version version = {fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()};
+
+    std::set<std::string> deviceSet =
+        deviceManifest->getInstances(fqName.package(), version, fqName.name());
+    std::set<std::string> frameworkSet =
+        frameworkManifest->getInstances(fqName.package(), version, fqName.name());
+
+    ret.insert(deviceSet.begin(), deviceSet.end());
+    ret.insert(frameworkSet.begin(), frameworkSet.end());
+
+    return ret;
+}
+
+
 }  // hardware
 }  // android
diff --git a/Vintf.h b/Vintf.h
index ceee286..d6db31f 100644
--- a/Vintf.h
+++ b/Vintf.h
@@ -1,8 +1,10 @@
 #pragma once
 
-#include <string>
 #include <vintf/Transport.h>
 
+#include <set>
+#include <string>
+
 namespace android {
 namespace hardware {
 
@@ -13,5 +15,8 @@
 vintf::Transport getTransport(const std::string &interfaceName,
                               const std::string &instanceName);
 
+// All HALs on the device in manifests.
+std::set<std::string> getInstances(const std::string& interfaceName);
+
 }  // hardware
 }  // android