Support <system-sdk> in fwk manifest and dev matrix.

<system-sdk> is a tag in framework manifest and
device matrix. It states a list of System SDK levels
that the framework supports for vendor apps / vendor
apps requires.

Format:
<system-sdk>
    <version>14</version>
    <version>15</version>
</system-sdk>

Versions must not be duplicated.

It is compatible when the set specified in framework
manifest is a superset of the set specified in the
device compatibility matrix.

Test: libvintf_test
Test: vintf_object_tests
Bug: 69088799
Change-Id: I802f055ea60666995202438a770d1e440517ec5c
diff --git a/parse_xml.cpp b/parse_xml.cpp
index 62ba763..74ba880 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -741,6 +741,20 @@
 
 const VendorNdkConverter vendorNdkConverter{};
 
+const XmlTextConverter<std::string> systemSdkVersionConverter{"version"};
+
+struct SystemSdkConverter : public XmlNodeConverter<SystemSdk> {
+    std::string elementName() const override { return "system-sdk"; }
+    void mutateNode(const SystemSdk& object, NodeType* root, DocType* d) const override {
+        appendChildren(root, systemSdkVersionConverter, object.versions(), d);
+    }
+    bool buildObject(SystemSdk* object, NodeType* root) const override {
+        return parseChildren(root, systemSdkVersionConverter, &object->mVersions);
+    }
+};
+
+const SystemSdkConverter systemSdkConverter{};
+
 struct HalManifestSepolicyConverter : public XmlNodeConverter<Version> {
     std::string elementName() const override { return "sepolicy"; }
     void mutateNode(const Version &m, NodeType *root, DocType *d) const override {
@@ -801,6 +815,11 @@
 
                 appendChildren(root, vendorNdkConverter, m.framework.mVendorNdks, d);
             }
+            if (!(flags & SerializeFlag::NO_SSDK)) {
+                if (!m.framework.mSystemSdk.empty()) {
+                    appendChild(root, systemSdkConverter(m.framework.mSystemSdk, d));
+                }
+            }
         }
 
         if (!(flags & SerializeFlag::NO_XMLFILES)) {
@@ -846,6 +865,10 @@
             if (!parseChildren(root, vendorNdkConverter, &object->framework.mVendorNdks)) {
                 return false;
             }
+
+            if (!parseOptionalChild(root, systemSdkConverter, {}, &object->framework.mSystemSdk)) {
+                return false;
+            }
         }
         for (auto &&hal : hals) {
             std::string description{hal.name};
@@ -949,6 +972,12 @@
                     appendChild(root, vendorNdkConverter(m.device.mVendorNdk, d));
                 }
             }
+
+            if (!(flags & SerializeFlag::NO_SSDK)) {
+                if (!m.device.mSystemSdk.empty()) {
+                    appendChild(root, systemSdkConverter(m.device.mSystemSdk, d));
+                }
+            }
         }
 
         if (!(flags & SerializeFlag::NO_XMLFILES)) {
@@ -1000,6 +1029,10 @@
             if (!parseOptionalChild(root, vendorNdkConverter, {}, &object->device.mVendorNdk)) {
                 return false;
             }
+
+            if (!parseOptionalChild(root, systemSdkConverter, {}, &object->device.mSystemSdk)) {
+                return false;
+            }
         }
 
         if (!kMetaVersion.minorAtLeast(version)) {