Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f22f5ddb authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Allow XML file paths to be customized with sysprop" am: 931d1554 am: 32a4b317

Change-Id: I3677fb8d63d08eef3517b795ae42622216d0268f
parents 3c93a915 32a4b317
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -319,10 +319,11 @@ status_t Codec2InfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
    // Obtain Codec2Client
    std::vector<Traits> traits = Codec2Client::ListComponents();

    // parse APEX XML first, followed by vendor XML
    // parse APEX XML first, followed by vendor XML.
    // Note: APEX XML names do not depend on ro.media.xml_variant.* properties.
    MediaCodecsXmlParser parser;
    parser.parseXmlFilesInSearchDirs(
            parser.getDefaultXmlNames(),
            { "media_codecs.xml", "media_codecs_performance.xml" },
            { "/apex/com.android.media.swcodec/etc" });

    // TODO: remove these c2-specific files once product moved to default file names
+49 −3
Original line number Diff line number Diff line
@@ -29,9 +29,55 @@
#include <OMX_Video.h>
#include <sys/stat.h>

#include <array>
#include <string>
#include <vector>

namespace android {

constexpr char const * const MediaProfiles::xmlFiles[];
namespace /* unnamed */ {

// Returns a list of possible paths for the media_profiles XML file.
std::array<char const*, 5> const& getXmlPaths() {
    static std::array<std::string const, 5> const paths =
        []() -> decltype(paths) {
            // Directories for XML file that will be searched (in this order).
            constexpr std::array<char const*, 4> searchDirs = {
                "product/etc/",
                "odm/etc/",
                "vendor/etc/",
                "system/etc/",
            };

            // The file name may contain a variant if the vendor property
            // ro.vendor.media_profiles_xml_variant is set.
            char variant[PROPERTY_VALUE_MAX];
            property_get("ro.media.xml_variant.profiles",
                         variant,
                         "_V1_0");

            std::string fileName =
                std::string("media_profiles") + variant + ".xml";

            return { searchDirs[0] + fileName,
                     searchDirs[1] + fileName,
                     searchDirs[2] + fileName,
                     searchDirs[3] + fileName,
                     "system/etc/media_profiles_V1_0.xml" // System fallback
                   };
        }();
    static std::array<char const*, 5> const cPaths = {
            paths[0].data(),
            paths[1].data(),
            paths[2].data(),
            paths[3].data(),
            paths[4].data()
        };
    return cPaths;
}

} // unnamed namespace

Mutex MediaProfiles::sLock;
bool MediaProfiles::sIsInitialized = false;
MediaProfiles *MediaProfiles::sInstance = NULL;
@@ -610,7 +656,7 @@ MediaProfiles::getInstance()
        char value[PROPERTY_VALUE_MAX];
        if (property_get("media.settings.xml", value, NULL) <= 0) {
            const char* xmlFile = nullptr;
            for (auto const& f : xmlFiles) {
            for (auto const& f : getXmlPaths()) {
                if (checkXmlFile(f)) {
                    xmlFile = f;
                    break;
+15 −32
Original line number Diff line number Diff line
/*
 **
 ** Copyright 2010, The Android Open Source Project.
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 *
 * Copyright 2010, The Android Open Source Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_MEDIAPROFILES_H
@@ -82,29 +82,12 @@ class MediaProfiles
{
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[] = {
            "odm/etc/media_profiles_V1_0.xml",
            "vendor/etc/media_profiles_V1_0.xml",
            "system/etc/media_profiles.xml"
            };

    /**
     * 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.
     * search through the list of preset XML file paths.
     *
     * If the search is unsuccessful, the default instance will be created
     * instead.
+50 −5
Original line number Diff line number Diff line
@@ -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.

        constexpr char const* xmlSearchDirs[] = {
                "/product/etc/",
                "/odm/etc/",
                "/vendor/etc/",
            };

    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(android::base::Basename(mediaSettingsPath).c_str(),
                                            {android::base::Dirname(mediaSettingsPath).c_str()},
                                            "/data/local/tmp/media_profiles.xsd");
        // 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);
    }
}
+20 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/properties.h>
#include <utils/Log.h>

#include <media/stagefright/MediaErrors.h>
@@ -38,8 +39,6 @@

namespace android {

using MCXP = MediaCodecsXmlParser;

namespace {

bool fileExists(const std::string &path) {
@@ -118,8 +117,8 @@ status_t combineStatus(status_t a, status_t b) {
    }
}

MCXP::StringSet parseCommaSeparatedStringSet(const char *s) {
    MCXP::StringSet result;
MediaCodecsXmlParser::StringSet parseCommaSeparatedStringSet(const char *s) {
    MediaCodecsXmlParser::StringSet result;
    for (const char *ptr = s ? : ""; *ptr; ) {
        const char *end = strchrnul(ptr, ',');
        if (ptr != end) { // skip empty values
@@ -136,6 +135,23 @@ MCXP::StringSet parseCommaSeparatedStringSet(const char *s) {

}  // unnamed namespace

std::vector<std::string> MediaCodecsXmlParser::getDefaultXmlNames() {
    static constexpr char const* prefixes[] = {
            "media_codecs",
            "media_codecs_performance"
        };
    static std::vector<std::string> variants = {
            android::base::GetProperty("ro.media.xml_variant.codecs", ""),
            android::base::GetProperty("ro.media.xml_variant.codecs_performance", "")
        };
    static std::vector<std::string> names = {
            prefixes[0] + variants[0] + ".xml",
            prefixes[1] + variants[1] + ".xml"
        };
    return names;
}


struct MediaCodecsXmlParser::Impl {
    // status + error message
    struct Result {
Loading