Attach filename to ManifestHal

This allows us to provide more debugging info when an
error is generated from a ManifestHal entry.

Test: libvintf_test
Test: vintf_object_test
Bug: 118757553
Change-Id: I5ae18b5a74da98806314c1a457af0e59170b4db4
diff --git a/ManifestHal.cpp b/ManifestHal.cpp
index 3a2a1c0..f5a1aee 100644
--- a/ManifestHal.cpp
+++ b/ManifestHal.cpp
@@ -36,6 +36,7 @@
 }
 
 bool ManifestHal::operator==(const ManifestHal &other) const {
+    // ignore fileName().
     if (format != other.format)
         return false;
     if (name != other.name)
diff --git a/include/vintf/ManifestHal.h b/include/vintf/ManifestHal.h
index 3a798a8..2d9144b 100644
--- a/include/vintf/ManifestHal.h
+++ b/include/vintf/ManifestHal.h
@@ -30,12 +30,13 @@
 #include "ManifestInstance.h"
 #include "TransportArch.h"
 #include "Version.h"
+#include "WithFileName.h"
 
 namespace android {
 namespace vintf {
 
 // A component of HalManifest.
-struct ManifestHal {
+struct ManifestHal : public WithFileName {
     using InstanceType = ManifestInstance;
 
     ManifestHal() = default;
diff --git a/parse_xml.cpp b/parse_xml.cpp
index e42f9f7..e32d9b3 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -1033,11 +1033,18 @@
             return false;
         }
 
-        std::vector<ManifestHal> hals;
-        if (!parseAttr(root, "type", &object->mType, error) ||
-            !parseChildren(root, manifestHalConverter, &hals, error)) {
+        if (!parseAttr(root, "type", &object->mType, error)) {
             return false;
         }
+
+        std::vector<ManifestHal> hals;
+        if (!parseChildren(root, manifestHalConverter, &hals, error)) {
+            return false;
+        }
+        for (auto&& hal : hals) {
+            hal.setFileName(object->fileName());
+        }
+
         if (object->mType == SchemaType::DEVICE) {
             // tags for device hal manifest only.
             // <sepolicy> can be missing because it can be determined at build time, not hard-coded