Add <xmlfile> to manifest / comp mat.

manifest.xml is allowed to contain <xmlfile> that is similar to:
<xmlfile>
    <name>media_profile</name>
    <version>1.0</version>
    <path>/path/to/media_profile_v1_0.xml</path>
</xmlfile>

For compatibility-matrix.xml
<xmlfile format="dtd" optional="false">
    <name>media_profile</name>
    <version>1.0-1</version>
    <path>/path/to/media_profile_v1_1.dtd</path>
</xmlfile>

The <path> tag is optional. See test/main.cpp for examples.

Test: libvintf_test
Test: vintf_object_test

Bug: 38359330

Change-Id: I0a921f32d023e1ba9c54ea6e898bb385fc7abd4f
diff --git a/test/main.cpp b/test/main.cpp
index 6ce1e23..090fd3d 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -52,6 +52,14 @@
     bool add(HalManifest &vm, ManifestHal &&hal) {
         return vm.add(std::move(hal));
     }
+    void addXmlFile(CompatibilityMatrix& cm, std::string name, VersionRange range) {
+        MatrixXmlFile f;
+        f.mName = name;
+        f.mVersionRange = range;
+        f.mFormat = XmlSchemaFormat::DTD;
+        f.mOptional = true;
+        cm.addXmlFile(std::move(f));
+    }
     void set(CompatibilityMatrix &cm, Sepolicy &&sepolicy) {
         cm.framework.mSepolicy = sepolicy;
     }
@@ -120,6 +128,14 @@
 
         return vm;
     }
+    HalManifest testDeviceManifestWithXmlFile() {
+        HalManifest vm = testDeviceManifest();
+        ManifestXmlFile xmlFile;
+        xmlFile.mName = "media_profile";
+        xmlFile.mVersion = {1, 0};
+        vm.addXmlFile(std::move(xmlFile));
+        return vm;
+    }
     HalManifest testFrameworkManfiest() {
         HalManifest vm;
         vm.mType = SchemaType::FRAMEWORK;
@@ -1101,6 +1117,87 @@
     EXPECT_TRUE(manifest.checkCompatibility(matrix, &error)) << error;
 }
 
+/////////////////// xmlfile tests
+
+TEST_F(LibVintfTest, HalManifestConverterXmlFile) {
+    HalManifest vm = testDeviceManifestWithXmlFile();
+    std::string xml = gHalManifestConverter(vm);
+    EXPECT_EQ(xml,
+              "<manifest version=\"1.0\" type=\"device\">\n"
+              "    <hal format=\"hidl\">\n"
+              "        <name>android.hardware.camera</name>\n"
+              "        <transport>hwbinder</transport>\n"
+              "        <version>2.0</version>\n"
+              "        <interface>\n"
+              "            <name>IBetterCamera</name>\n"
+              "            <instance>camera</instance>\n"
+              "        </interface>\n"
+              "        <interface>\n"
+              "            <name>ICamera</name>\n"
+              "            <instance>default</instance>\n"
+              "            <instance>legacy/0</instance>\n"
+              "        </interface>\n"
+              "    </hal>\n"
+              "    <hal format=\"hidl\">\n"
+              "        <name>android.hardware.nfc</name>\n"
+              "        <transport arch=\"32+64\">passthrough</transport>\n"
+              "        <version>1.0</version>\n"
+              "        <interface>\n"
+              "            <name>INfc</name>\n"
+              "            <instance>default</instance>\n"
+              "        </interface>\n"
+              "    </hal>\n"
+              "    <sepolicy>\n"
+              "        <version>25.0</version>\n"
+              "    </sepolicy>\n"
+              "    <xmlfile>\n"
+              "        <name>media_profile</name>\n"
+              "        <version>1.0</version>\n"
+              "    </xmlfile>\n"
+              "</manifest>\n");
+    HalManifest vm2;
+    EXPECT_TRUE(gHalManifestConverter(&vm2, xml));
+    EXPECT_EQ(vm, vm2);
+}
+
+TEST_F(LibVintfTest, CompatibilityMatrixConverterXmlFile) {
+    CompatibilityMatrix cm;
+    addXmlFile(cm, "media_profile", {1, 0});
+    std::string xml = gCompatibilityMatrixConverter(cm);
+    EXPECT_EQ(xml,
+              "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+              "    <sepolicy>\n"
+              "        <kernel-sepolicy-version>0</kernel-sepolicy-version>\n"
+              "    </sepolicy>\n"
+              "    <avb>\n"
+              "        <vbmeta-version>0.0</vbmeta-version>\n"
+              "    </avb>\n"
+              "    <xmlfile format=\"dtd\" optional=\"true\">\n"
+              "        <name>media_profile</name>\n"
+              "        <version>1.0</version>\n"
+              "    </xmlfile>\n"
+              "</compatibility-matrix>\n");
+    CompatibilityMatrix cm2;
+    EXPECT_TRUE(gCompatibilityMatrixConverter(&cm2, xml));
+    EXPECT_EQ(cm, cm2);
+}
+
+TEST_F(LibVintfTest, CompatibilityMatrixConverterXmlFile2) {
+    std::string xml =
+        "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+        "    <xmlfile format=\"dtd\" optional=\"false\">\n"
+        "        <name>media_profile</name>\n"
+        "        <version>1.0</version>\n"
+        "    </xmlfile>\n"
+        "</compatibility-matrix>\n";
+    CompatibilityMatrix cm;
+    EXPECT_FALSE(gCompatibilityMatrixConverter(&cm, xml));
+    EXPECT_EQ(
+        "compatibility-matrix.xmlfile entry media_profile has to be optional for "
+        "compatibility matrix version 1.0",
+        gCompatibilityMatrixConverter.lastError());
+}
+
 } // namespace vintf
 } // namespace android