Fetch framework matrix from /product/etc/vintf/compatibility_matrix.xml.
It will be combined with fragments in
/system/etc/vintf.
Test: vintf_object_test
Bug: 120600021
Change-Id: Iafe5d467f0938972085e1c7f15070a7b4216593a
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 64f4a61..1100977 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -144,8 +144,15 @@
status_t VintfObject::getCombinedFrameworkMatrix(
const std::shared_ptr<const HalManifest>& deviceManifest, CompatibilityMatrix* out,
std::string* error) {
- auto matrixFragments = getAllFrameworkMatrixLevels(error);
+ std::vector<Named<CompatibilityMatrix>> matrixFragments;
+ auto matrixFragmentsStatus = getAllFrameworkMatrixLevels(&matrixFragments, error);
+ if (matrixFragmentsStatus != OK) {
+ return matrixFragmentsStatus;
+ }
if (matrixFragments.empty()) {
+ if (error && error->empty()) {
+ *error = "Cannot get framework matrix for each FCM version for unknown error.";
+ }
return NAME_NOT_FOUND;
}
@@ -338,47 +345,66 @@
}
}
-std::vector<Named<CompatibilityMatrix>> VintfObject::getAllFrameworkMatrixLevels(
- std::string* error) {
- std::vector<std::string> fileNames;
- std::vector<Named<CompatibilityMatrix>> results;
+status_t VintfObject::getOneMatrix(const std::string& path, Named<CompatibilityMatrix>* out,
+ std::string* error) {
+ std::string content;
+ status_t status = getFileSystem()->fetch(path, &content, error);
+ if (status != OK) {
+ return status;
+ }
+ if (!gCompatibilityMatrixConverter(&out->object, content, error)) {
+ if (error) {
+ error->insert(0, "Cannot parse " + path + ": ");
+ }
+ return BAD_VALUE;
+ }
+ out->name = path;
+ return OK;
+}
- if (getFileSystem()->listFiles(kSystemVintfDir, &fileNames, error) != OK) {
- return {};
+status_t VintfObject::getAllFrameworkMatrixLevels(std::vector<Named<CompatibilityMatrix>>* results,
+ std::string* error) {
+ std::vector<std::string> fileNames;
+
+ status_t listStatus = getFileSystem()->listFiles(kSystemVintfDir, &fileNames, error);
+ if (listStatus != OK) {
+ return listStatus;
}
for (const std::string& fileName : fileNames) {
std::string path = kSystemVintfDir + fileName;
-
- std::string content;
- std::string fetchError;
- status_t status = getFileSystem()->fetch(path, &content, &fetchError);
- if (status != OK) {
- appendLine(error, "Framework Matrix: Ignore file " + path + ": " + fetchError);
+ Named<CompatibilityMatrix> namedMatrix;
+ std::string matrixError;
+ status_t matrixStatus = getOneMatrix(path, &namedMatrix, &matrixError);
+ if (matrixStatus != OK) {
+ // System manifests and matrices share the same dir. Client may not have enough
+ // permissions to read system manifests, or may not be able to parse it.
+ auto logLevel = matrixStatus == BAD_VALUE ? base::DEBUG : base::ERROR;
+ LOG(logLevel) << "Framework Matrix: Ignore file " << path << ": " << matrixError;
continue;
}
-
- auto it = results.emplace(results.end());
- std::string parseError;
- if (!gCompatibilityMatrixConverter(&it->object, content, &parseError)) {
- appendLine(error, "Framework Matrix: Ignore file " + path + ": " + parseError);
- results.erase(it);
- continue;
- }
+ results->emplace_back(std::move(namedMatrix));
}
- if (results.empty()) {
- if (error) {
- error->insert(0, "No framework matrices under " + kSystemVintfDir +
- " can be fetched or parsed.\n");
- }
+ Named<CompatibilityMatrix> productMatrix;
+ std::string productError;
+ status_t productStatus = getOneMatrix(kProductMatrix, &productMatrix, &productError);
+ if (productStatus == OK) {
+ results->emplace_back(std::move(productMatrix));
+ } else if (productStatus == NAME_NOT_FOUND) {
+ LOG(DEBUG) << "Framework Matrix: missing " << kProductMatrix;
} else {
- if (error && !error->empty()) {
- LOG(WARNING) << *error;
- *error = "";
- }
+ if (error) *error = std::move(productError);
+ return productStatus;
}
- return results;
+ if (results->empty()) {
+ if (error) {
+ *error =
+ "No framework matrices under " + kSystemVintfDir + " can be fetched or parsed.\n";
+ }
+ return NAME_NOT_FOUND;
+ }
+ return OK;
}
std::shared_ptr<const RuntimeInfo> VintfObject::GetRuntimeInfo(bool skipCache,
@@ -541,11 +567,13 @@
const std::string kSystemVintfDir = "/system/etc/vintf/";
const std::string kVendorVintfDir = "/vendor/etc/vintf/";
const std::string kOdmVintfDir = "/odm/etc/vintf/";
+const std::string kProductVintfDir = "/product/etc/vintf/";
const std::string kVendorManifest = kVendorVintfDir + "manifest.xml";
const std::string kSystemManifest = kSystemVintfDir + "manifest.xml";
const std::string kVendorMatrix = kVendorVintfDir + "compatibility_matrix.xml";
const std::string kOdmManifest = kOdmVintfDir + "manifest.xml";
+const std::string kProductMatrix = kProductVintfDir + "compatibility_matrix.xml";
const std::string kVendorManifestFragmentDir = kVendorVintfDir + "manifest/";
const std::string kSystemManifestFragmentDir = kSystemVintfDir + "manifest/";
@@ -560,9 +588,17 @@
std::vector<std::string> dumpFileList() {
return {
- kSystemVintfDir, kVendorVintfDir, kOdmVintfDir, kOdmLegacyVintfDir,
-
- kVendorLegacyManifest, kVendorLegacyMatrix, kSystemLegacyManifest, kSystemLegacyMatrix,
+ // clang-format off
+ kSystemVintfDir,
+ kVendorVintfDir,
+ kOdmVintfDir,
+ kProductVintfDir,
+ kOdmLegacyVintfDir,
+ kVendorLegacyManifest,
+ kVendorLegacyMatrix,
+ kSystemLegacyManifest,
+ kSystemLegacyMatrix,
+ // clang-format on
};
}
@@ -658,10 +694,15 @@
return GetInstance()->checkDeprecation(listInstances, error);
}
int32_t VintfObject::checkDeprecation(const ListInstances& listInstances, std::string* error) {
- auto matrixFragments = getAllFrameworkMatrixLevels(error);
+ std::vector<Named<CompatibilityMatrix>> matrixFragments;
+ auto matrixFragmentsStatus = getAllFrameworkMatrixLevels(&matrixFragments, error);
+ if (matrixFragmentsStatus != OK) {
+ return matrixFragmentsStatus;
+ }
if (matrixFragments.empty()) {
- if (error && error->empty())
+ if (error && error->empty()) {
*error = "Cannot get framework matrix for each FCM version for unknown error.";
+ }
return NAME_NOT_FOUND;
}
auto deviceManifest = getDeviceHalManifest();