Add <sepolicy> tag to HalManifest.

Test: libvintf_test

Bug: 36456394

Change-Id: If85aabc87c42d5afbe3b230dde8b3cbe8fbd8eb6
diff --git a/include/vintf/HalManifest.h b/include/vintf/HalManifest.h
index a260d00..7618a1e 100644
--- a/include/vintf/HalManifest.h
+++ b/include/vintf/HalManifest.h
@@ -114,6 +114,7 @@
 
     // entries for device hal manifest only
     struct {
+        Version mSepolicyVersion;
     } device;
 };
 
diff --git a/parse_xml.cpp b/parse_xml.cpp
index 7500797..64c3721 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -539,12 +539,26 @@
 };
 const SepolicyConverter sepolicyConverter{};
 
+struct HalManifestSepolicyConverter : public XmlNodeConverter<Version> {
+    std::string elementName() const override { return "sepolicy"; }
+    void mutateNode(const Version &m, NodeType *root, DocType *d) const override {
+        appendChild(root, versionConverter(m, d));
+    }
+    bool buildObject(Version *object, NodeType *root) const override {
+        return parseChild(root, versionConverter, object);
+    }
+};
+const HalManifestSepolicyConverter halManifestSepolicyConverter{};
+
 struct HalManifestConverter : public XmlNodeConverter<HalManifest> {
     std::string elementName() const override { return "manifest"; }
     void mutateNode(const HalManifest &m, NodeType *root, DocType *d) const override {
         appendAttr(root, "version", HalManifest::kVersion);
         appendAttr(root, "type", m.mType);
         appendChildren(root, manifestHalConverter, m.getHals(), d);
+        if (m.mType == SchemaType::DEVICE) {
+            appendChild(root, halManifestSepolicyConverter(m.device.mSepolicyVersion, d));
+        }
     }
     bool buildObject(HalManifest *object, NodeType *root) const override {
         Version version;
@@ -558,6 +572,14 @@
             this->mLastError = "Unrecognized manifest.version";
             return false;
         }
+        if (object->mType == SchemaType::DEVICE) {
+            // tags for device hal manifest only.
+            // TODO(b/36456394): should not allow <sepolicy> to be missing.
+            if (!parseOptionalChild(root, halManifestSepolicyConverter, {},
+                    &object->device.mSepolicyVersion)) {
+                return false;
+            }
+        }
         for (auto &&hal : hals) {
             if (!object->add(std::move(hal))) {
                 this->mLastError = "Duplicated manifest.hal entry";
diff --git a/test/main.cpp b/test/main.cpp
index 582ac19..f73c2db 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -69,6 +69,7 @@
     HalManifest testHalManifest() {
         HalManifest vm;
         vm.mType = SchemaType::DEVICE;
+        vm.device.mSepolicyVersion = {25, 0};
         vm.add(ManifestHal{
             .format = HalFormat::HIDL,
             .name = "android.hardware.camera",
@@ -155,6 +156,9 @@
         "            <instance>default</instance>\n"
         "        </interface>\n"
         "    </hal>\n"
+        "    <sepolicy>\n"
+        "        <version>25.0</version>\n"
+        "    </sepolicy>\n"
         "</manifest>\n");
 }