Create a way to easily generate a compatibility matrix.

Test: BOARD_SEPOLICY_VERS=10000.0 assemble_vintf -i
      device/.../.../manifest.xml -m
Test: assemble_vintf -i system/libhidl/manifest.xml -m

Bug: 33633372
Bug: 37321309

Change-Id: I9b786040cff70cfcb495078f4277b6aae1b56ba5
diff --git a/assemble_vintf.cpp b/assemble_vintf.cpp
index d3846a2..cfa9bf6 100644
--- a/assemble_vintf.cpp
+++ b/assemble_vintf.cpp
@@ -49,7 +49,9 @@
         return true;
     }
 
-    static bool assemble(std::basic_istream<char>& inFile, std::basic_ostream<char>& outFile) {
+    static bool assemble(std::basic_istream<char>& inFile,
+                         std::basic_ostream<char>& outFile,
+                         bool isMatrix) {
         std::stringstream ss;
         ss << inFile.rdbuf();
         std::string fileContent = ss.str();
@@ -67,8 +69,25 @@
             }
         }
 
-        std::string outFileContent = gHalManifestConverter(halManifest);
-        outFile << outFileContent;
+        if (isMatrix) {
+            CompatibilityMatrix mat = halManifest.generateCompatibleMatrix();
+            std::string error;
+            if (!halManifest.checkCompatibility(mat, &error)) {
+                std::cerr << "FATAL ERROR: cannot generate a compatible matrix: "
+                          << error << std::endl;
+            }
+            outFile << "<!-- \n"
+                       "    Autogenerated skeleton compatibility matrix. \n"
+                       "    Use with caution. Modify it to suit your needs.\n"
+                       "    All HALs are set to optional.\n"
+                       "    Many entries other than HALs are zero-filled and\n"
+                       "    require human attention. \n"
+                       "-->\n"
+                    << gCompatibilityMatrixConverter(mat);
+        } else {
+            outFile << gHalManifestConverter(halManifest);
+        }
+
         outFile.flush();
 
         return true;
@@ -82,17 +101,20 @@
     std::cerr <<
         "assemble_vintf -h\n"
         "               Display this help text.\n"
-        "assemble_vintf -i <input file> [-o <output file>]\n"
+        "assemble_vintf -i <input file> [-o <output file>] [-m]\n"
         "               Fill in build-time flags into the given manifest.\n"
-        "               If no designated output file, write to stdout.\n";
+        "               If no designated output file, write to stdout.\n"
+        "               If -m is set, a compatible compatibility matrix is\n"
+        "               generated instead.\n";
 }
 
 int main(int argc, char **argv) {
     std::ifstream inFile;
     std::ofstream outFile;
     std::ostream* outFileRef = &std::cout;
+    bool isMatrix = false;
     int res;
-    while((res = getopt(argc, argv, "hi:o:v:")) >= 0) {
+    while((res = getopt(argc, argv, "hi:o:m")) >= 0) {
         switch (res) {
             case 'i': {
                 inFile.open(optarg);
@@ -111,6 +133,10 @@
                 outFileRef = &outFile;
             } break;
 
+            case 'm': {
+                isMatrix = true;
+            } break;
+
             case 'h':
             default: {
                 help();
@@ -125,7 +151,7 @@
         return 1;
     }
 
-    return ::android::vintf::AssembleVintf::assemble(inFile, *outFileRef)
+    return ::android::vintf::AssembleVintf::assemble(inFile, *outFileRef, isMatrix)
             ? 0 : 1;
 }