Add <fqname> to manifests.

The format of <fqname> is:
<hal>
    <name>android.hardware.foo</name>
    <!-- transport, etc. -->
    <fqname>@1.0::IFoo/default</fqname>
</hal>

It is possible to mix <fqname> and <version>
x <interface> x <instance> ; see tests for details.

This allows instances at different versions. For example,
it is now allowed to serve @1.0::IFoo/default, @1.1::IFoo/custom
simultaneously without serving @1.1::IFoo/default.

If override="true" and no <version>x<interface>x<instance> nor
<fqname>, the HAL tag is disabled. (Previously, the HAL tag
is disabled iff no <version> exists).

Bug: 73556059
Test: libvintf_test
Test: vintf_object_test

Change-Id: I80cb9ccdeec708c2c5530812913b37f8b3cc3ffa
Merged-In: I80cb9ccdeec708c2c5530812913b37f8b3cc3ffa
diff --git a/test/LibVintfTest.cpp b/test/LibVintfTest.cpp
index 9a243f4..7fc4e2a 100644
--- a/test/LibVintfTest.cpp
+++ b/test/LibVintfTest.cpp
@@ -251,7 +251,8 @@
 
 TEST_F(LibVintfTest, HalManifestConverter) {
     HalManifest vm = testDeviceManifest();
-    std::string xml = gHalManifestConverter(vm);
+    std::string xml =
+        gHalManifestConverter(vm, SerializeFlag::HALS_NO_FQNAME & SerializeFlag::SEPOLICY_ONLY);
     EXPECT_EQ(xml,
         "<manifest version=\"1.0\" type=\"device\">\n"
         "    <hal format=\"hidl\">\n"
@@ -288,7 +289,8 @@
 
 TEST_F(LibVintfTest, HalManifestConverterFramework) {
     HalManifest vm = testFrameworkManfiest();
-    std::string xml = gHalManifestConverter(vm);
+    std::string xml =
+        gHalManifestConverter(vm, SerializeFlag::HALS_NO_FQNAME & SerializeFlag::VNDK_ONLY);
     EXPECT_EQ(xml,
         "<manifest version=\"1.0\" type=\"framework\">\n"
         "    <hal format=\"hidl\">\n"
@@ -1275,7 +1277,9 @@
 
 TEST_F(LibVintfTest, HalManifestConverterXmlFile) {
     HalManifest vm = testDeviceManifestWithXmlFile();
-    std::string xml = gHalManifestConverter(vm);
+    std::string xml =
+        gHalManifestConverter(vm, SerializeFlag::HALS_NO_FQNAME & SerializeFlag::SEPOLICY_ONLY &
+                                      SerializeFlag::XMLFILES_ONLY);
     EXPECT_EQ(xml,
               "<manifest version=\"1.0\" type=\"device\">\n"
               "    <hal format=\"hidl\">\n"
@@ -2435,7 +2439,7 @@
     EXPECT_TRUE(gHalManifestConverter(&newManifest, xml)) << gHalManifestConverter.lastError();
 
     manifest.addAllHals(&newManifest);
-    EXPECT_EQ(xml, gHalManifestConverter(manifest, SerializeFlag::HALS_ONLY));
+    EXPECT_EQ(xml, gHalManifestConverter(manifest, SerializeFlag::HALS_NO_FQNAME));
 }
 
 TEST_F(LibVintfTest, ManifestAddOverrideHalSimpleOverride) {
@@ -2466,7 +2470,7 @@
     EXPECT_TRUE(gHalManifestConverter(&newManifest, xml)) << gHalManifestConverter.lastError();
 
     manifest.addAllHals(&newManifest);
-    EXPECT_EQ(xml, gHalManifestConverter(manifest, SerializeFlag::HALS_ONLY));
+    EXPECT_EQ(xml, gHalManifestConverter(manifest, SerializeFlag::HALS_NO_FQNAME));
 }
 
 // Existing major versions should be removed.
@@ -2536,7 +2540,7 @@
         "        </interface>\n"
         "    </hal>\n"
         "</manifest>\n",
-        gHalManifestConverter(manifest, SerializeFlag::HALS_ONLY));
+        gHalManifestConverter(manifest, SerializeFlag::HALS_NO_FQNAME));
 }
 
 TEST_F(LibVintfTest, ManifestAddOverrideHalMultiVersion2) {
@@ -2573,7 +2577,7 @@
     EXPECT_TRUE(gHalManifestConverter(&newManifest, xml)) << gHalManifestConverter.lastError();
 
     manifest.addAllHals(&newManifest);
-    EXPECT_EQ(xml, gHalManifestConverter(manifest, SerializeFlag::HALS_ONLY));
+    EXPECT_EQ(xml, gHalManifestConverter(manifest, SerializeFlag::HALS_NO_FQNAME));
 }
 
 // if no <versions>, remove all existing <hal> with given <name>.
@@ -2843,6 +2847,7 @@
     xml =
         "<manifest version=\"1.0\" type=\"framework\">\n"
         "    <hal format=\"hidl\" override=\"true\">\n"
+        "        <transport>hwbinder</transport>\n"
         "        <name>android.hardware.foo</name>\n"
         "        <transport>hwbinder</transport>\n"
         "    </hal>\n"
@@ -2869,6 +2874,169 @@
     EXPECT_FALSE(baz.front()->isDisabledHal());
 }
 
+TEST_F(LibVintfTest, FqNameValid) {
+    std::string error;
+    std::string xml;
+
+    CompatibilityMatrix cm;
+    xml =
+        "<compatibility-matrix version=\"1.0\" type=\"device\">\n"
+        "    <hal format=\"hidl\" optional=\"false\">\n"
+        "        <name>android.hardware.foo</name>\n"
+        "        <version>1.0</version>\n"
+        "        <interface>\n"
+        "            <name>IFoo</name>\n"
+        "            <instance>default</instance>\n"
+        "        </interface>\n"
+        "    </hal>\n"
+        "    <hal format=\"hidl\" optional=\"false\">\n"
+        "        <name>android.hardware.foo</name>\n"
+        "        <version>1.1</version>\n"
+        "        <interface>\n"
+        "            <name>IFoo</name>\n"
+        "            <instance>custom</instance>\n"
+        "        </interface>\n"
+        "    </hal>\n"
+        "</compatibility-matrix>\n";
+    EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml, &error)) << error;
+
+    {
+        HalManifest manifest;
+        xml =
+            "<manifest version=\"1.0\" type=\"framework\">\n"
+            "    <hal format=\"hidl\">\n"
+            "        <name>android.hardware.foo</name>\n"
+            "        <transport>hwbinder</transport>\n"
+            "        <version>1.0</version>\n"
+            "        <interface>\n"
+            "            <name>IFoo</name>\n"
+            "            <instance>default</instance>\n"
+            "            <instance>custom</instance>\n"
+            "        </interface>\n"
+            "        <fqname>@1.1::IFoo/custom</fqname>\n"
+            "    </hal>\n"
+            "</manifest>\n";
+        ASSERT_TRUE(gHalManifestConverter(&manifest, xml, &error)) << error;
+        EXPECT_TRUE(manifest.checkCompatibility(cm, &error)) << error;
+    }
+
+    {
+        HalManifest manifest;
+        xml =
+            "<manifest version=\"1.0\" type=\"framework\">\n"
+            "    <hal format=\"hidl\">\n"
+            "        <name>android.hardware.foo</name>\n"
+            "        <transport>hwbinder</transport>\n"
+            "        <fqname>@1.0::IFoo/default</fqname>\n"
+            "        <fqname>@1.1::IFoo/custom</fqname>\n"
+            "    </hal>\n"
+            "</manifest>\n";
+        ASSERT_TRUE(gHalManifestConverter(&manifest, xml, &error)) << error;
+        EXPECT_TRUE(manifest.checkCompatibility(cm, &error)) << error;
+    }
+
+    {
+        HalManifest manifest;
+        xml =
+            "<manifest version=\"1.0\" type=\"framework\">\n"
+            "    <hal format=\"hidl\">\n"
+            "        <name>android.hardware.foo</name>\n"
+            "        <transport>hwbinder</transport>\n"
+            "        <version>1.0</version>\n"
+            "        <interface>\n"
+            "            <name>IFoo</name>\n"
+            "            <instance>default</instance>\n"
+            "            <instance>custom</instance>\n"
+            "        </interface>\n"
+            "    </hal>\n"
+            "</manifest>\n";
+        ASSERT_TRUE(gHalManifestConverter(&manifest, xml, &error)) << error;
+        EXPECT_FALSE(manifest.checkCompatibility(cm, &error));
+        EXPECT_IN(
+            "android.hardware.foo:\n"
+            "    required: @1.1::IFoo/custom\n"
+            "    provided: \n"
+            "        @1.0::IFoo/custom\n"
+            "        @1.0::IFoo/default",
+            error);
+    }
+
+    {
+        HalManifest manifest;
+        xml =
+            "<manifest version=\"1.0\" type=\"framework\">\n"
+            "    <hal format=\"hidl\">\n"
+            "        <name>android.hardware.foo</name>\n"
+            "        <transport>hwbinder</transport>\n"
+            "        <fqname>@1.0::IFoo/default</fqname>\n"
+            "        <fqname>@1.0::IFoo/custom</fqname>\n"
+            "    </hal>\n"
+            "</manifest>\n";
+        ASSERT_TRUE(gHalManifestConverter(&manifest, xml, &error)) << error;
+        EXPECT_IN(
+            "android.hardware.foo:\n"
+            "    required: @1.1::IFoo/custom\n"
+            "    provided: \n"
+            "        @1.0::IFoo/custom\n"
+            "        @1.0::IFoo/default",
+            error);
+    }
+}
+
+TEST_F(LibVintfTest, FqNameInvalid) {
+    std::string error;
+    std::string xml;
+    ManifestHal hal;
+    xml =
+        "<hal format=\"hidl\">\n"
+        "    <name>android.hardware.foo</name>\n"
+        "    <transport>hwbinder</transport>\n"
+        "    <fqname>@1.1::IFoo/custom</fqname>\n"
+        "</hal>\n";
+    EXPECT_TRUE(gManifestHalConverter(&hal, xml, &error)) << error;
+    xml =
+        "<hal format=\"hidl\">\n"
+        "    <name>android.hardware.foo</name>\n"
+        "    <transport>hwbinder</transport>\n"
+        "    <fqname>1.1::IFoo/custom</fqname>\n"
+        "</hal>\n";
+    ASSERT_FALSE(gManifestHalConverter(&hal, xml, &error));
+    EXPECT_IN("Could not parse text \"1.1::IFoo/custom\" in element <fqname>", error);
+    xml =
+        "<hal format=\"hidl\">\n"
+        "    <name>android.hardware.foo</name>\n"
+        "    <transport>hwbinder</transport>\n"
+        "    <fqname>android.hardware.foo@1.1::IFoo/custom</fqname>\n"
+        "</hal>\n";
+    ASSERT_FALSE(gManifestHalConverter(&hal, xml, &error));
+    EXPECT_IN("Should not specify package", error);
+    xml =
+        "<hal format=\"hidl\">\n"
+        "    <name>android.hardware.foo</name>\n"
+        "    <transport>hwbinder</transport>\n"
+        "    <fqname>IFoo/custom</fqname>\n"
+        "</hal>\n";
+    ASSERT_FALSE(gManifestHalConverter(&hal, xml, &error));
+    EXPECT_IN("Should specify version", error);
+    xml =
+        "<hal format=\"hidl\">\n"
+        "    <name>android.hardware.foo</name>\n"
+        "    <transport>hwbinder</transport>\n"
+        "    <fqname>@1.0::IFoo</fqname>\n"
+        "</hal>\n";
+    ASSERT_FALSE(gManifestHalConverter(&hal, xml, &error));
+    EXPECT_IN("Should specify instance", error);
+    xml =
+        "<hal format=\"hidl\">\n"
+        "    <name>n07 4 v4l1d 1n73rf4c3</name>\n"
+        "    <transport>hwbinder</transport>\n"
+        "    <fqname>@1.0::IFoo/custom</fqname>\n"
+        "</hal>\n";
+    ASSERT_FALSE(gManifestHalConverter(&hal, xml, &error));
+    EXPECT_IN("Cannot create FqInstance", error);
+    EXPECT_IN("n07 4 v4l1d 1n73rf4c3", error);
+}
+
 } // namespace vintf
 } // namespace android