Add getXmlFilePath for manifest / matrix.
Return <path> or if it doesn't exist,
/{system,vendor}/etc/<name>_V<major>_<minor>.<format>
Test: libvintf_test
Test: vintf_object_test
Bug: 38359330
Change-Id: I80eff960a5dea91521e99e628e1af7cf52dad195
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp
index 907ac8c..509ca1d 100644
--- a/CompatibilityMatrix.cpp
+++ b/CompatibilityMatrix.cpp
@@ -16,6 +16,7 @@
#include "CompatibilityMatrix.h"
+#include "parse_string.h"
#include "utils.h"
namespace android {
@@ -57,6 +58,25 @@
return details::fetchAllInformation(path, gCompatibilityMatrixConverter, this);
}
+std::string CompatibilityMatrix::getXmlSchemaPath(const std::string& xmlFileName,
+ const Version& version) const {
+ using std::literals::string_literals::operator""s;
+ auto range = getXmlFiles(xmlFileName);
+ for (auto it = range.first; it != range.second; ++it) {
+ const MatrixXmlFile& matrixXmlFile = it->second;
+ if (matrixXmlFile.versionRange().contains(version)) {
+ if (!matrixXmlFile.overriddenPath().empty()) {
+ return matrixXmlFile.overriddenPath();
+ }
+ return "/"s + (type() == SchemaType::DEVICE ? "vendor" : "system") + "/etc/" +
+ xmlFileName + "_V" + std::to_string(matrixXmlFile.versionRange().majorVer) +
+ "_" + std::to_string(matrixXmlFile.versionRange().maxMinor) + "." +
+ to_string(matrixXmlFile.format());
+ }
+ }
+ return "";
+}
+
bool operator==(const CompatibilityMatrix &lft, const CompatibilityMatrix &rgt) {
return lft.mType == rgt.mType && lft.mHals == rgt.mHals && lft.mXmlFiles == rgt.mXmlFiles &&
(lft.mType != SchemaType::DEVICE || (lft.device.mVndk == rgt.device.mVndk)) &&
diff --git a/HalManifest.cpp b/HalManifest.cpp
index 5ebe083..f0fcf3f 100644
--- a/HalManifest.cpp
+++ b/HalManifest.cpp
@@ -374,6 +374,24 @@
return framework.mVndks;
}
+std::string HalManifest::getXmlFilePath(const std::string& xmlFileName,
+ const Version& version) const {
+ using std::literals::string_literals::operator""s;
+ auto range = getXmlFiles(xmlFileName);
+ for (auto it = range.first; it != range.second; ++it) {
+ const ManifestXmlFile& manifestXmlFile = it->second;
+ if (manifestXmlFile.version() == version) {
+ if (!manifestXmlFile.overriddenPath().empty()) {
+ return manifestXmlFile.overriddenPath();
+ }
+ return "/"s + (type() == SchemaType::DEVICE ? "vendor" : "system") + "/etc/" +
+ xmlFileName + "_V" + std::to_string(version.majorVer) + "_" +
+ std::to_string(version.minorVer) + ".xml";
+ }
+ }
+ return "";
+}
+
bool operator==(const HalManifest &lft, const HalManifest &rgt) {
return lft.mType == rgt.mType && lft.mHals == rgt.mHals && lft.mXmlFiles == rgt.mXmlFiles &&
(lft.mType != SchemaType::DEVICE ||
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h
index 66e5f8d..94b8004 100644
--- a/include/vintf/CompatibilityMatrix.h
+++ b/include/vintf/CompatibilityMatrix.h
@@ -43,7 +43,18 @@
constexpr static Version kVersion{1, 0};
-private:
+ // If the corresponding <xmlfile> with the given version exists, for the first match,
+ // - Return the overridden <path> if it is present,
+ // - otherwise the default value: /{system,vendor}/etc/<name>_V<major>_<minor-max>.<format>
+ // Otherwise if the <xmlfile> entry does not exist, "" is returned.
+ // For example, if the matrix says ["audio@1.0-5" -> "foo.xml", "audio@1.3-7" -> bar.xml]
+ // getXmlSchemaPath("audio", 1.0) -> foo.xml
+ // getXmlSchemaPath("audio", 1.5) -> foo.xml
+ // getXmlSchemaPath("audio", 1.7) -> bar.xml
+ // (Normally, version ranges do not overlap, and the only match is returned.)
+ std::string getXmlSchemaPath(const std::string& xmlFileName, const Version& version) const;
+
+ private:
bool add(MatrixHal &&hal);
bool add(MatrixKernel &&kernel);
diff --git a/include/vintf/HalManifest.h b/include/vintf/HalManifest.h
index 2f78301..31c4801 100644
--- a/include/vintf/HalManifest.h
+++ b/include/vintf/HalManifest.h
@@ -121,6 +121,12 @@
// Abort if type != framework.
const std::vector<Vndk> &vndks() const;
+ // If the corresponding <xmlfile> with the given version exists,
+ // - Return the overridden <path> if it is present,
+ // - otherwise the default value: /{system,vendor}/etc/<name>_V<major>_<minor>.xml
+ // Otherwise if the <xmlfile> entry does not exist, "" is returned.
+ std::string getXmlFilePath(const std::string& xmlFileName, const Version& version) const;
+
protected:
// Check before add()
bool shouldAdd(const ManifestHal& toAdd) const override;
diff --git a/test/main.cpp b/test/main.cpp
index 090fd3d..25694b9 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -1198,6 +1198,116 @@
gCompatibilityMatrixConverter.lastError());
}
+TEST_F(LibVintfTest, ManifestXmlFilePathDevice) {
+ std::string manifestXml =
+ "<manifest version=\"1.0\" type=\"device\">"
+ " <xmlfile>"
+ " <name>media_profile</name>"
+ " <version>1.0</version>"
+ " </xmlfile>"
+ "</manifest>";
+ HalManifest manifest;
+ EXPECT_TRUE(gHalManifestConverter(&manifest, manifestXml));
+ EXPECT_EQ(manifest.getXmlFilePath("media_profile", {1, 0}),
+ "/vendor/etc/media_profile_V1_0.xml");
+}
+
+TEST_F(LibVintfTest, ManifestXmlFilePathFramework) {
+ std::string manifestXml =
+ "<manifest version=\"1.0\" type=\"framework\">"
+ " <xmlfile>"
+ " <name>media_profile</name>"
+ " <version>1.0</version>"
+ " </xmlfile>"
+ "</manifest>";
+ HalManifest manifest;
+ EXPECT_TRUE(gHalManifestConverter(&manifest, manifestXml));
+ EXPECT_EQ(manifest.getXmlFilePath("media_profile", {1, 0}),
+ "/system/etc/media_profile_V1_0.xml");
+}
+
+TEST_F(LibVintfTest, ManifestXmlFilePathOverride) {
+ std::string manifestXml =
+ "<manifest version=\"1.0\" type=\"device\">"
+ " <xmlfile>"
+ " <name>media_profile</name>"
+ " <version>1.0</version>"
+ " <path>/vendor/etc/foo.xml</path>"
+ " </xmlfile>"
+ "</manifest>";
+ HalManifest manifest;
+ EXPECT_TRUE(gHalManifestConverter(&manifest, manifestXml));
+ EXPECT_EQ(manifest.getXmlFilePath("media_profile", {1, 0}), "/vendor/etc/foo.xml");
+}
+
+TEST_F(LibVintfTest, ManifestXmlFilePathMissing) {
+ std::string manifestXml =
+ "<manifest version=\"1.0\" type=\"device\">"
+ " <xmlfile>"
+ " <name>media_profile</name>"
+ " <version>1.1</version>"
+ " </xmlfile>"
+ "</manifest>";
+ HalManifest manifest;
+ EXPECT_TRUE(gHalManifestConverter(&manifest, manifestXml));
+ EXPECT_EQ(manifest.getXmlFilePath("media_profile", {1, 0}), "");
+}
+
+TEST_F(LibVintfTest, MatrixXmlFilePathFramework) {
+ std::string matrixXml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">"
+ " <xmlfile format=\"dtd\" optional=\"true\">"
+ " <name>media_profile</name>"
+ " <version>2.0-1</version>"
+ " </xmlfile>"
+ "</compatibility-matrix>";
+ CompatibilityMatrix matrix;
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&matrix, matrixXml));
+ EXPECT_EQ(matrix.getXmlSchemaPath("media_profile", {2, 1}),
+ "/system/etc/media_profile_V2_1.dtd");
+}
+
+TEST_F(LibVintfTest, MatrixXmlFilePathDevice) {
+ std::string matrixXml =
+ "<compatibility-matrix version=\"1.0\" type=\"device\">"
+ " <xmlfile format=\"xsd\" optional=\"true\">"
+ " <name>media_profile</name>"
+ " <version>2.0-1</version>"
+ " </xmlfile>"
+ "</compatibility-matrix>";
+ CompatibilityMatrix matrix;
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&matrix, matrixXml));
+ EXPECT_EQ(matrix.getXmlSchemaPath("media_profile", {2, 0}),
+ "/vendor/etc/media_profile_V2_1.xsd");
+}
+
+TEST_F(LibVintfTest, MatrixXmlFilePathOverride) {
+ std::string matrixXml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">"
+ " <xmlfile format=\"xsd\" optional=\"true\">"
+ " <name>media_profile</name>"
+ " <version>2.0-1</version>"
+ " <path>/system/etc/foo.xsd</path>"
+ " </xmlfile>"
+ "</compatibility-matrix>";
+ CompatibilityMatrix matrix;
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&matrix, matrixXml));
+ EXPECT_EQ(matrix.getXmlSchemaPath("media_profile", {2, 0}), "/system/etc/foo.xsd");
+}
+
+TEST_F(LibVintfTest, MatrixXmlFilePathMissing) {
+ std::string matrixXml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">"
+ " <xmlfile format=\"dtd\" optional=\"true\">"
+ " <name>media_profile</name>"
+ " <version>2.1</version>"
+ " </xmlfile>"
+ "</compatibility-matrix>";
+ CompatibilityMatrix matrix;
+ EXPECT_TRUE(gCompatibilityMatrixConverter(&matrix, matrixXml));
+ EXPECT_EQ(matrix.getXmlSchemaPath("media_profile", {2, 0}), "");
+}
+
} // namespace vintf
} // namespace android