Match /proc/config.gz with fwk comp mat <kernel> fragments
Multiple <kernel> elements with the same version can
exist. The <condition> element decides whether the <kernel>
element is actually used during matching.
Test: libvintf_test
Bug: 64124223
Change-Id: I0dd28b8b1bdfe06a4da61aaa81df91f4df5fcf26
Merged-In: I0dd28b8b1bdfe06a4da61aaa81df91f4df5fcf26
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;