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: