Rework compat check of ManifestHal vs. MatrixHal

<interface> and <instance> in a compatibility-matrix.hal
also needs to be checked in a manifest.hal. Specifically,
all instances specified in compatibility-matrix.hal
must be present in manifest.hal, although they can span
across different tag elements. See tests for samples.

For details, see:

    go/android-treble-vintf-object

Test: libvintf_test
Test: vintf_object_test
Bug: 38395193
Change-Id: Ia009c5a1d779818594efc4c7f485d9fe4f23ed55
Merged-In: Ia009c5a1d779818594efc4c7f485d9fe4f23ed55
diff --git a/test/main.cpp b/test/main.cpp
index 9bdaead..63d0bf5 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -681,6 +681,240 @@
     EXPECT_EQ(getAvb(cm), Version(0, 0));
 }
 
+// This is the test extracted from VINTF Object doc
+TEST_F(LibVintfTest, HalCompat) {
+    CompatibilityMatrix matrix;
+    std::string error;
+
+    std::string matrixXml =
+            "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+            "    <hal format=\"hidl\" optional=\"false\">\n"
+            "        <name>android.hardware.foo</name>\n"
+            "        <version>1.0</version>\n"
+            "        <version>3.1-2</version>\n"
+            "        <interface>\n"
+            "            <name>IFoo</name>\n"
+            "            <instance>default</instance>\n"
+            "            <instance>specific</instance>\n"
+            "        </interface>\n"
+            "    </hal>\n"
+            "    <hal format=\"hidl\" optional=\"false\">\n"
+            "        <name>android.hardware.foo</name>\n"
+            "        <version>2.0</version>\n"
+            "        <interface>\n"
+            "            <name>IBar</name>\n"
+            "            <instance>default</instance>\n"
+            "        </interface>\n"
+            "    </hal>\n"
+            "    <sepolicy>\n"
+            "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+            "        <sepolicy-version>25.5</sepolicy-version>\n"
+            "    </sepolicy>\n"
+            "</compatibility-matrix>\n";
+    EXPECT_TRUE(gCompatibilityMatrixConverter(&matrix, matrixXml))
+            << gCompatibilityMatrixConverter.lastError();
+
+    {
+        std::string manifestXml =
+                "<manifest version=\"1.0\" type=\"device\">\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>specific</instance>\n"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <hal format=\"hidl\">\n"
+                "        <name>android.hardware.foo</name>\n"
+                "        <transport>hwbinder</transport>\n"
+                "        <version>2.0</version>\n"
+                "        <interface>\n"
+                "            <name>IBar</name>\n"
+                "            <instance>default</instance>\n"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <sepolicy>\n"
+                "        <version>25.5</version>\n"
+                "    </sepolicy>\n"
+                "</manifest>\n";
+
+        HalManifest manifest;
+        EXPECT_TRUE(gHalManifestConverter(&manifest, manifestXml));
+        EXPECT_TRUE(manifest.checkCompatibility(matrix, &error)) << error;
+    }
+
+    {
+        std::string manifestXml =
+                "<manifest version=\"1.0\" type=\"device\">\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>specific</instance>\n"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <sepolicy>\n"
+                "        <version>25.5</version>\n"
+                "    </sepolicy>\n"
+                "</manifest>\n";
+        HalManifest manifest;
+        EXPECT_TRUE(gHalManifestConverter(&manifest, manifestXml));
+        EXPECT_FALSE(manifest.checkCompatibility(matrix, &error))
+                << "should not be compatible because IBar is missing";
+    }
+
+    {
+        std::string manifestXml =
+                "<manifest version=\"1.0\" type=\"device\">\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"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <hal format=\"hidl\">\n"
+                "        <name>android.hardware.foo</name>\n"
+                "        <transport>hwbinder</transport>\n"
+                "        <version>2.0</version>\n"
+                "        <interface>\n"
+                "            <name>IBar</name>\n"
+                "            <instance>default</instance>\n"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <sepolicy>\n"
+                "        <version>25.5</version>\n"
+                "    </sepolicy>\n"
+                "</manifest>\n";
+        HalManifest manifest;
+        EXPECT_TRUE(gHalManifestConverter(&manifest, manifestXml));
+        EXPECT_FALSE(manifest.checkCompatibility(matrix, &error))
+                << "should not be compatible because IFoo/default is missing";
+    }
+
+    {
+        std::string manifestXml =
+                "<manifest version=\"1.0\" type=\"device\">\n"
+                "    <hal format=\"hidl\">\n"
+                "        <name>android.hardware.foo</name>\n"
+                "        <transport>hwbinder</transport>\n"
+                "        <version>3.3</version>\n"
+                "        <interface>\n"
+                "            <name>IFoo</name>\n"
+                "            <instance>default</instance>\n"
+                "            <instance>specific</instance>\n"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <hal format=\"hidl\">\n"
+                "        <name>android.hardware.foo</name>\n"
+                "        <transport>hwbinder</transport>\n"
+                "        <version>2.0</version>\n"
+                "        <interface>\n"
+                "            <name>IBar</name>\n"
+                "            <instance>default</instance>\n"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <sepolicy>\n"
+                "        <version>25.5</version>\n"
+                "    </sepolicy>\n"
+                "</manifest>\n";
+        HalManifest manifest;
+        EXPECT_TRUE(gHalManifestConverter(&manifest, manifestXml));
+        EXPECT_TRUE(manifest.checkCompatibility(matrix, &error)) << error;
+    }
+
+    {
+        std::string manifestXml =
+                "<manifest version=\"1.0\" type=\"device\">\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"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <hal format=\"hidl\">\n"
+                "        <name>android.hardware.foo</name>\n"
+                "        <transport>hwbinder</transport>\n"
+                "        <version>3.2</version>\n"
+                "        <interface>\n"
+                "            <name>IFoo</name>\n"
+                "            <instance>specific</instance>\n"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <hal format=\"hidl\">\n"
+                "        <name>android.hardware.foo</name>\n"
+                "        <transport>hwbinder</transport>\n"
+                "        <version>2.0</version>\n"
+                "        <interface>\n"
+                "            <name>IBar</name>\n"
+                "            <instance>default</instance>\n"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <sepolicy>\n"
+                "        <version>25.5</version>\n"
+                "    </sepolicy>\n"
+                "</manifest>\n";
+        HalManifest manifest;
+        EXPECT_TRUE(gHalManifestConverter(&manifest, manifestXml));
+        EXPECT_FALSE(manifest.checkCompatibility(matrix, &error))
+                << "should not be compatible even though @1.0::IFoo/default "
+                << "and @3.2::IFoo/specific present";
+    }
+
+    {
+        std::string manifestXml =
+                "<manifest version=\"1.0\" type=\"device\">\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"
+                "        </interface>\n"
+                "    </hal>\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>specific</instance>\n"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <hal format=\"hidl\">\n"
+                "        <name>android.hardware.foo</name>\n"
+                "        <transport>hwbinder</transport>\n"
+                "        <version>2.0</version>\n"
+                "        <interface>\n"
+                "            <name>IBar</name>\n"
+                "            <instance>default</instance>\n"
+                "        </interface>\n"
+                "    </hal>\n"
+                "    <sepolicy>\n"
+                "        <version>25.5</version>\n"
+                "    </sepolicy>\n"
+                "</manifest>\n";
+        HalManifest manifest;
+        EXPECT_TRUE(gHalManifestConverter(&manifest, manifestXml));
+        EXPECT_FALSE(manifest.checkCompatibility(matrix, &error))
+                << "should be compatible even though @1.0::IFoo/default "
+                << "and @1.0::IFoo/specific are splitted in two <hal>: "
+                << error;
+    }
+}
+
 TEST_F(LibVintfTest, Compat) {
     std::string manifestXml =
         "<manifest version=\"1.0\" type=\"device\">\n"
@@ -728,11 +962,24 @@
         "        <name>android.hardware.camera</name>\n"
         "        <version>2.0-5</version>\n"
         "        <version>3.4-16</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\" optional=\"false\">\n"
         "        <name>android.hardware.nfc</name>\n"
         "        <version>1.0</version>\n"
         "        <version>2.0</version>\n"
+        "        <interface>\n"
+        "            <name>INfc</name>\n"
+        "            <instance>nfc_nci</instance>\n"
+        "        </interface>\n"
         "    </hal>\n"
         "    <hal format=\"hidl\" optional=\"true\">\n"
         "        <name>android.hardware.foo</name>\n"