assemble_vintf: add --no-kernel-requirements option
am: 86678e40bc

Change-Id: I7a4d7a80bf9ae013f33911dd33682af079d098ff
diff --git a/AssembleVintf.cpp b/AssembleVintf.cpp
index ea8c9b3..b54b971 100644
--- a/AssembleVintf.cpp
+++ b/AssembleVintf.cpp
@@ -678,6 +678,12 @@
         return true;
     }
 
+    bool setNoKernelRequirements() override {
+        mSerializeFlags |= SerializeFlag::NO_KERNEL_CONFIGS;
+        mSerializeFlags |= SerializeFlag::NO_KERNEL_MINOR_REVISION;
+        return true;
+    }
+
    private:
     std::vector<NamedIstream> mInFiles;
     Ostream mOutRef;
diff --git a/assemble_vintf_main.cpp b/assemble_vintf_main.cpp
index e84aaaf..2733261 100644
--- a/assemble_vintf_main.cpp
+++ b/assemble_vintf_main.cpp
@@ -63,7 +63,10 @@
                  "               Output has only <hal> entries. Cannot be used with -n.\n"
                  "    -n, --no-hals\n"
                  "               Output has no <hal> entries (but all other entries).\n"
-                 "               Cannot be used with -l.\n";
+                 "               Cannot be used with -l.\n"
+                 "    --no-kernel-requirements\n"
+                 "               Output has no <config> entries in <kernel>, and kernel minor\n"
+                 "               version is set to zero. (For example, 3.18.0).\n";
 }
 
 int main(int argc, char** argv) {
@@ -71,6 +74,7 @@
     const struct option longopts[] = {{"kernel", required_argument, NULL, 'k'},
                                       {"hals-only", no_argument, NULL, 'l'},
                                       {"no-hals", no_argument, NULL, 'n'},
+                                      {"no-kernel-requirements", no_argument, NULL, 'K'},
                                       {0, 0, 0, 0}};
 
     std::string outFilePath;
@@ -126,6 +130,12 @@
                 }
             } break;
 
+            case 'K': {
+                if (!assembleVintf->setNoKernelRequirements()) {
+                    return 1;
+                }
+            } break;
+
             case 'h':
             default: {
                 help();
diff --git a/include-test/vintf/AssembleVintf.h b/include-test/vintf/AssembleVintf.h
index ac6d2af..56b4811 100644
--- a/include-test/vintf/AssembleVintf.h
+++ b/include-test/vintf/AssembleVintf.h
@@ -38,6 +38,7 @@
     virtual ~AssembleVintf() = default;
     virtual bool setHalsOnly() = 0;
     virtual bool setNoHals() = 0;
+    virtual bool setNoKernelRequirements() = 0;
     virtual void setOutputMatrix() = 0;
     virtual bool assemble() = 0;
 
diff --git a/include/vintf/parse_xml.h b/include/vintf/parse_xml.h
index 578e15b..744a2e7 100644
--- a/include/vintf/parse_xml.h
+++ b/include/vintf/parse_xml.h
@@ -32,6 +32,8 @@
     NO_XMLFILES = 1 << 5,
     NO_SSDK = 1 << 6,
     NO_FQNAME = 1 << 7,
+    NO_KERNEL_CONFIGS = 1 << 8,
+    NO_KERNEL_MINOR_REVISION = 1 << 9,
 
     EVERYTHING = 0,
     HALS_ONLY = ~(NO_HALS | NO_FQNAME),  // <hal> with <fqname>
diff --git a/parse_xml.cpp b/parse_xml.cpp
index fbac04e..7947fc3 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -601,12 +601,23 @@
 
 struct MatrixKernelConverter : public XmlNodeConverter<MatrixKernel> {
     std::string elementName() const override { return "kernel"; }
-    void mutateNode(const MatrixKernel &kernel, NodeType *root, DocType *d) const override {
-        appendAttr(root, "version", kernel.mMinLts);
+    void mutateNode(const MatrixKernel& kernel, NodeType* root, DocType* d) const override {
+        mutateNode(kernel, root, d, SerializeFlag::EVERYTHING);
+    }
+    void mutateNode(const MatrixKernel& kernel, NodeType* root, DocType* d,
+                    SerializeFlags flags) const override {
+        KernelVersion kv = kernel.mMinLts;
+        if (flags & SerializeFlag::NO_KERNEL_MINOR_REVISION) {
+            kv.minorRev = 0u;
+        }
+        appendAttr(root, "version", kv);
+
         if (!kernel.mConditions.empty()) {
             appendChild(root, matrixKernelConditionsConverter(kernel.mConditions, d));
         }
-        appendChildren(root, kernelConfigConverter, kernel.mConfigs, d);
+        if (!(flags & SerializeFlag::NO_KERNEL_CONFIGS)) {
+            appendChildren(root, kernelConfigConverter, kernel.mConfigs, d);
+        }
     }
     bool buildObject(MatrixKernel* object, NodeType* root, std::string* error) const override {
         if (!parseAttr(root, "version", &object->mMinLts, error) ||
@@ -1023,7 +1034,7 @@
         }
         if (m.mType == SchemaType::FRAMEWORK) {
             if (!(flags & SerializeFlag::NO_KERNEL)) {
-                appendChildren(root, matrixKernelConverter, m.framework.mKernels, d);
+                appendChildren(root, matrixKernelConverter, m.framework.mKernels, d, flags);
             }
             if (!(flags & SerializeFlag::NO_SEPOLICY)) {
                 if (!(m.framework.mSepolicy == Sepolicy{})) {