Merge changes from topic "kernel_config_arch"
* changes:
Add tests for kernel config fragments in fwk comp mat.
Do not allow first <kernel> version to have non-empty <condition>.
Remove unused CompatibilityMatrix::findKernel
Improve error messages in parse_xml.cpp
Match /proc/config.gz with fwk comp mat <kernel> fragments
Add <conditions> to <kernel> in framework compat mat
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp
index 509ca1d..f320861 100644
--- a/CompatibilityMatrix.cpp
+++ b/CompatibilityMatrix.cpp
@@ -36,19 +36,6 @@
return true;
}
-const MatrixKernel *CompatibilityMatrix::findKernel(const KernelVersion &v) const {
- if (mType != SchemaType::FRAMEWORK) {
- return nullptr;
- }
- for (const MatrixKernel &matrixKernel : framework.mKernels) {
- if (matrixKernel.minLts().version == v.version &&
- matrixKernel.minLts().majorRev == v.majorRev) {
- return matrixKernel.minLts().minorRev <= v.minorRev ? &matrixKernel : nullptr;
- }
- }
- return nullptr;
-}
-
SchemaType CompatibilityMatrix::type() const {
return mType;
}
diff --git a/RuntimeInfo.cpp b/RuntimeInfo.cpp
index b29a146..0bcb363 100644
--- a/RuntimeInfo.cpp
+++ b/RuntimeInfo.cpp
@@ -69,6 +69,38 @@
return mBootAvbVersion;
}
+bool RuntimeInfo::matchKernelConfigs(const std::vector<KernelConfig>& matrixConfigs,
+ std::string* error) const {
+ for (const KernelConfig& matrixConfig : matrixConfigs) {
+ const std::string& key = matrixConfig.first;
+ auto it = this->mKernelConfigs.find(key);
+ if (it == this->mKernelConfigs.end()) {
+ // special case: <value type="tristate">n</value> matches if the config doesn't exist.
+ if (matrixConfig.second == KernelConfigTypedValue::gMissingConfig) {
+ continue;
+ }
+ if (error != nullptr) {
+ *error = "Missing config " + key;
+ }
+ return false;
+ }
+ const std::string& kernelValue = it->second;
+ if (!matrixConfig.second.matchValue(kernelValue)) {
+ if (error != nullptr) {
+ *error = "For config " + key + ", value = " + kernelValue + " but required " +
+ to_string(matrixConfig.second);
+ }
+ return false;
+ }
+ }
+ return true;
+}
+
+bool RuntimeInfo::matchKernelVersion(const KernelVersion& minLts) const {
+ return minLts.version == mKernelVersion.version && minLts.majorRev == mKernelVersion.majorRev &&
+ minLts.minorRev <= mKernelVersion.minorRev;
+}
+
bool RuntimeInfo::checkCompatibility(const CompatibilityMatrix &mat,
std::string *error) const {
if (mat.mType != SchemaType::FRAMEWORK) {
@@ -86,36 +118,46 @@
return false;
}
- // mat.mSepolicy.sepolicyVersion() is checked against static HalManifest.device.mSepolicyVersion
+ // mat.mSepolicy.sepolicyVersion() is checked against static
+ // HalManifest.device.mSepolicyVersion in HalManifest::checkCompatibility.
- const MatrixKernel *matrixKernel = mat.findKernel(this->mKernelVersion);
- if (matrixKernel == nullptr) {
+ bool foundMatchedKernelVersion = false;
+ bool foundMatchedConditions = false;
+ for (const MatrixKernel& matrixKernel : mat.framework.mKernels) {
+ if (!matchKernelVersion(matrixKernel.minLts())) {
+ continue;
+ }
+ foundMatchedKernelVersion = true;
+ // ignore this fragment if not all conditions are met.
+ if (!matchKernelConfigs(matrixKernel.conditions(), error)) {
+ continue;
+ }
+ foundMatchedConditions = true;
+ if (!matchKernelConfigs(matrixKernel.configs(), error)) {
+ return false;
+ }
+ }
+ if (!foundMatchedKernelVersion) {
if (error != nullptr) {
- *error = "Cannot find suitable kernel entry for " + to_string(mKernelVersion);
+ std::stringstream ss;
+ ss << "Framework is incompatible with kernel version " << mKernelVersion
+ << ", compatible kernel versions are";
+ for (const MatrixKernel& matrixKernel : mat.framework.mKernels)
+ ss << " " << matrixKernel.minLts();
+ *error = ss.str();
}
return false;
}
- for (const KernelConfig &matrixConfig : matrixKernel->configs()) {
- const std::string &key = matrixConfig.first;
- auto it = this->mKernelConfigs.find(key);
- if (it == this->mKernelConfigs.end()) {
- // special case: <value type="tristate">n</value> matches if the config doesn't exist.
- if (matrixConfig.second == KernelConfigTypedValue::gMissingConfig) {
- continue;
- }
- if (error != nullptr) {
- *error = "Missing config " + key;
- }
- return false;
+ if (!foundMatchedConditions) {
+ // This should not happen because first <conditions> for each <kernel> must be
+ // empty. Reject here for inconsistency.
+ if (error != nullptr) {
+ error->insert(0, "Framework match kernel version with unmet conditions:");
}
- const std::string &kernelValue = it->second;
- if (!matrixConfig.second.matchValue(kernelValue)) {
- if (error != nullptr) {
- *error = "For config " + key + ", value = " + kernelValue
- + " but required " + to_string(matrixConfig.second);
- }
- return false;
- }
+ return false;
+ }
+ if (error != nullptr) {
+ error->clear();
}
const Version &matAvb = mat.framework.mAvbMetaVersion;
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h
index 94b8004..36aac51 100644
--- a/include/vintf/CompatibilityMatrix.h
+++ b/include/vintf/CompatibilityMatrix.h
@@ -58,9 +58,6 @@
bool add(MatrixHal &&hal);
bool add(MatrixKernel &&kernel);
- // Find a MatrixKernel entry that has version v. nullptr if not found.
- const MatrixKernel *findKernel(const KernelVersion &v) const;
-
status_t fetchAllInformation(const std::string &path);
friend struct HalManifest;
diff --git a/include/vintf/MatrixKernel.h b/include/vintf/MatrixKernel.h
index 4b261a6..f0990a8 100644
--- a/include/vintf/MatrixKernel.h
+++ b/include/vintf/MatrixKernel.h
@@ -35,7 +35,8 @@
using KernelConfig = std::pair<KernelConfigKey, KernelConfigTypedValue>;
-// A kernel entry to a compatibility matrix
+// A <kernel> entry to a compatibility matrix represents a fragment of kernel
+// config requirements.
struct MatrixKernel {
MatrixKernel() {}
@@ -50,12 +51,18 @@
// for (const KernelConfig &config : kernel.configs()) {...}
const std::vector<KernelConfig> &configs() const { return mConfigs; }
-private:
+ // Return an iterable on all kernel config conditions. Use it as follows:
+ // for (const KernelConfig &config : kernel.conditions()) {...}
+ const std::vector<KernelConfig>& conditions() const { return mConditions; }
+
+ private:
friend struct MatrixKernelConverter;
+ friend struct MatrixKernelConditionsConverter;
friend class AssembleVintf;
KernelVersion mMinLts;
std::vector<KernelConfig> mConfigs;
+ std::vector<KernelConfig> mConditions;
};
} // namespace vintf
diff --git a/include/vintf/RuntimeInfo.h b/include/vintf/RuntimeInfo.h
index 4e34f64..6b510fb 100644
--- a/include/vintf/RuntimeInfo.h
+++ b/include/vintf/RuntimeInfo.h
@@ -25,6 +25,9 @@
#include <utils/Errors.h>
+#include "MatrixKernel.h"
+#include "Version.h"
+
namespace android {
namespace vintf {
@@ -79,6 +82,13 @@
status_t fetchAllInformation();
+ // mKernelVersion = x'.y'.z', minLts = x.y.z,
+ // match if x == x' , y == y' , and z <= z'.
+ bool matchKernelVersion(const KernelVersion& minLts) const;
+ // return true if all kernel configs in matrixConfigs matches.
+ bool matchKernelConfigs(const std::vector<KernelConfig>& matrixConfigs,
+ std::string* error = nullptr) const;
+
// /proc/config.gz
// Key: CONFIG_xxx; Value: the value after = sign.
std::map<std::string, std::string> mKernelConfigs;
diff --git a/parse_xml.cpp b/parse_xml.cpp
index 3c840da..259fd4e 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -244,8 +244,8 @@
std::string attrText;
bool ret = getAttr(root, attrName, &attrText) && ::android::vintf::parse(attrText, attr);
if (!ret) {
- mLastError = "Could not find/parse attr with name \"" + attrName + "\" for element <"
- + elementName() + ">";
+ mLastError = "Could not find/parse attr with name \"" + attrName + "\" and value \"" +
+ attrText + "\" for element <" + elementName() + ">";
}
return ret;
}
@@ -549,14 +549,31 @@
const MatrixHalConverter matrixHalConverter{};
+struct MatrixKernelConditionsConverter : public XmlNodeConverter<std::vector<KernelConfig>> {
+ std::string elementName() const override { return "conditions"; }
+ void mutateNode(const std::vector<KernelConfig>& conds, NodeType* root,
+ DocType* d) const override {
+ appendChildren(root, kernelConfigConverter, conds, d);
+ }
+ bool buildObject(std::vector<KernelConfig>* object, NodeType* root) const override {
+ return parseChildren(root, kernelConfigConverter, object);
+ }
+};
+
+const MatrixKernelConditionsConverter matrixKernelConditionsConverter{};
+
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);
+ if (!kernel.mConditions.empty()) {
+ appendChild(root, matrixKernelConditionsConverter(kernel.mConditions, d));
+ }
appendChildren(root, kernelConfigConverter, kernel.mConfigs, d);
}
bool buildObject(MatrixKernel *object, NodeType *root) const override {
if (!parseAttr(root, "version", &object->mMinLts) ||
+ !parseOptionalChild(root, matrixKernelConditionsConverter, {}, &object->mConditions) ||
!parseChildren(root, kernelConfigConverter, &object->mConfigs)) {
return false;
}
@@ -870,6 +887,21 @@
!parseOptionalChild(root, avbConverter, {}, &object->framework.mAvbMetaVersion)) {
return false;
}
+
+ std::set<Version> seenKernelVersions;
+ for (const auto& kernel : object->framework.mKernels) {
+ Version minLts(kernel.minLts().version, kernel.minLts().majorRev);
+ if (seenKernelVersions.find(minLts) != seenKernelVersions.end()) {
+ continue;
+ }
+ if (!kernel.conditions().empty()) {
+ this->mLastError = "First <kernel> for version " + to_string(minLts) +
+ " must have empty <conditions> for backwards compatibility.";
+ return false;
+ }
+ seenKernelVersions.insert(minLts);
+ }
+
} else if (object->mType == SchemaType::DEVICE) {
// <vndk> can be missing because it can be determined at build time, not hard-coded
// in the XML file.
diff --git a/test/main.cpp b/test/main.cpp
index d8cfaf3..94a4d8e 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -100,6 +100,7 @@
bool isValid(const ManifestHal &mh) {
return mh.isValid();
}
+ std::vector<MatrixKernel>& getKernels(CompatibilityMatrix& cm) { return cm.framework.mKernels; }
std::map<std::string, HalInterface> testHalInterfaces() {
HalInterface intf;
@@ -709,6 +710,12 @@
}
{
+ MatrixKernel kernel(KernelVersion{3, 18, 60}, KernelConfigs(configs));
+ CompatibilityMatrix cm = testMatrix(std::move(kernel));
+ EXPECT_FALSE(ki.checkCompatibility(cm)) << "Kernel version shouldn't match";
+ }
+
+ {
MatrixKernel kernel(KernelVersion{3, 18, 22}, KernelConfigs(configs));
CompatibilityMatrix cm = testMatrix(std::move(kernel));
EXPECT_TRUE(ki.checkCompatibility(cm, &error)) << error;
@@ -1534,6 +1541,366 @@
#endif // LIBVINTF_HOST
}
+TEST_F(LibVintfTest, KernelConfigConditionTest) {
+ std::string xml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"3.18.22\"/>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ARM</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_FOO</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+ " <sepolicy-version>25.0</sepolicy-version>\n"
+ " </sepolicy>\n"
+ " <avb>\n"
+ " <vbmeta-version>2.1</vbmeta-version>\n"
+ " </avb>\n"
+ "</compatibility-matrix>\n";
+
+ CompatibilityMatrix cm;
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
+ << gCompatibilityMatrixConverter.lastError();
+ const auto& kernels = getKernels(cm);
+ ASSERT_GE(kernels.size(), 2u);
+ ASSERT_TRUE(kernels[0].conditions().empty());
+ const auto& kernel = kernels[1];
+ const auto& cond = kernel.conditions();
+ ASSERT_FALSE(cond.empty());
+ EXPECT_EQ("CONFIG_ARM", cond.begin()->first);
+ EXPECT_EQ(KernelConfigTypedValue(Tristate::YES), cond.begin()->second);
+ EXPECT_FALSE(kernel.configs().empty());
+
+ EXPECT_EQ(xml, gCompatibilityMatrixConverter(cm));
+}
+
+TEST_F(LibVintfTest, KernelConfigConditionEmptyTest) {
+ std::string xml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"4.4.0\"/>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ARM</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " </kernel>\n"
+ "</compatibility-matrix>\n";
+
+ CompatibilityMatrix cm;
+ EXPECT_FALSE(gCompatibilityMatrixConverter(&cm, xml))
+ << "Should not accept first kernel version with non-empty conditions";
+ EXPECT_EQ(
+ "First <kernel> for version 3.18 must have empty <conditions> "
+ "for backwards compatibility.",
+ gCompatibilityMatrixConverter.lastError());
+}
+
+TEST_F(LibVintfTest, KernelConfigConditionMatch) {
+ RuntimeInfo runtime = testRuntimeInfo();
+ std::string error;
+ std::string xml;
+ CompatibilityMatrix cm;
+
+ xml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"3.18.22\"/>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_64BIT</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ARCH_MMAP_RND_BITS</key>\n"
+ " <value type=\"int\">24</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+ " </sepolicy>\n"
+ " <avb><vbmeta-version>2.1</vbmeta-version></avb>\n"
+ "</compatibility-matrix>\n";
+
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
+ << gCompatibilityMatrixConverter.lastError();
+ EXPECT_TRUE(runtime.checkCompatibility(cm, &error)) << error;
+
+ xml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"3.18.22\"/>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_64BIT</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ARCH_MMAP_RND_BITS</key>\n"
+ " <value type=\"int\">26</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+ " </sepolicy>\n"
+ " <avb><vbmeta-version>2.1</vbmeta-version></avb>\n"
+ "</compatibility-matrix>\n";
+
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
+ << gCompatibilityMatrixConverter.lastError();
+ EXPECT_FALSE(runtime.checkCompatibility(cm, &error))
+ << "conditions met, so CONFIG_ARCH_MMAP_RND_BITS should not match";
+
+ xml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"3.18.22\"/>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_64BIT</key>\n"
+ " <value type=\"tristate\">n</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ARCH_MMAP_RND_BITS</key>\n"
+ " <value type=\"int\">26</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+ " </sepolicy>\n"
+ " <avb><vbmeta-version>2.1</vbmeta-version></avb>\n"
+ "</compatibility-matrix>\n";
+
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
+ << gCompatibilityMatrixConverter.lastError();
+ EXPECT_TRUE(runtime.checkCompatibility(cm, &error)) << error;
+ xml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"3.18.22\"/>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_64BIT</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " <config>\n"
+ " <key>CONFIG_ARCH_MMAP_RND_BITS</key>\n"
+ " <value type=\"int\">24</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ILLEGAL_POINTER_VALUE</key>\n"
+ " <value type=\"int\">0xdead000000000000</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+ " </sepolicy>\n"
+ " <avb><vbmeta-version>2.1</vbmeta-version></avb>\n"
+ "</compatibility-matrix>\n";
+
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
+ << gCompatibilityMatrixConverter.lastError();
+ EXPECT_TRUE(runtime.checkCompatibility(cm, &error));
+
+ xml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"3.18.22\"/>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_64BIT</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " <config>\n"
+ " <key>CONFIG_ARCH_MMAP_RND_BITS</key>\n"
+ " <value type=\"int\">24</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ILLEGAL_POINTER_VALUE</key>\n"
+ " <value type=\"int\">0xbeaf000000000000</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+ " </sepolicy>\n"
+ " <avb><vbmeta-version>2.1</vbmeta-version></avb>\n"
+ "</compatibility-matrix>\n";
+
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
+ << gCompatibilityMatrixConverter.lastError();
+ EXPECT_FALSE(runtime.checkCompatibility(cm, &error))
+ << "conditions have 'and' relationship, so CONFIG_ILLEGAL_POINTER_VALUE should not match";
+
+ xml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"3.18.22\"/>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_64BIT</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " <config>\n"
+ " <key>CONFIG_ARCH_MMAP_RND_BITS</key>\n"
+ " <value type=\"int\">26</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ILLEGAL_POINTER_VALUE</key>\n"
+ " <value type=\"int\">0xbeaf000000000000</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+ " </sepolicy>\n"
+ " <avb><vbmeta-version>2.1</vbmeta-version></avb>\n"
+ "</compatibility-matrix>\n";
+
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
+ << gCompatibilityMatrixConverter.lastError();
+ EXPECT_TRUE(runtime.checkCompatibility(cm, &error)) << error;
+
+ xml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <config>\n"
+ " <key>CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES</key>\n"
+ " <value type=\"string\"/>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_64BIT</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ILLEGAL_POINTER_VALUE</key>\n"
+ " <value type=\"int\">0xdead000000000000</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ARCH_MMAP_RND_BITS</key>\n"
+ " <value type=\"int\">24</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ANDROID_BINDER_DEVICES</key>\n"
+ " <value type=\"string\">binder,hwbinder</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+ " </sepolicy>\n"
+ " <avb><vbmeta-version>2.1</vbmeta-version></avb>\n"
+ "</compatibility-matrix>\n";
+
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
+ << gCompatibilityMatrixConverter.lastError();
+ EXPECT_TRUE(runtime.checkCompatibility(cm, &error)) << error;
+
+ xml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <config>\n"
+ " <key>CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES</key>\n"
+ " <value type=\"string\"/>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_64BIT</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ILLEGAL_POINTER_VALUE</key>\n"
+ " <value type=\"int\">0xbeaf000000000000</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ARCH_MMAP_RND_BITS</key>\n"
+ " <value type=\"int\">24</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ANDROID_BINDER_DEVICES</key>\n"
+ " <value type=\"string\">binder,hwbinder</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+ " </sepolicy>\n"
+ " <avb><vbmeta-version>2.1</vbmeta-version></avb>\n"
+ "</compatibility-matrix>\n";
+
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
+ << gCompatibilityMatrixConverter.lastError();
+ EXPECT_FALSE(runtime.checkCompatibility(cm, &error)) << "all fragments should be used.";
+
+ xml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <config>\n"
+ " <key>CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES</key>\n"
+ " <value type=\"string\"/>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_64BIT</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ILLEGAL_POINTER_VALUE</key>\n"
+ " <value type=\"int\">0xdead000000000000</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <kernel version=\"3.18.22\">\n"
+ " <conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ARCH_MMAP_RND_BITS</key>\n"
+ " <value type=\"int\">24</value>\n"
+ " </config>\n"
+ " </conditions>\n"
+ " <config>\n"
+ " <key>CONFIG_ANDROID_BINDER_DEVICES</key>\n"
+ " <value type=\"string\">binder</value>\n"
+ " </config>\n"
+ " </kernel>\n"
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+ " </sepolicy>\n"
+ " <avb><vbmeta-version>2.1</vbmeta-version></avb>\n"
+ "</compatibility-matrix>\n";
+
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
+ << gCompatibilityMatrixConverter.lastError();
+ EXPECT_FALSE(runtime.checkCompatibility(cm, &error)) << "all fragments should be used";
+}
+
// Run KernelConfigParserInvalidTest on processComments = {true, false}
class KernelConfigParserInvalidTest : public ::testing::TestWithParam<bool> {};