VintfObject::checkCompatibility reads incoming kernel info.
am: 40b7e622fd
Change-Id: I18e14864f3fc531b38dfe6f453dd321fd4574efb
diff --git a/HalManifest.cpp b/HalManifest.cpp
index f7bac29..d844c4c 100644
--- a/HalManifest.cpp
+++ b/HalManifest.cpp
@@ -317,20 +317,24 @@
return false;
}
} else if (mType == SchemaType::DEVICE) {
- bool match = false;
+ bool sepolicyMatch = false;
for (const auto &range : mat.framework.mSepolicy.sepolicyVersions()) {
if (range.supportedBy(device.mSepolicyVersion)) {
- match = true;
+ sepolicyMatch = true;
break;
}
}
- if (!match) {
+ if (!sepolicyMatch) {
if (error != nullptr) {
*error = "Sepolicy version " + to_string(device.mSepolicyVersion)
+ " doesn't satisify the requirements.";
}
return false;
}
+
+ if (!!kernel() && !kernel()->matchKernelRequirements(mat.framework.mKernels, error)) {
+ return false;
+ }
}
return true;
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 1100977..fbe4045 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -548,9 +548,15 @@
return INCOMPATIBLE;
}
+ CheckFlags::Type runtimeInfoCheckFlags = flags;
+ if (!!getDeviceHalManifest()->kernel()) {
+ // Use kernel from incoming OTA package, but not on the device.
+ runtimeInfoCheckFlags = runtimeInfoCheckFlags.disableKernel();
+ }
+
if (flags.isRuntimeInfoEnabled()) {
if (!getRuntimeInfo()->checkCompatibility(*getFrameworkCompatibilityMatrix(), error,
- flags)) {
+ runtimeInfoCheckFlags)) {
if (error) {
error->insert(0,
"Runtime info and framework compatibility matrix are incompatible: ");
diff --git a/include/vintf/CheckFlags.h b/include/vintf/CheckFlags.h
index 2da807c..52d35a7 100644
--- a/include/vintf/CheckFlags.h
+++ b/include/vintf/CheckFlags.h
@@ -25,9 +25,9 @@
// Flags for *::checkCompatibility functions.
class Type {
public:
-#define VINTF_CHECK_FLAGS_FIELD(name, bit) \
- constexpr Type enable##name() const { return Type(mValue | (1 << bit)); } \
- constexpr Type disable##name() const { return Type(mValue & ~(1 << bit)); } \
+#define VINTF_CHECK_FLAGS_FIELD(name, bit) \
+ [[nodiscard]] constexpr Type enable##name() const { return Type(mValue | (1 << bit)); } \
+ [[nodiscard]] constexpr Type disable##name() const { return Type(mValue & ~(1 << bit)); } \
constexpr bool is##name##Enabled() const { return mValue & (1 << bit); }
VINTF_CHECK_FLAGS_FIELD(Avb, 0)
diff --git a/test/vintf_object_tests.cpp b/test/vintf_object_tests.cpp
index 92e2ce9..f97d81f 100644
--- a/test/vintf_object_tests.cpp
+++ b/test/vintf_object_tests.cpp
@@ -327,6 +327,27 @@
" </hal>\n"
"</manifest>\n";
+//
+// Set of metadata for kernel requirements
+//
+
+const std::string vendorManifestKernel318 =
+ "<manifest version=\"1.0\" type=\"device\">\n"
+ " <kernel version=\"3.18.999\" />\n"
+ " <sepolicy>\n"
+ " <version>25.5</version>\n"
+ " </sepolicy>\n"
+ "</manifest>\n";
+
+const std::string systemMatrixKernel318 =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <kernel version=\"3.18.999\"></kernel>\n"
+ " <sepolicy>\n"
+ " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
+ " <sepolicy-version>25.5</sepolicy-version>\n"
+ " </sepolicy>\n"
+ "</compatibility-matrix>\n";
+
class VintfObjectTestBase : public ::testing::Test {
protected:
MockFileSystem& fetcher() {
@@ -585,6 +606,28 @@
ASSERT_STREQ(error.c_str(), "");
}
+// Test that framework-only OTA fails when kernel is not compatible with incoming system.
+TEST_F(VintfObjectCompatibleTest, KernelInfoIncompatible) {
+ std::string error;
+ std::vector<std::string> packageInfo = {systemMatrixKernel318};
+
+ int result = checkCompatibility(packageInfo, &error);
+
+ ASSERT_EQ(result, INCOMPATIBLE) << "Should have failed.";
+ EXPECT_IN("Framework is incompatible with kernel version 3.18.31", error);
+}
+
+// Test that full OTA is successful when the OTA package provides a compatible kernel.
+TEST_F(VintfObjectCompatibleTest, UpdateKernel) {
+ std::string error;
+ std::vector<std::string> packageInfo = {vendorManifestKernel318, systemMatrixKernel318};
+
+ int result = checkCompatibility(packageInfo, &error);
+
+ ASSERT_EQ(result, COMPATIBLE) << "Fail message:" << error;
+ ASSERT_STREQ(error.c_str(), "");
+}
+
// Test fixture that provides incompatible metadata from the mock device.
class VintfObjectIncompatibleTest : public VintfObjectTestBase {
protected: