Allow RuntimeInfo::fetch to fetch conditionally
am: 1fb004e730

Change-Id: I96ff51398ce6fa81fe7ae69e2c98bdea64298c92
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp
index f320861..73d0384 100644
--- a/CompatibilityMatrix.cpp
+++ b/CompatibilityMatrix.cpp
@@ -22,8 +22,6 @@
 namespace android {
 namespace vintf {
 
-constexpr Version CompatibilityMatrix::kVersion;
-
 bool CompatibilityMatrix::add(MatrixHal &&hal) {
     return HalGroup<MatrixHal>::add(std::move(hal));
 }
@@ -40,6 +38,11 @@
     return mType;
 }
 
+Version CompatibilityMatrix::getMinimumMetaVersion() const {
+    // TODO(b/62801658): this needs to depend on whether there are 1.1 requirements
+    // (e.g. required <xmlfile> entry)
+    return {1, 0};
+}
 
 status_t CompatibilityMatrix::fetchAllInformation(const std::string &path) {
     return details::fetchAllInformation(path, gCompatibilityMatrixConverter, this);
diff --git a/HalManifest.cpp b/HalManifest.cpp
index f0fcf3f..4345d7a 100644
--- a/HalManifest.cpp
+++ b/HalManifest.cpp
@@ -32,8 +32,6 @@
 namespace android {
 namespace vintf {
 
-constexpr Version HalManifest::kVersion;
-
 // Check <version> tag for all <hal> with the same name.
 bool HalManifest::shouldAdd(const ManifestHal& hal) const {
     if (!hal.isValid()) {
@@ -364,6 +362,10 @@
     return mType;
 }
 
+Version HalManifest::getMetaVersion() const {
+    return mMetaVersion;
+}
+
 const Version &HalManifest::sepolicyVersion() const {
     CHECK(mType == SchemaType::DEVICE);
     return device.mSepolicyVersion;
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h
index 36aac51..bc3fbf4 100644
--- a/include/vintf/CompatibilityMatrix.h
+++ b/include/vintf/CompatibilityMatrix.h
@@ -40,8 +40,7 @@
     CompatibilityMatrix() : mType(SchemaType::FRAMEWORK) {};
 
     SchemaType type() const;
-
-    constexpr static Version kVersion{1, 0};
+    Version getMinimumMetaVersion() const;
 
     // If the corresponding <xmlfile> with the given version exists, for the first match,
     // - Return the overridden <path> if it is present,
diff --git a/include/vintf/HalManifest.h b/include/vintf/HalManifest.h
index 31c4801..bf224db 100644
--- a/include/vintf/HalManifest.h
+++ b/include/vintf/HalManifest.h
@@ -41,8 +41,6 @@
 // framework code. This is the API for the framework.
 struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestXmlFile> {
    public:
-    // manifest.version
-    constexpr static Version kVersion{1, 0};
 
     // Construct a device HAL manifest.
     HalManifest() : mType(SchemaType::DEVICE) {}
@@ -127,6 +125,9 @@
     // Otherwise if the <xmlfile> entry does not exist, "" is returned.
     std::string getXmlFilePath(const std::string& xmlFileName, const Version& version) const;
 
+    // Get metaversion of this manifest.
+    Version getMetaVersion() const;
+
    protected:
     // Check before add()
     bool shouldAdd(const ManifestHal& toAdd) const override;
@@ -153,6 +154,8 @@
                                                        bool includeOptional = true) const;
 
     SchemaType mType;
+    // version attribute. Default is 1.0 for manifests created programatically.
+    Version mMetaVersion{1, 0};
 
     // entries for device hal manifest only
     struct {
diff --git a/include/vintf/constants.h b/include/vintf/constants.h
new file mode 100644
index 0000000..efbb73c
--- /dev/null
+++ b/include/vintf/constants.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_VINTF_CONSTANTS_H
+#define ANDROID_VINTF_CONSTANTS_H
+
+#include "Version.h"
+
+namespace android {
+namespace vintf {
+
+/* libvintf meta-version */
+constexpr Version kMetaVersion{1, 0};
+
+}  // namespace vintf
+}  // namespace android
+
+#endif  // ANDROID_VINTF_CONSTANTS_H
diff --git a/parse_xml.cpp b/parse_xml.cpp
index 259fd4e..0b3a514 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -25,6 +25,7 @@
 
 #include <tinyxml2.h>
 
+#include "constants.h"
 #include "parse_string.h"
 
 namespace android {
@@ -747,7 +748,7 @@
 struct HalManifestConverter : public XmlNodeConverter<HalManifest> {
     std::string elementName() const override { return "manifest"; }
     void mutateNode(const HalManifest &m, NodeType *root, DocType *d) const override {
-        appendAttr(root, "version", HalManifest::kVersion);
+        appendAttr(root, "version", m.getMetaVersion());
         appendAttr(root, "type", m.mType);
 
         appendChildren(root, manifestHalConverter, m.getHals(), d);
@@ -760,15 +761,15 @@
         appendChildren(root, manifestXmlFileConverter, m.getXmlFiles(), d);
     }
     bool buildObject(HalManifest *object, NodeType *root) const override {
-        Version version;
         std::vector<ManifestHal> hals;
-        if (!parseAttr(root, "version", &version) ||
+        if (!parseAttr(root, "version", &object->mMetaVersion) ||
             !parseAttr(root, "type", &object->mType) ||
             !parseChildren(root, manifestHalConverter, &hals)) {
             return false;
         }
-        if (version != HalManifest::kVersion) {
-            this->mLastError = "Unrecognized manifest.version";
+        if (!kMetaVersion.minorAtLeast(object->mMetaVersion)) {
+            this->mLastError = "Unrecognized manifest.version " + to_string(object->mMetaVersion) +
+                               " (libvintf@" + to_string(kMetaVersion) + ")";
             return false;
         }
         if (object->mType == SchemaType::DEVICE) {
@@ -857,7 +858,7 @@
 struct CompatibilityMatrixConverter : public XmlNodeConverter<CompatibilityMatrix> {
     std::string elementName() const override { return "compatibility-matrix"; }
     void mutateNode(const CompatibilityMatrix &m, NodeType *root, DocType *d) const override {
-        appendAttr(root, "version", CompatibilityMatrix::kVersion);
+        appendAttr(root, "version", m.getMinimumMetaVersion());
         appendAttr(root, "type", m.mType);
         appendChildren(root, matrixHalConverter, iterateValues(m.mHals), d);
         if (m.mType == SchemaType::FRAMEWORK) {
@@ -910,8 +911,9 @@
             }
         }
 
-        if (version != CompatibilityMatrix::kVersion) {
-            this->mLastError = "Unrecognized compatibility-matrix.version";
+        if (!kMetaVersion.minorAtLeast(version)) {
+            this->mLastError = "Unrecognized compatibility-matrix.version " + to_string(version) +
+                               " (libvintf@" + to_string(kMetaVersion) + ")";
             return false;
         }
         for (auto &&hal : hals) {