Allow XML file paths to be customized with sysprop

Three properties are declared as vendor-init-settable:
ro.media.xml_variant.codecs
ro.media.xml_variant.codecs_performance
ro.media.xml_variant.profiles

media_codecs.xml can now be named
media_codecs${ro.media.xml_variant.codecs}.xml

media_codecs_performance.xml can now be named
media_codecs_performance${ro.media.xml_variant.codecs_performance}.xml

media_profiles_V1_0 can now be named
media_profiles${ro.media.xml_variant.profiles}.xml

Test: Rename "media_codecs.xml" to "media_codecs_test.xml",
set ro.media.xml_variant.codecs to "_test", then
call "stagefright -i".

Test: Rename "media_codecs_performance.xml" to
"media_codecs_performance_test.xml",
set ro.media.xml_variant.codecs_performance to "_test", then
run android.media.cts.VideoDecoderPerfTest.

Test: Rename "media_profiles_V1_0.xml" to "media_profiles_test.xml",
set ro.media.xml_variant.profiles to "_test", then
run vts_mediaProfiles_validate_test.

Bug: 142102953
Change-Id: I38fa2924e02363639d1cdc3dd85128e0652343ee
Merged-In: I38fa2924e02363639d1cdc3dd85128e0652343ee
diff --git a/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp b/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
index 7729d52..4f3951a 100644
--- a/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
+++ b/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
@@ -14,23 +14,68 @@
  * limitations under the License.
  */
 
+#include <fstream>
 #include <string>
 
 #include <android-base/file.h>
 #include <android-base/properties.h>
 #include "utility/ValidateXml.h"
 
+bool isFileReadable(std::string const& path) {
+  std::ifstream f(path);
+  return f.good();
+}
+
 TEST(CheckConfig, mediaProfilesValidation) {
     RecordProperty("description",
                    "Verify that the media profiles file "
                    "is valid according to the schema");
 
+    // Schema path.
+    constexpr char const* xsdPath = "/data/local/tmp/media_profiles.xsd";
+
+    // If "media.settings.xml" is set, it will be used as an absolute path.
     std::string mediaSettingsPath = android::base::GetProperty("media.settings.xml", "");
     if (mediaSettingsPath.empty()) {
-        mediaSettingsPath.assign("/vendor/etc/media_profiles_V1_0.xml");
-    }
+        // If "media.settings.xml" is not set, we will search through a list of
+        // file paths.
 
-    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(android::base::Basename(mediaSettingsPath).c_str(),
-                                            {android::base::Dirname(mediaSettingsPath).c_str()},
-                                            "/data/local/tmp/media_profiles.xsd");
+        constexpr char const* xmlSearchDirs[] = {
+                "/product/etc/",
+                "/odm/etc/",
+                "/vendor/etc/",
+            };
+
+        // The vendor may provide a vendor variant for the file name.
+        std::string variant = android::base::GetProperty(
+                "ro.media.xml_variant.profiles", "_V1_0");
+        std::string fileName = "media_profiles" + variant + ".xml";
+
+        // Fallback path does not depend on the property defined from the vendor
+        // partition.
+        constexpr char const* fallbackXmlPath =
+                "/system/etc/media_profiles_V1_0.xml";
+
+        std::vector<std::string> xmlPaths = {
+                xmlSearchDirs[0] + fileName,
+                xmlSearchDirs[1] + fileName,
+                xmlSearchDirs[2] + fileName,
+                fallbackXmlPath
+            };
+
+        auto findXmlPath =
+            std::find_if(xmlPaths.begin(), xmlPaths.end(), isFileReadable);
+        ASSERT_TRUE(findXmlPath != xmlPaths.end())
+                << "Cannot read from " << fileName
+                << " in any search directories ("
+                << xmlSearchDirs[0] << ", "
+                << xmlSearchDirs[1] << ", "
+                << xmlSearchDirs[2] << ") and from "
+                << fallbackXmlPath << ".";
+
+        char const* xmlPath = findXmlPath->c_str();
+        EXPECT_VALID_XML(xmlPath, xsdPath);
+    } else {
+        EXPECT_VALID_XML(mediaSettingsPath.c_str(), xsdPath);
+    }
 }