assemble_vintf supports DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILES

Relax multiple cases that were previously flagged as error
to allow combining matrices that doesn't have a "level"
attribute. Specifically, all HALs in matrices without a specific
FCM version are added as-is.

Test: m framework_compatibility_matrix.xml -j
Test: libvintf_test
Test: vintf_object_test
Bug: 65028233

Change-Id: Ifa947529731ab17d705be945139de504db2d0253
Merged-In: Ifa947529731ab17d705be945139de504db2d0253
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp
index 88ecd26..451ca60 100644
--- a/CompatibilityMatrix.cpp
+++ b/CompatibilityMatrix.cpp
@@ -215,35 +215,25 @@
 // as a base matrix.
 CompatibilityMatrix* CompatibilityMatrix::findOrInsertBaseMatrix(
     std::vector<Named<CompatibilityMatrix>>* matrices, std::string* error) {
-    bool multipleFound = false;
-    CompatibilityMatrix* matrix = nullptr;
+    std::vector<CompatibilityMatrix*> matricesUnspecified;
+    std::vector<CompatibilityMatrix*> matricesEmpty;
     for (auto& e : *matrices) {
         if (e.object.level() == Level::UNSPECIFIED) {
+            matricesUnspecified.push_back(&e.object);
+
             if (!e.object.mHals.empty()) {
-                if (error) {
-                    *error = "Error: File \"" + e.name + "\" should not contain " + "HAL elements.";
-                }
-                return nullptr;
+                continue;
             }
 
             if (!e.object.mXmlFiles.empty()) {
-                if (error) {
-                    *error =
-                        "Error: File \"" + e.name + "\" should not contain " + "XML File elements.";
-                }
-                return nullptr;
+                continue;
             }
 
-            if (matrix != nullptr) {
-                multipleFound = true;
-            }
-
-            matrix = &e.object;
-            // continue to detect multiple files with "unspecified" levels
+            matricesEmpty.push_back(&e.object);
         }
     }
 
-    if (multipleFound) {
+    if (matricesEmpty.size() > 1) {
         if (error) {
             *error =
                 "Error: multiple framework compatibility matrix files have "
@@ -256,25 +246,21 @@
         }
         return nullptr;
     }
-
-    if (matrix == nullptr) {
-        matrix = &matrices->emplace(matrices->end())->object;
-        matrix->mType = SchemaType::FRAMEWORK;
-        matrix->mLevel = Level::UNSPECIFIED;
+    if (matricesEmpty.size() == 1) {
+        return matricesEmpty.front();
     }
-
+    if (!matricesUnspecified.empty()) {
+        return matricesUnspecified.front();
+    }
+    auto matrix = &matrices->emplace(matrices->end())->object;
+    matrix->mType = SchemaType::FRAMEWORK;
+    matrix->mLevel = Level::UNSPECIFIED;
     return matrix;
 }
 
 CompatibilityMatrix* CompatibilityMatrix::combine(Level deviceLevel,
                                                   std::vector<Named<CompatibilityMatrix>>* matrices,
                                                   std::string* error) {
-    if (deviceLevel == Level::UNSPECIFIED) {
-        if (error) {
-            *error = "Error: device level is unspecified.";
-        }
-        return nullptr;
-    }
 
     CompatibilityMatrix* matrix = findOrInsertBaseMatrix(matrices, error);
     if (matrix == nullptr) {
@@ -284,7 +270,8 @@
     matrix->mLevel = deviceLevel;
 
     for (auto& e : *matrices) {
-        if (&e.object != matrix && e.object.level() == deviceLevel) {
+        if (&e.object != matrix &&
+            (e.object.level() == deviceLevel || e.object.level() == Level::UNSPECIFIED)) {
             if (!matrix->addAllHals(&e.object, error)) {
                 if (error) {
                     *error = "File \"" + e.name + "\" cannot be added: HAL " + *error +