Revert "Revert "Create assemble_vintf""

Test: builds on mac

This reverts commit dbb9a780e050221fbedbf5bfdf3286994511c07c.

Bug: 36456394
Bug: 36983271
Bug: 36681384

Change-Id: Id01227fd856f56890fdf13035d04054cd2446e75
Merged-In: Id01227fd856f56890fdf13035d04054cd2446e75
diff --git a/Android.bp b/Android.bp
index 9f7de8a..cdc1c34 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,14 +23,13 @@
 
 cc_library {
     name: "libvintf",
+    host_supported: true,
     cflags: libvintf_flags,
     shared_libs: [
         "libbase",
         "liblog",
         "libselinux",
         "libtinyxml2",
-        "libutils",
-        "libz",
     ],
     export_include_dirs: ["include"],
     local_include_dirs: ["include/vintf"],
@@ -48,6 +47,21 @@
         "TransportArch.cpp",
         "VintfObject.cpp",
     ],
+
+    target: {
+        linux: {
+            shared_libs: [
+                "libz-host",
+            ],
+        },
+        android: {
+            shared_libs: [
+                "libutils",
+                "libz"
+            ],
+            cflags: ["-DLIBVINTF_TARGET"],
+        },
+    }
 }
 
 cc_binary {
@@ -55,9 +69,19 @@
     cflags: libvintf_flags,
     shared_libs: [
         "libvintf",
-        "libselinux",
     ],
     srcs: [
         "main.cpp"
     ],
 }
+
+cc_binary_host {
+    name: "assemble_vintf",
+    cflags: libvintf_flags,
+    shared_libs: [
+        "libvintf"
+    ],
+    srcs: [
+        "assemble_vintf.cpp"
+    ],
+}
diff --git a/RuntimeInfo.cpp b/RuntimeInfo.cpp
index c14ea95..8e6662c 100644
--- a/RuntimeInfo.cpp
+++ b/RuntimeInfo.cpp
@@ -136,7 +136,12 @@
 }
 
 status_t RuntimeInfoFetcher::fetchKernelSepolicyVers() {
-    int pv = security_policyvers();
+    int pv;
+#ifdef LIBVINTF_TARGET
+    pv = security_policyvers();
+#else
+    pv = 0;
+#endif
     if (pv < 0) {
         return pv;
     }
diff --git a/assemble_vintf.cpp b/assemble_vintf.cpp
new file mode 100644
index 0000000..d3846a2
--- /dev/null
+++ b/assemble_vintf.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <fstream>
+#include <iostream>
+#include <unordered_map>
+#include <sstream>
+#include <string>
+
+#include <vintf/parse_string.h>
+#include <vintf/parse_xml.h>
+
+namespace android {
+namespace vintf {
+
+/**
+ * Slurps the device manifest file and add build time flag to it.
+ */
+class AssembleVintf {
+public:
+    template<typename T>
+    static bool getFlag(const std::string& key, T* value) {
+        const char *envValue = getenv(key.c_str());
+        if (envValue == NULL) {
+            std::cerr << "Required " << key << " flag." << std::endl;
+            return false;
+        }
+
+        if (!parse(envValue, value)) {
+            std::cerr << "Cannot parse " << envValue << "." << std::endl;
+            return false;
+        }
+        return true;
+    }
+
+    static bool assemble(std::basic_istream<char>& inFile, std::basic_ostream<char>& outFile) {
+        std::stringstream ss;
+        ss << inFile.rdbuf();
+        std::string fileContent = ss.str();
+
+        HalManifest halManifest;
+        if (!gHalManifestConverter(&halManifest, fileContent)) {
+            std::cerr << "Illformed HAL manifest: " << gHalManifestConverter.lastError()
+                    << std::endl;
+            return false;
+        }
+
+        if (halManifest.mType == SchemaType::DEVICE) {
+            if (!getFlag("BOARD_SEPOLICY_VERS", &halManifest.device.mSepolicyVersion)) {
+                return false;
+            }
+        }
+
+        std::string outFileContent = gHalManifestConverter(halManifest);
+        outFile << outFileContent;
+        outFile.flush();
+
+        return true;
+    }
+};
+
+}  // namespace vintf
+}  // namespace android
+
+void help() {
+    std::cerr <<
+        "assemble_vintf -h\n"
+        "               Display this help text.\n"
+        "assemble_vintf -i <input file> [-o <output file>]\n"
+        "               Fill in build-time flags into the given manifest.\n"
+        "               If no designated output file, write to stdout.\n";
+}
+
+int main(int argc, char **argv) {
+    std::ifstream inFile;
+    std::ofstream outFile;
+    std::ostream* outFileRef = &std::cout;
+    int res;
+    while((res = getopt(argc, argv, "hi:o:v:")) >= 0) {
+        switch (res) {
+            case 'i': {
+                inFile.open(optarg);
+                if (!inFile.is_open()) {
+                    std::cerr << "Failed to open " << optarg << std::endl;
+                    return 1;
+                }
+            } break;
+
+            case 'o': {
+                outFile.open(optarg);
+                if (!outFile.is_open()) {
+                    std::cerr << "Failed to open " << optarg << std::endl;
+                    return 1;
+                }
+                outFileRef = &outFile;
+            } break;
+
+            case 'h':
+            default: {
+                help();
+                return 1;
+            } break;
+        }
+    }
+
+    if (!inFile.is_open()) {
+        std::cerr << "Missing input file" << std::endl;
+        help();
+        return 1;
+    }
+
+    return ::android::vintf::AssembleVintf::assemble(inFile, *outFileRef)
+            ? 0 : 1;
+}
+