HalManifest::checkIncompatibleHals uses instances API.
Now that <hal> is not the smallest unit of a manifest,
the compatibility check logic is updated accordingly.
Test: libvintf_test
Test: vintf_object_test
Bug: 73556059
Change-Id: Ief73afc61bace0dcc3d02410c16c7e261fa63315
diff --git a/MatrixHal.cpp b/MatrixHal.cpp
index fbe9a5f..9788545 100644
--- a/MatrixHal.cpp
+++ b/MatrixHal.cpp
@@ -70,14 +70,22 @@
bool MatrixHal::forEachInstance(const std::function<bool(const MatrixInstance&)>& func) const {
for (const auto& vr : versionRanges) {
- for (const auto& intf : iterateValues(interfaces)) {
- for (const auto& instance : intf.instances) {
- // TODO(b/73556059): Store MatrixInstance as well to avoid creating temps
- FqInstance fqInstance;
- if (fqInstance.setTo(getName(), vr.majorVer, vr.minMinor, intf.name, instance)) {
- if (!func(MatrixInstance(std::move(fqInstance), VersionRange(vr), optional))) {
- return false;
- }
+ if (!forEachInstance(vr, func)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool MatrixHal::forEachInstance(const VersionRange& vr,
+ const std::function<bool(const MatrixInstance&)>& func) const {
+ for (const auto& intf : iterateValues(interfaces)) {
+ for (const auto& instance : intf.instances) {
+ // TODO(b/73556059): Store MatrixInstance as well to avoid creating temps
+ FqInstance fqInstance;
+ if (fqInstance.setTo(getName(), vr.majorVer, vr.minMinor, intf.name, instance)) {
+ if (!func(MatrixInstance(std::move(fqInstance), VersionRange(vr), optional))) {
+ return false;
}
}
}
@@ -85,5 +93,42 @@
return true;
}
+bool MatrixHal::isCompatible(const std::set<FqInstance>& providedInstances,
+ const std::set<Version>& providedVersions) const {
+ // <version>'s are related by OR.
+ return std::any_of(versionRanges.begin(), versionRanges.end(), [&](const VersionRange& vr) {
+ return isCompatible(vr, providedInstances, providedVersions);
+ });
+}
+
+bool MatrixHal::isCompatible(const VersionRange& vr, const std::set<FqInstance>& providedInstances,
+ const std::set<Version>& providedVersions) const {
+ bool hasAnyInstance = false;
+ bool versionUnsatisfied = false;
+
+ // Look at each interface/instance, and ensure that they are in providedInstances.
+ forEachInstance(vr, [&](const MatrixInstance& matrixInstance) {
+ hasAnyInstance = true;
+
+ versionUnsatisfied |=
+ !std::any_of(providedInstances.begin(), providedInstances.end(),
+ [&](const FqInstance& providedInstance) {
+ return matrixInstance.isSatisfiedBy(providedInstance);
+ });
+
+ return !versionUnsatisfied; // if any interface/instance is unsatisfied, break
+ });
+
+ if (hasAnyInstance) {
+ return !versionUnsatisfied;
+ }
+
+ // In some cases (e.g. tests and native HALs), compatibility matrix doesn't specify
+ // any instances. Check versions only.
+ return std::any_of(
+ providedVersions.begin(), providedVersions.end(),
+ [&](const auto& providedVersion) { return vr.supportedBy(providedVersion); });
+}
+
} // namespace vintf
} // namespace android