Implement VintfObject::getLatestMinLtsAtFcmVersion.
This function returns the MAX of minlts of FCM at
a given level.
Details can be found in the kernel/configs project.
For example, for Android 12, this returns 5.10.43,
and for Android 13, this returns 5.15.41.
Test: TH
Bug: 255995840
Change-Id: Ib83b8013f4b903da6c943f45c572a15d7b2be997
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp
index 06f5b73..46218f0 100644
--- a/CompatibilityMatrix.cpp
+++ b/CompatibilityMatrix.cpp
@@ -480,5 +480,18 @@
return level();
}
+KernelVersion CompatibilityMatrix::getLatestKernelMinLts() const {
+ if (type() != SchemaType::FRAMEWORK) {
+ return {};
+ }
+ auto maxIt = std::max_element(
+ framework.mKernels.begin(), framework.mKernels.end(),
+ [](const MatrixKernel& a, const MatrixKernel& b) { return a.minLts() < b.minLts(); });
+ if (maxIt == framework.mKernels.end()) {
+ return {};
+ }
+ return maxIt->minLts();
+}
+
} // namespace vintf
} // namespace android
diff --git a/VintfObject.cpp b/VintfObject.cpp
index bfbc90d..e84486d 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -1326,6 +1326,28 @@
return {};
}
+android::base::Result<KernelVersion> VintfObject::getLatestMinLtsAtFcmVersion(Level fcmVersion) {
+ auto allFcms = getAllFrameworkMatrixLevels();
+ if (!allFcms.ok()) return allFcms.error();
+
+ // Get the max of latestKernelMinLts for all FCM fragments at |fcmVersion|.
+ // Usually there's only one such fragment.
+ KernelVersion foundLatestMinLts;
+ for (const auto& fcm : *allFcms) {
+ if (fcm.level() != fcmVersion) {
+ continue;
+ }
+ // Note: this says "minLts", but "Latest" indicates that it is a max value.
+ auto thisLatestMinLts = fcm.getLatestKernelMinLts();
+ if (foundLatestMinLts < thisLatestMinLts) foundLatestMinLts = thisLatestMinLts;
+ }
+ if (foundLatestMinLts != KernelVersion{}) {
+ return foundLatestMinLts;
+ }
+ return android::base::Error(-NAME_NOT_FOUND)
+ << "Can't find compatibility matrix fragment for level " << fcmVersion;
+}
+
// make_unique does not work because VintfObject constructor is private.
VintfObject::Builder::Builder()
: VintfObjectBuilder(std::unique_ptr<VintfObject>(new VintfObject())) {}
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h
index 462e2e9..a5aaa62 100644
--- a/include/vintf/CompatibilityMatrix.h
+++ b/include/vintf/CompatibilityMatrix.h
@@ -152,6 +152,10 @@
// Prerequisite: matrixKernel is in mKernels.
Level getSourceMatrixLevel(const MatrixKernel* matrixKernel) const;
+ // Return the minlts of the latest <kernel>, or empty value if any error (e.g. this is not an
+ // FCM, or there are no <kernel> tags).
+ [[nodiscard]] KernelVersion getLatestKernelMinLts() const;
+
friend struct HalManifest;
friend struct RuntimeInfo;
friend struct CompatibilityMatrixConverter;
diff --git a/include/vintf/Version.h b/include/vintf/Version.h
index 6c6b0ff..15c1089 100644
--- a/include/vintf/Version.h
+++ b/include/vintf/Version.h
@@ -94,6 +94,9 @@
if (majorRev > other.majorRev) return false;
return minorRev < other.minorRev;
}
+ inline bool operator>(const KernelVersion& other) const { return other < (*this); }
+ inline bool operator<=(const KernelVersion& other) const { return !((*this) > other); }
+ inline bool operator>=(const KernelVersion& other) const { return !((*this) < other); }
inline constexpr Version dropMinor() const { return Version{version, majorRev}; }
};
diff --git a/include/vintf/VintfObject.h b/include/vintf/VintfObject.h
index 57d92ff..5fded4d 100644
--- a/include/vintf/VintfObject.h
+++ b/include/vintf/VintfObject.h
@@ -269,6 +269,9 @@
const std::vector<HidlInterfaceMetadata>& hidlMetadata,
const std::vector<AidlInterfaceMetadata>& aidlMetadata);
+ // Get the latest <kernel> minlts for compatibility matrix level |fcmVersion|.
+ android::base::Result<KernelVersion> getLatestMinLtsAtFcmVersion(Level fcmVersion);
+
private:
std::unique_ptr<FileSystem> mFileSystem;
std::unique_ptr<ObjectFactory<RuntimeInfo>> mRuntimeInfoFactory;
diff --git a/test/vintf_object_tests.cpp b/test/vintf_object_tests.cpp
index 37691ed..e84d21e 100644
--- a/test/vintf_object_tests.cpp
+++ b/test/vintf_object_tests.cpp
@@ -39,7 +39,9 @@
using namespace std::literals;
using android::base::testing::HasError;
+using android::base::testing::HasValue;
using android::base::testing::Ok;
+using android::base::testing::WithCode;
using android::base::testing::WithMessage;
using android::vintf::FqInstance;
@@ -2743,6 +2745,56 @@
::testing::ValuesIn(VintfObjectComposerHalTest::GetParams()),
[](const auto& info) { return to_string(info.param); });
+constexpr const char* systemMatrixLatestMinLtsFormat = R"(
+<compatibility-matrix %s type="framework" level="%s">
+ <kernel version="%s" />
+ <kernel version="%s" />
+ <kernel version="%s" />
+</compatibility-matrix>
+)";
+
+class VintfObjectLatestMinLtsTest : public MultiMatrixTest {};
+
+TEST_F(VintfObjectLatestMinLtsTest, TestEmpty) {
+ SetUpMockSystemMatrices({});
+ EXPECT_THAT(vintfObject->getLatestMinLtsAtFcmVersion(Level::S),
+ HasError(WithCode(-NAME_NOT_FOUND)));
+}
+
+TEST_F(VintfObjectLatestMinLtsTest, TestMissing) {
+ SetUpMockSystemMatrices({
+ android::base::StringPrintf(systemMatrixLatestMinLtsFormat, kMetaVersionStr.c_str(),
+ to_string(Level::S).c_str(), "4.19.191", "5.4.86", "5.10.43"),
+ });
+ EXPECT_THAT(
+ vintfObject->getLatestMinLtsAtFcmVersion(Level::T),
+ HasError(WithMessage(HasSubstr("Can't find compatibility matrix fragment for level 7"))));
+}
+
+TEST_F(VintfObjectLatestMinLtsTest, TestSimple) {
+ SetUpMockSystemMatrices({
+ android::base::StringPrintf(systemMatrixLatestMinLtsFormat, kMetaVersionStr.c_str(),
+ to_string(Level::S).c_str(), "4.19.191", "5.4.86", "5.10.43"),
+ android::base::StringPrintf(systemMatrixLatestMinLtsFormat, kMetaVersionStr.c_str(),
+ to_string(Level::T).c_str(), "5.4.86", "5.10.107", "5.15.41"),
+ });
+ EXPECT_THAT(vintfObject->getLatestMinLtsAtFcmVersion(Level::S),
+ HasValue(KernelVersion{5, 10, 43}));
+ EXPECT_THAT(vintfObject->getLatestMinLtsAtFcmVersion(Level::T),
+ HasValue(KernelVersion{5, 15, 41}));
+}
+
+TEST_F(VintfObjectLatestMinLtsTest, TestMultipleFragment) {
+ SetUpMockSystemMatrices({
+ android::base::StringPrintf(systemMatrixLatestMinLtsFormat, kMetaVersionStr.c_str(),
+ to_string(Level::S).c_str(), "4.19.191", "5.4.86", "5.10.43"),
+ android::base::StringPrintf(systemMatrixLatestMinLtsFormat, kMetaVersionStr.c_str(),
+ to_string(Level::S).c_str(), "5.4.86", "5.10.107", "5.15.41"),
+ });
+ EXPECT_THAT(vintfObject->getLatestMinLtsAtFcmVersion(Level::S),
+ HasValue(KernelVersion{5, 15, 41}));
+}
+
} // namespace testing
} // namespace vintf
} // namespace android