assemble_vintf: accept --kernel for manifests.

Add KernelInfo to HalManifest object.

The final verified_assembled_vendor_manifest.xml will contain
<kernel> information for compatibility check during OTA.

Bug: 111125947
Test: build verified_assembled_vendor_manifest.xml

Change-Id: If5a3124b6cbed4da9b2038c30274c223ee52b259
diff --git a/AssembleVintf.cpp b/AssembleVintf.cpp
index 2353216..bcefc73 100644
--- a/AssembleVintf.cpp
+++ b/AssembleVintf.cpp
@@ -206,13 +206,7 @@
     static bool parseFileForKernelConfigs(std::basic_istream<char>& stream,
                                           std::vector<KernelConfig>* out) {
         KernelConfigParser parser(true /* processComments */, true /* relaxedFormat */);
-        std::string content = read(stream);
-        status_t err = parser.process(content.c_str(), content.size());
-        if (err != OK) {
-            std::cerr << parser.error();
-            return false;
-        }
-        err = parser.finish();
+        status_t err = parser.processAndFinish(read(stream));
         if (err != OK) {
             std::cerr << parser.error();
             return false;
@@ -314,6 +308,36 @@
         out() << "-->" << std::endl;
     }
 
+    // Parse --kernel arguments and write to output manifest.
+    bool setDeviceManifestKernel(HalManifest* manifest) {
+        if (mKernels.empty()) {
+            return true;
+        }
+        if (mKernels.size() > 1) {
+            std::cerr << "Warning: multiple --kernel is specified when building device manifest. "
+                      << "Only the first one will be used." << std::endl;
+        }
+        auto& kernelArg = *mKernels.begin();
+        const auto& kernelVer = kernelArg.first;
+        auto& kernelConfigFiles = kernelArg.second;
+        // addKernel() guarantees that !kernelConfigFiles.empty().
+        if (kernelConfigFiles.size() > 1) {
+            std::cerr << "Warning: multiple config files are specified in --kernel when building "
+                      << "device manfiest. Only the first one will be used." << std::endl;
+        }
+
+        KernelConfigParser parser(true /* processComments */, false /* relaxedFormat */);
+        status_t err = parser.processAndFinish(read(kernelConfigFiles[0].stream()));
+        if (err != OK) {
+            std::cerr << parser.error();
+            return false;
+        }
+        manifest->device.mKernel = std::make_optional<KernelInfo>();
+        manifest->device.mKernel->mVersion = kernelVer;
+        manifest->device.mKernel->mConfigs = parser.configs();
+        return true;
+    }
+
     bool assembleHalManifest(HalManifests* halManifests) {
         std::string error;
         HalManifest* halManifest = &halManifests->front().object;
@@ -364,6 +388,10 @@
             if (!setDeviceFcmVersion(halManifest)) {
                 return false;
             }
+
+            if (!setDeviceManifestKernel(halManifest)) {
+                return false;
+            }
         }
 
         if (halManifest->mType == SchemaType::FRAMEWORK) {