Add HalManifest::shouldCheckKernelCompatibility
Now that <kernel> may exist in a HAL manifest without version and
configs, HalManifest::kernel().has_value() does not indicate whether
kernel information exists.
Add a function, shouldCheckKernelCompatibility(), that also checks
the existance of kernel version. kernel()->checkCompatibility may
be called if and only if this function returns true.
Test: cuttlefish vintf vts test
Test: libvintf_test
Test: vintf_object_test
Change-Id: I147703da6823275ceed9a134a75aefaa0ceae099
diff --git a/HalManifest.cpp b/HalManifest.cpp
index 6d2eafc..bd0379a 100644
--- a/HalManifest.cpp
+++ b/HalManifest.cpp
@@ -347,7 +347,7 @@
return false;
}
- if (flags.isKernelEnabled() && !!kernel() &&
+ if (flags.isKernelEnabled() && shouldCheckKernelCompatibility() &&
kernel()
->getMatchedKernelRequirements(mat.framework.mKernels, kernel()->level(), error)
.empty()) {
@@ -358,6 +358,10 @@
return true;
}
+bool HalManifest::shouldCheckKernelCompatibility() const {
+ return kernel().has_value() && kernel()->version() != KernelVersion{};
+}
+
CompatibilityMatrix HalManifest::generateCompatibleMatrix() const {
CompatibilityMatrix matrix;
diff --git a/VintfObject.cpp b/VintfObject.cpp
index c0ce79b..15ea4d2 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -602,7 +602,7 @@
}
CheckFlags::Type runtimeInfoCheckFlags = flags;
- if (!!getDeviceHalManifest()->kernel()) {
+ if (getDeviceHalManifest()->shouldCheckKernelCompatibility()) {
// Use kernel from incoming OTA package, but not on the device.
runtimeInfoCheckFlags = runtimeInfoCheckFlags.disableKernel();
}
diff --git a/include/vintf/HalManifest.h b/include/vintf/HalManifest.h
index ee900e6..e7b2a0e 100644
--- a/include/vintf/HalManifest.h
+++ b/include/vintf/HalManifest.h
@@ -198,6 +198,10 @@
// Merge information of other to this.
bool mergeKernel(std::optional<KernelInfo>* other, std::string* error = nullptr);
+ // Whether the manifest contains information about the kernel for compatibility checks.
+ // True if kernel()->checkCompatibility can be called.
+ bool shouldCheckKernelCompatibility() const;
+
SchemaType mType;
Level mLevel = Level::UNSPECIFIED;
diff --git a/test/vintf_object_tests.cpp b/test/vintf_object_tests.cpp
index 30bfc70..f92db0e 100644
--- a/test/vintf_object_tests.cpp
+++ b/test/vintf_object_tests.cpp
@@ -1399,7 +1399,18 @@
"</compatibility-matrix>\n",
};
-class KernelTest : public MultiMatrixTest {};
+class KernelTest : public MultiMatrixTest {
+ public:
+ void expectKernelFcmVersion(size_t targetFcm, Level kernelFcm) {
+ std::string xml = "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"" +
+ to_string(static_cast<Level>(targetFcm)) + "\">\n";
+ if (kernelFcm != Level::UNSPECIFIED) {
+ xml += " <kernel target-level=\"" + to_string(kernelFcm) + "\"/>\n";
+ }
+ xml += "</manifest>";
+ expectFetch(kVendorManifest, xml);
+ }
+};
// Assume that we are developing level 2. Test that old <kernel> requirements should
// not change and new <kernel> versions are added.
@@ -1439,19 +1450,44 @@
EXPECT_IN(FAKE_KERNEL("4.0.0", "D3", 3), xml) << "\nShould see <kernel> from new matrices";
}
+KernelInfo MakeKernelInfo(const std::string& version, const std::string& key) {
+ KernelInfo info;
+ CHECK(gKernelInfoConverter(&info,
+ " <kernel version=\"" + version + "\">\n"
+ " <config>\n"
+ " <key>CONFIG_" + key + "</key>\n"
+ " <value type=\"tristate\">y</value>\n"
+ " </config>\n"
+ " </kernel>\n"));
+ return info;
+}
+
+TEST_F(KernelTest, Compatible) {
+ setFakeProperties();
+ setupMockFetcher(vendorManifestXml1, systemMatrixXml1, systemManifestXml1, vendorMatrixXml1,
+ productModel);
+
+ SetUpMockSystemMatrices({
+ "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\">\n"
+ FAKE_KERNEL("1.0.0", "A1", 1)
+ FAKE_KERNEL("2.0.0", "B1", 1)
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>0</kernel-sepolicy-version>\n"
+ " <sepolicy-version>0.0</sepolicy-version>\n"
+ " </sepolicy>\n"
+ "</compatibility-matrix>\n"});
+ expectKernelFcmVersion(Level{1}, Level{1});
+ expectSystemManifest();
+ expectVendorMatrix();
+
+ auto info = MakeKernelInfo("1.0.0", "A1");
+ runtimeInfoFactory().getInfo()->setNextFetchKernelInfo(info.version(), info.configs());
+ std::string error;
+ ASSERT_EQ(COMPATIBLE, vintfObject->checkCompatibility(&error)) << error;
+}
+
class KernelTestP : public KernelTest, public WithParamInterface<
- std::tuple<std::vector<std::string>, KernelInfo, Level, Level, bool>> {
- public:
- void expectKernelFcmVersion(size_t targetFcm, Level kernelFcm) {
- std::string xml = "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"" +
- to_string(static_cast<Level>(targetFcm)) + "\">\n";
- if (kernelFcm != Level::UNSPECIFIED) {
- xml += " <kernel target-level=\"" + to_string(kernelFcm) + "\"/>\n";
- }
- xml += "</manifest>";
- expectFetch(kVendorManifest, xml);
- }
-};
+ std::tuple<std::vector<std::string>, KernelInfo, Level, Level, bool>> {};
// Assume that we are developing level 2. Test that old <kernel> requirements should
// not change and new <kernel> versions are added.
TEST_P(KernelTestP, Test) {
@@ -1472,17 +1508,6 @@
<< (pass ? error : fallbackError);
}
-KernelInfo MakeKernelInfo(const std::string& version, const std::string& key) {
- KernelInfo info;
- CHECK(gKernelInfoConverter(&info,
- " <kernel version=\"" + version + "\">\n"
- " <config>\n"
- " <key>CONFIG_" + key + "</key>\n"
- " <value type=\"tristate\">y</value>\n"
- " </config>\n"
- " </kernel>\n"));
- return info;
-}
std::vector<KernelTestP::ParamType> KernelTestParamValues() {
std::vector<KernelTestP::ParamType> ret;