regex-instance: Fix check deprecate test
Deprecation check should check <regex-instance> as well
as <instance>.
An instance is considered deprecated if it matches
some <instance> or <regex-instance> in "old" matrix
but a higher major version / higher minor version matchese
some <instance> or <regex-instance> in "new" matrix.
For example:
1.xml: @1.0::IFoo/legacy/[0-9]+
2.xml: @2.0::IFoo/leg[a-z]+/[0-9]+
And a device manifest provides @1.0::IFoo/legacy/1, then
this instance is deprecated.
Caveat:
VintfObject::IsInstanceInUse is changed to VintfObject::ListInstances
because the matrix no longer provides an exact list of instances
that it checks, but rather a "match rule"; hence it needs to list
all instances from IServiceManager or manifest to work. However,
this doesn't work with passthrough service manager. Hence, if a HAL
is a passthrough HAL, only <instance>s can be checked.
Bug: 73738616
Test: libvintf_test
Test: vintf_object_test
Test: vts_treble_vintf_test
Change-Id: Ibb7585b157c3c1148ba78b8fcd27a113d398297a
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 367dc17..604f7cb 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -577,10 +577,10 @@
bool VintfObject::isHalDeprecated(const MatrixHal& oldMatrixHal,
const CompatibilityMatrix& targetMatrix,
- const IsInstanceInUse& isInstanceInUse, std::string* error) {
+ const ListInstances& listInstances, std::string* error) {
bool isDeprecated = false;
oldMatrixHal.forEachInstance([&](const MatrixInstance& oldMatrixInstance) {
- if (isInstanceDeprecated(oldMatrixInstance, targetMatrix, isInstanceInUse, error)) {
+ if (isInstanceDeprecated(oldMatrixInstance, targetMatrix, listInstances, error)) {
isDeprecated = true;
}
return !isDeprecated; // continue if no deprecated instance is found.
@@ -588,30 +588,39 @@
return isDeprecated;
}
-// If isInstanceInUse(package@x.y::interface/instance), return true iff:
-// 1. package@x.?::interface/instance is not in targetMatrix; OR
-// 2. package@x.z::interface/instance is in targetMatrix but
-// !isInstanceInUse(package@x.z::interface/instance)
+// Let oldMatrixInstance = package@x.y-w::interface with instancePattern.
+// If any "servedInstance" in listInstances(package@x.y::interface) matches instancePattern, return
+// true iff:
+// 1. package@x.?::interface/servedInstance is not in targetMatrix; OR
+// 2. package@x.z::interface/servedInstance is in targetMatrix but
+// servedInstance is not in listInstances(package@x.z::interface)
bool VintfObject::isInstanceDeprecated(const MatrixInstance& oldMatrixInstance,
const CompatibilityMatrix& targetMatrix,
- const IsInstanceInUse& isInstanceInUse, std::string* error) {
+ const ListInstances& listInstances, std::string* error) {
const std::string& package = oldMatrixInstance.package();
const Version& version = oldMatrixInstance.versionRange().minVer();
const std::string& interface = oldMatrixInstance.interface();
- const std::string& instance = oldMatrixInstance.instance();
- bool oldVersionIsServed;
- Version servedVersion;
- std::tie(oldVersionIsServed, servedVersion) =
- isInstanceInUse(package, version, interface, instance);
- if (oldVersionIsServed) {
+ std::vector<std::string> instanceHint;
+ if (!oldMatrixInstance.isRegex()) {
+ instanceHint.push_back(oldMatrixInstance.exactInstance());
+ }
+
+ auto list = listInstances(package, version, interface, instanceHint);
+ for (const auto& pair : list) {
+ const std::string& servedInstance = pair.first;
+ Version servedVersion = pair.second;
+ if (!oldMatrixInstance.matchInstance(servedInstance)) {
+ continue;
+ }
+
// Find any package@x.? in target matrix, and check if instance is in target matrix.
bool foundInstance = false;
Version targetMatrixMinVer;
targetMatrix.forEachInstanceOfPackage(package, [&](const auto& targetMatrixInstance) {
if (targetMatrixInstance.versionRange().majorVer == version.majorVer &&
targetMatrixInstance.interface() == interface &&
- targetMatrixInstance.instance() == instance) {
+ targetMatrixInstance.matchInstance(servedInstance)) {
targetMatrixMinVer = targetMatrixInstance.versionRange().minVer();
foundInstance = true;
}
@@ -619,7 +628,7 @@
});
if (!foundInstance) {
if (error) {
- *error = toFQNameString(package, servedVersion, interface, instance) +
+ *error = toFQNameString(package, servedVersion, interface, servedInstance) +
" is deprecated in compatibility matrix at FCM Version " +
to_string(targetMatrix.level()) + "; it should not be served.";
}
@@ -627,23 +636,29 @@
}
// Assuming that targetMatrix requires @x.u-v, require that at least @x.u is served.
- bool targetVersionServed;
- std::tie(targetVersionServed, std::ignore) =
- isInstanceInUse(package, targetMatrixMinVer, interface, instance);
+ bool targetVersionServed = false;
+ for (const auto& newPair :
+ listInstances(package, targetMatrixMinVer, interface, instanceHint)) {
+ if (newPair.first == servedInstance) {
+ targetVersionServed = true;
+ break;
+ }
+ }
if (!targetVersionServed) {
if (error) {
- *error += toFQNameString(package, servedVersion) + " is deprecated; " +
- "require at least " + to_string(targetMatrixMinVer) + "\n";
+ *error += toFQNameString(package, servedVersion, interface, servedInstance) +
+ " is deprecated; requires at least " + to_string(targetMatrixMinVer) +
+ "\n";
}
return true;
}
}
+
return false;
}
-int32_t VintfObject::CheckDeprecation(const IsInstanceInUse& isInstanceInUse,
- std::string* error) {
+int32_t VintfObject::CheckDeprecation(const ListInstances& listInstances, std::string* error) {
auto matrixFragments = GetAllFrameworkMatrixLevels(error);
if (matrixFragments.empty()) {
if (error && error->empty())
@@ -680,7 +695,7 @@
const auto& oldMatrix = namedMatrix.object;
for (const MatrixHal& hal : oldMatrix.getHals()) {
- hasDeprecatedHals |= isHalDeprecated(hal, *targetMatrix, isInstanceInUse, error);
+ hasDeprecatedHals |= isHalDeprecated(hal, *targetMatrix, listInstances, error);
}
}
@@ -690,22 +705,18 @@
int32_t VintfObject::CheckDeprecation(std::string* error) {
using namespace std::placeholders;
auto deviceManifest = GetDeviceHalManifest();
- IsInstanceInUse inManifest = [&deviceManifest](const std::string& package, Version version,
- const std::string& interface,
- const std::string& instance) {
- std::pair<bool, Version> ret(false, Version{});
- deviceManifest->forEachInstanceOfInterface(
- package, version, interface,
- [&instance, &ret](const ManifestInstance& manifestInstance) {
- if (manifestInstance.instance() == instance) {
- ret.first = true;
- ret.second = manifestInstance.version();
- return false;
- }
- return true;
- });
- return ret;
- };
+ ListInstances inManifest =
+ [&deviceManifest](const std::string& package, Version version, const std::string& interface,
+ const std::vector<std::string>& /* hintInstances */) {
+ std::vector<std::pair<std::string, Version>> ret;
+ deviceManifest->forEachInstanceOfInterface(
+ package, version, interface, [&ret](const ManifestInstance& manifestInstance) {
+ ret.push_back(
+ std::make_pair(manifestInstance.instance(), manifestInstance.version()));
+ return true;
+ });
+ return ret;
+ };
return CheckDeprecation(inManifest, error);
}