Merge changes from topic 'OMX Treble 19' into oc-dev

* changes:
  Update schema for media_profiles_V1_0.xml
  Add search paths for xml files for MediaProfiles
  Add media_profiles_V1_0.dtd
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index e2d48a2..b574df1 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -114,3 +114,15 @@
 
 include $(BUILD_SHARED_LIBRARY)
 
+#######################################
+# xml/media_profiles_V1_0.dtd
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := media_profiles_V1_0.dtd
+LOCAL_SRC_FILES := xml/$(LOCAL_MODULE)
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
+
+include $(BUILD_PREBUILT)
+
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index ff0e52e..aade69a 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -27,9 +27,11 @@
 #include <media/MediaProfiles.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <OMX_Video.h>
+#include <sys/stat.h>
 
 namespace android {
 
+constexpr char const * const MediaProfiles::xmlFiles[];
 Mutex MediaProfiles::sLock;
 bool MediaProfiles::sIsInitialized = false;
 MediaProfiles *MediaProfiles::sInstance = NULL;
@@ -593,14 +595,19 @@
     if (!sIsInitialized) {
         char value[PROPERTY_VALUE_MAX];
         if (property_get("media.settings.xml", value, NULL) <= 0) {
-            const char *defaultXmlFile = "/etc/media_profiles.xml";
-            FILE *fp = fopen(defaultXmlFile, "r");
-            if (fp == NULL) {
-                ALOGW("could not find media config xml file");
+            const char* xmlFile = nullptr;
+            for (auto const& f : xmlFiles) {
+                if (checkXmlFile(f)) {
+                    xmlFile = f;
+                    break;
+                }
+            }
+            if (xmlFile == nullptr) {
+                ALOGW("Could not find a validated xml file. "
+                        "Using the default instance instead.");
                 sInstance = createDefaultInstance();
             } else {
-                fclose(fp);  // close the file first.
-                sInstance = createInstanceFromXmlFile(defaultXmlFile);
+                sInstance = createInstanceFromXmlFile(xmlFile);
             }
         } else {
             sInstance = createInstanceFromXmlFile(value);
@@ -838,6 +845,12 @@
     return profiles;
 }
 
+bool MediaProfiles::checkXmlFile(const char* xmlFile) {
+    struct stat fStat;
+    return stat(xmlFile, &fStat) == 0 && S_ISREG(fStat.st_mode);
+    // TODO: Add validation
+}
+
 /*static*/ MediaProfiles*
 MediaProfiles::createInstanceFromXmlFile(const char *xml)
 {
diff --git a/media/libmedia/include/media/MediaProfiles.h b/media/libmedia/include/media/MediaProfiles.h
index e02918f..6975581 100644
--- a/media/libmedia/include/media/MediaProfiles.h
+++ b/media/libmedia/include/media/MediaProfiles.h
@@ -71,9 +71,34 @@
 {
 public:
 
+    /*
+     * If property media.settings.xml is not set:
+     *
+     * getInstance() will search through paths listed in xmlFiles.
+     * The search goes through members of xmlFiles in the order that they are
+     * defined, so files at lower indices have higher priority than those at
+     * higher indices.
+     *
+     * TODO: Add runtime validation of xml files. A search should be considered
+     * successful only when validation is successful.
+     */
+    static constexpr char const * const xmlFiles[] = {
+            "vendor/etc/media_profiles_V1_0.xml",
+            "system/etc/media_profiles.xml"
+            };
+
     /**
-     * Returns the singleton instance for subsequence queries.
-     * or NULL if error.
+     * Returns the singleton instance for subsequence queries or NULL if error.
+     *
+     * If property media.settings.xml is set, getInstance() will attempt to read
+     * from file path in media.settings.xml. Otherwise, getInstance() will
+     * search through the list xmlFiles as described above.
+     *
+     * If the search is unsuccessful, the default instance will be created
+     * instead.
+     *
+     * TODO: After validation is added, getInstance() should handle validation
+     * failure properly.
      */
     static MediaProfiles* getInstance();
 
@@ -335,6 +360,10 @@
     static void logVideoDecoderCap(const VideoDecoderCap& cap);
     static void logAudioDecoderCap(const AudioDecoderCap& cap);
 
+    // Returns true if xmlFile exists.
+    // TODO: Add runtime validation.
+    static bool checkXmlFile(const char* xmlFile);
+
     // If the xml configuration file does exist, use the settings
     // from the xml
     static MediaProfiles* createInstanceFromXmlFile(const char *xml);
diff --git a/media/libmedia/xml/media_profiles_V1_0.dtd b/media/libmedia/xml/media_profiles_V1_0.dtd
new file mode 100644
index 0000000..40900e0
--- /dev/null
+++ b/media/libmedia/xml/media_profiles_V1_0.dtd
@@ -0,0 +1,56 @@
+<!ELEMENT MediaSettings (CamcorderProfiles+,
+                         EncoderOutputFileFormat+,
+                         VideoEncoderCap+,
+                         AudioEncoderCap+,
+                         VideoDecoderCap,
+                         AudioDecoderCap)>
+<!ELEMENT CamcorderProfiles (EncoderProfile|ImageEncoding|ImageDecoding|Camera)+>
+<!ATTLIST CamcorderProfiles cameraId (0|1) #REQUIRED>
+<!ELEMENT EncoderProfile (Video, Audio)>
+<!ATTLIST EncoderProfile quality CDATA #REQUIRED>
+<!ATTLIST EncoderProfile fileFormat (mp4|3gp) #REQUIRED>
+<!ATTLIST EncoderProfile duration (30|60) #REQUIRED>
+<!ELEMENT Video EMPTY>
+<!ATTLIST Video codec (h264|h263|m4v) #REQUIRED>
+<!ATTLIST Video bitRate CDATA #REQUIRED>
+<!ATTLIST Video width CDATA #REQUIRED>
+<!ATTLIST Video height CDATA #REQUIRED>
+<!ATTLIST Video frameRate CDATA #REQUIRED>
+<!ELEMENT Audio EMPTY>
+<!ATTLIST Audio codec (amrnb|amrwb|aac) #REQUIRED>
+<!ATTLIST Audio bitRate CDATA #REQUIRED>
+<!ATTLIST Audio sampleRate CDATA #REQUIRED>
+<!ATTLIST Audio channels (1|2) #REQUIRED>
+<!ELEMENT ImageEncoding EMPTY>
+<!ATTLIST ImageEncoding quality (95|90|80|70|60|50|40) #REQUIRED>
+<!ELEMENT ImageDecoding EMPTY>
+<!ATTLIST ImageDecoding memCap CDATA #REQUIRED>
+<!ELEMENT Camera EMPTY>
+<!ELEMENT EncoderOutputFileFormat EMPTY>
+<!ATTLIST EncoderOutputFileFormat name (mp4|3gp) #REQUIRED>
+<!ELEMENT VideoEncoderCap EMPTY>
+<!ATTLIST VideoEncoderCap name (hevc|h264|h263|m4v|wmv) #REQUIRED>
+<!ATTLIST VideoEncoderCap enabled (true|false) #REQUIRED>
+<!ATTLIST VideoEncoderCap minBitRate CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxBitRate CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap minFrameWidth CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxFrameWidth CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap minFrameHeight CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxFrameHeight CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap minFrameRate CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxFrameRate CDATA #REQUIRED>
+<!ELEMENT AudioEncoderCap EMPTY>
+<!ATTLIST AudioEncoderCap name (amrnb|amrwb|aac|wma|heaac|aaceld) #REQUIRED>
+<!ATTLIST AudioEncoderCap enabled (true|false) #REQUIRED>
+<!ATTLIST AudioEncoderCap minBitRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap maxBitRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap minSampleRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap maxSampleRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap minChannels (1|2) #REQUIRED>
+<!ATTLIST AudioEncoderCap maxChannels (1|2) #REQUIRED>
+<!ELEMENT VideoDecoderCap EMPTY>
+<!ATTLIST VideoDecoderCap name (wmv) #REQUIRED>
+<!ATTLIST VideoDecoderCap enabled (true|false) #REQUIRED>
+<!ELEMENT AudioDecoderCap EMPTY>
+<!ATTLIST AudioDecoderCap name (wma) #REQUIRED>
+<!ATTLIST AudioDecoderCap enabled (true|false) #REQUIRED>