/*
 * Copyright 2017, 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.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "MediaCodecsXmlParser"

#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>

#include <utils/Log.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/omx/OMXUtils.h>
#include <sys/stat.h>
#include <expat.h>

#include <cctype>
#include <algorithm>

namespace android {

namespace {

/**
 * Search for a file in a list of search directories.
 *
 * For each string `searchDir` in `searchDirs`, `searchDir/fileName` will be
 * tested whether it is a valid file name or not. If it is a valid file name,
 * the concatenated name (`searchDir/fileName`) will be stored in the output
 * variable `outPath`, and the function will return `true`. Otherwise, the
 * search continues until the `nullptr` element in `searchDirs` is reached, at
 * which point the function returns `false`.
 *
 * \param[in] searchDirs Null-terminated array of search paths.
 * \param[in] fileName Name of the file to search.
 * \param[out] outPath Full path of the file. `outPath` will hold a valid file
 * name if the return value of this function is `true`.
 * \return `true` if some element in `searchDirs` combined with `fileName` is a
 * valid file name; `false` otherwise.
 */
bool findFileInDirs(
        const char* const* searchDirs,
        const char *fileName,
        std::string *outPath) {
    for (; *searchDirs != nullptr; ++searchDirs) {
        *outPath = std::string(*searchDirs) + "/" + fileName;
        struct stat fileStat;
        if (stat(outPath->c_str(), &fileStat) == 0 &&
                S_ISREG(fileStat.st_mode)) {
            return true;
        }
    }
    return false;
}

bool strnEq(const char* s1, const char* s2, size_t count) {
    return strncmp(s1, s2, count) == 0;
}

bool strEq(const char* s1, const char* s2) {
    return strcmp(s1, s2) == 0;
}

bool striEq(const char* s1, const char* s2) {
    return strcasecmp(s1, s2) == 0;
}

bool strHasPrefix(const char* test, const char* prefix) {
    return strnEq(test, prefix, strlen(prefix));
}

bool parseBoolean(const char* s) {
    return striEq(s, "y") ||
            striEq(s, "yes") ||
            striEq(s, "t") ||
            striEq(s, "true") ||
            striEq(s, "1");
}

status_t limitFoundMissingAttr(const char* name, const char *attr, bool found = true) {
    ALOGE("limit '%s' with %s'%s' attribute", name,
            (found ? "" : "no "), attr);
    return BAD_VALUE;
}

status_t limitError(const char* name, const char *msg) {
    ALOGE("limit '%s' %s", name, msg);
    return BAD_VALUE;
}

status_t limitInvalidAttr(const char* name, const char* attr, const char* value) {
    ALOGE("limit '%s' with invalid '%s' attribute (%s)", name,
            attr, value);
    return BAD_VALUE;
}

}; // unnamed namespace

constexpr char const* MediaCodecsXmlParser::defaultSearchDirs[];
constexpr char const* MediaCodecsXmlParser::defaultMainXmlName;
constexpr char const* MediaCodecsXmlParser::defaultPerformanceXmlName;
constexpr char const* MediaCodecsXmlParser::defaultProfilingResultsXmlPath;

MediaCodecsXmlParser::MediaCodecsXmlParser(
        const char* const* searchDirs,
        const char* mainXmlName,
        const char* performanceXmlName,
        const char* profilingResultsXmlPath) :
    mParsingStatus(NO_INIT),
    mUpdate(false),
    mCodecCounter(0) {
    std::string path;
    if (findFileInDirs(searchDirs, mainXmlName, &path)) {
        parseTopLevelXMLFile(path.c_str(), false);
    } else {
        ALOGE("Cannot find %s", mainXmlName);
        mParsingStatus = NAME_NOT_FOUND;
    }
    if (findFileInDirs(searchDirs, performanceXmlName, &path)) {
        parseTopLevelXMLFile(path.c_str(), true);
    }
    if (profilingResultsXmlPath != nullptr) {
        parseTopLevelXMLFile(profilingResultsXmlPath, true);
    }
}

bool MediaCodecsXmlParser::parseTopLevelXMLFile(
        const char *codecs_xml,
        bool ignore_errors) {
    // get href_base
    const char *href_base_end = strrchr(codecs_xml, '/');
    if (href_base_end != nullptr) {
        mHrefBase = std::string(codecs_xml, href_base_end - codecs_xml + 1);
    }

    mParsingStatus = OK; // keeping this here for safety
    mCurrentSection = SECTION_TOPLEVEL;

    parseXMLFile(codecs_xml);

    if (mParsingStatus != OK) {
        ALOGW("parseTopLevelXMLFile(%s) failed", codecs_xml);
        if (ignore_errors) {
            mParsingStatus = OK;
            return false;
        }
        mCodecMap.clear();
        return false;
    }
    return true;
}

MediaCodecsXmlParser::~MediaCodecsXmlParser() {
}

void MediaCodecsXmlParser::parseXMLFile(const char *path) {
    FILE *file = fopen(path, "r");

    if (file == nullptr) {
        ALOGW("unable to open media codecs configuration xml file: %s", path);
        mParsingStatus = NAME_NOT_FOUND;
        return;
    }

    XML_Parser parser = ::XML_ParserCreate(nullptr);
    LOG_FATAL_IF(parser == nullptr, "XML_MediaCodecsXmlParserCreate() failed.");

    ::XML_SetUserData(parser, this);
    ::XML_SetElementHandler(
            parser, StartElementHandlerWrapper, EndElementHandlerWrapper);

    static constexpr int BUFF_SIZE = 512;
    while (mParsingStatus == OK) {
        void *buff = ::XML_GetBuffer(parser, BUFF_SIZE);
        if (buff == nullptr) {
            ALOGE("failed in call to XML_GetBuffer()");
            mParsingStatus = UNKNOWN_ERROR;
            break;
        }

        int bytes_read = ::fread(buff, 1, BUFF_SIZE, file);
        if (bytes_read < 0) {
            ALOGE("failed in call to read");
            mParsingStatus = ERROR_IO;
            break;
        }

        XML_Status status = ::XML_ParseBuffer(parser, bytes_read, bytes_read == 0);
        if (status != XML_STATUS_OK) {
            ALOGE("malformed (%s)", ::XML_ErrorString(::XML_GetErrorCode(parser)));
            mParsingStatus = ERROR_MALFORMED;
            break;
        }

        if (bytes_read == 0) {
            break;
        }
    }

    ::XML_ParserFree(parser);

    fclose(file);
    file = nullptr;
}

// static
void MediaCodecsXmlParser::StartElementHandlerWrapper(
        void *me, const char *name, const char **attrs) {
    static_cast<MediaCodecsXmlParser*>(me)->startElementHandler(name, attrs);
}

// static
void MediaCodecsXmlParser::EndElementHandlerWrapper(void *me, const char *name) {
    static_cast<MediaCodecsXmlParser*>(me)->endElementHandler(name);
}

status_t MediaCodecsXmlParser::includeXMLFile(const char **attrs) {
    const char *href = nullptr;
    size_t i = 0;
    while (attrs[i] != nullptr) {
        if (strEq(attrs[i], "href")) {
            if (attrs[++i] == nullptr) {
                return BAD_VALUE;
            }
            href = attrs[i];
        } else {
            ALOGE("includeXMLFile: unrecognized attribute: %s", attrs[i]);
            return BAD_VALUE;
        }
        ++i;
    }

    // For security reasons and for simplicity, file names can only contain
    // [a-zA-Z0-9_.] and must start with  media_codecs_ and end with .xml
    for (i = 0; href[i] != '\0'; i++) {
        if (href[i] == '.' || href[i] == '_' ||
                (href[i] >= '0' && href[i] <= '9') ||
                (href[i] >= 'A' && href[i] <= 'Z') ||
                (href[i] >= 'a' && href[i] <= 'z')) {
            continue;
        }
        ALOGE("invalid include file name: %s", href);
        return BAD_VALUE;
    }

    std::string filename = href;
    if (filename.compare(0, 13, "media_codecs_") != 0 ||
            filename.compare(filename.size() - 4, 4, ".xml") != 0) {
        ALOGE("invalid include file name: %s", href);
        return BAD_VALUE;
    }
    filename.insert(0, mHrefBase);

    status_t oldParsingStatus = mParsingStatus;

    parseXMLFile(filename.c_str());

    status_t newParsingStatus = mParsingStatus;
    mParsingStatus = oldParsingStatus;
    return newParsingStatus;
}

void MediaCodecsXmlParser::startElementHandler(
        const char *name, const char **attrs) {
    bool inType = true;

    if (strEq(name, "Include")) {
        if (includeXMLFile(attrs) == OK) {
            mSectionStack.push_back(mCurrentSection);
            mCurrentSection = SECTION_INCLUDE;
        }
        return;
    }

    switch (mCurrentSection) {
        case SECTION_TOPLEVEL:
        {
            if (strEq(name, "Decoders")) {
                mCurrentSection = SECTION_DECODERS;
            } else if (strEq(name, "Encoders")) {
                mCurrentSection = SECTION_ENCODERS;
            } else if (strEq(name, "Settings")) {
                mCurrentSection = SECTION_SETTINGS;
            }
            break;
        }

        case SECTION_SETTINGS:
        {
            if (strEq(name, "Setting")) {
                (void)addSettingFromAttributes(attrs);
            }
            break;
        }

        case SECTION_DECODERS:
        {
            if (strEq(name, "MediaCodec")) {
                (void)addMediaCodecFromAttributes(false /* encoder */, attrs);
                mCurrentSection = SECTION_DECODER;
            }
            break;
        }

        case SECTION_ENCODERS:
        {
            if (strEq(name, "MediaCodec")) {
                (void)addMediaCodecFromAttributes(true /* encoder */, attrs);
                mCurrentSection = SECTION_ENCODER;
            }
            break;
        }

        case SECTION_DECODER:
        case SECTION_ENCODER:
        {
            if (strEq(name, "Quirk")) {
                (void)addQuirk(attrs);
            } else if (strEq(name, "Type")) {
                (void)addTypeFromAttributes(attrs,
                        (mCurrentSection == SECTION_ENCODER));
                mCurrentSection =
                        (mCurrentSection == SECTION_DECODER ?
                        SECTION_DECODER_TYPE : SECTION_ENCODER_TYPE);
            }
        }
        inType = false;
        // fall through

        case SECTION_DECODER_TYPE:
        case SECTION_ENCODER_TYPE:
        {
            // ignore limits and features specified outside of type
            bool outside = !inType &&
                    mCurrentType == mCurrentCodec->second.typeMap.end();
            if (outside &&
                    (strEq(name, "Limit") || strEq(name, "Feature"))) {
                ALOGW("ignoring %s specified outside of a Type", name);
            } else if (strEq(name, "Limit")) {
                (void)addLimit(attrs);
            } else if (strEq(name, "Feature")) {
                (void)addFeature(attrs);
            }
            break;
        }

        default:
            break;
    }

}

void MediaCodecsXmlParser::endElementHandler(const char *name) {
    switch (mCurrentSection) {
        case SECTION_SETTINGS:
        {
            if (strEq(name, "Settings")) {
                mCurrentSection = SECTION_TOPLEVEL;
            }
            break;
        }

        case SECTION_DECODERS:
        {
            if (strEq(name, "Decoders")) {
                mCurrentSection = SECTION_TOPLEVEL;
            }
            break;
        }

        case SECTION_ENCODERS:
        {
            if (strEq(name, "Encoders")) {
                mCurrentSection = SECTION_TOPLEVEL;
            }
            break;
        }

        case SECTION_DECODER_TYPE:
        case SECTION_ENCODER_TYPE:
        {
            if (strEq(name, "Type")) {
                mCurrentSection =
                        (mCurrentSection == SECTION_DECODER_TYPE ?
                        SECTION_DECODER : SECTION_ENCODER);

                mCurrentType = mCurrentCodec->second.typeMap.end();
            }
            break;
        }

        case SECTION_DECODER:
        {
            if (strEq(name, "MediaCodec")) {
                mCurrentSection = SECTION_DECODERS;
                mCurrentName.clear();
            }
            break;
        }

        case SECTION_ENCODER:
        {
            if (strEq(name, "MediaCodec")) {
                mCurrentSection = SECTION_ENCODERS;
                mCurrentName.clear();
            }
            break;
        }

        case SECTION_INCLUDE:
        {
            if (strEq(name, "Include") && (mSectionStack.size() > 0)) {
                mCurrentSection = mSectionStack.back();
                mSectionStack.pop_back();
            }
            break;
        }

        default:
            break;
    }

}

status_t MediaCodecsXmlParser::addSettingFromAttributes(const char **attrs) {
    const char *name = nullptr;
    const char *value = nullptr;
    const char *update = nullptr;

    size_t i = 0;
    while (attrs[i] != nullptr) {
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addSettingFromAttributes: name is null");
                return BAD_VALUE;
            }
            name = attrs[i];
        } else if (strEq(attrs[i], "value")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addSettingFromAttributes: value is null");
                return BAD_VALUE;
            }
            value = attrs[i];
        } else if (strEq(attrs[i], "update")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addSettingFromAttributes: update is null");
                return BAD_VALUE;
            }
            update = attrs[i];
        } else {
            ALOGE("addSettingFromAttributes: unrecognized attribute: %s", attrs[i]);
            return BAD_VALUE;
        }
        ++i;
    }

    if (name == nullptr || value == nullptr) {
        ALOGE("addSettingFromAttributes: name or value unspecified");
        return BAD_VALUE;
    }

    // Boolean values are converted to "0" or "1".
    if (strHasPrefix(name, "supports-")) {
        value = parseBoolean(value) ? "1" : "0";
    }

    mUpdate = (update != nullptr) && parseBoolean(update);
    auto attribute = mServiceAttributeMap.find(name);
    if (attribute == mServiceAttributeMap.end()) { // New attribute name
        if (mUpdate) {
            ALOGE("addSettingFromAttributes: updating non-existing setting");
            return BAD_VALUE;
        }
        mServiceAttributeMap.insert(Attribute(name, value));
    } else { // Existing attribute name
        if (!mUpdate) {
            ALOGE("addSettingFromAttributes: adding existing setting");
        }
        attribute->second = value;
    }

    return OK;
}

status_t MediaCodecsXmlParser::addMediaCodecFromAttributes(
        bool encoder, const char **attrs) {
    const char *name = nullptr;
    const char *type = nullptr;
    const char *update = nullptr;

    size_t i = 0;
    while (attrs[i] != nullptr) {
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addMediaCodecFromAttributes: name is null");
                return BAD_VALUE;
            }
            name = attrs[i];
        } else if (strEq(attrs[i], "type")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addMediaCodecFromAttributes: type is null");
                return BAD_VALUE;
            }
            type = attrs[i];
        } else if (strEq(attrs[i], "update")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addMediaCodecFromAttributes: update is null");
                return BAD_VALUE;
            }
            update = attrs[i];
        } else {
            ALOGE("addMediaCodecFromAttributes: unrecognized attribute: %s", attrs[i]);
            return BAD_VALUE;
        }
        ++i;
    }

    if (name == nullptr) {
        ALOGE("addMediaCodecFromAttributes: name not found");
        return BAD_VALUE;
    }

    mUpdate = (update != nullptr) && parseBoolean(update);
    mCurrentCodec = mCodecMap.find(name);
    if (mCurrentCodec == mCodecMap.end()) { // New codec name
        if (mUpdate) {
            ALOGW("addMediaCodecFromAttributes: cannot update "
                  "non-existing codec \"%s\".", name);
            return BAD_VALUE;
        }
        // Create a new codec in mCodecMap
        mCurrentCodec = mCodecMap.insert(
                Codec(name, CodecProperties())).first;
        if (type != nullptr) {
            mCurrentType = mCurrentCodec->second.typeMap.insert(
                    Type(type, AttributeMap())).first;
        } else {
            mCurrentType = mCurrentCodec->second.typeMap.end();
        }
        mCurrentCodec->second.isEncoder = encoder;
        mCurrentCodec->second.order = mCodecCounter++;
    } else { // Existing codec name
        if (!mUpdate) {
            ALOGW("addMediaCodecFromAttributes: trying to add "
                  "existing codec \"%s\"", name);
            return ALREADY_EXISTS;
        }
        if (type != nullptr) {
            mCurrentType = mCurrentCodec->second.typeMap.find(type);
            if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
                ALOGE("addMediaCodecFromAttributes: cannot update "
                      "non-existing type \"%s\" for codec \"%s\"",
                        type, name);
                return BAD_VALUE;
            }
        } else {
            // This should happen only when the codec has at most one type.
            mCurrentType = mCurrentCodec->second.typeMap.begin();
            if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
                ALOGE("addMediaCodecFromAttributes: cannot update "
                      "codec \"%s\" without type specified", name);
                return BAD_VALUE;
            }
        }
    }

    return OK;
}

status_t MediaCodecsXmlParser::addQuirk(const char **attrs) {
    if (mCurrentCodec == mCodecMap.end()) {
        return BAD_VALUE;
    }

    const char *name = nullptr;

    size_t i = 0;
    while (attrs[i] != nullptr) {
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addQuirk: name is null");
                return BAD_VALUE;
            }
            name = attrs[i];
        } else {
            ALOGE("addQuirk: unrecognized attribute: %s", attrs[i]);
            return BAD_VALUE;
        }
        ++i;
    }

    if (name == nullptr) {
        ALOGE("addQuirk: name not found");
        return BAD_VALUE;
    }

    mCurrentCodec->second.quirkSet.emplace(name);
    return OK;
}

status_t MediaCodecsXmlParser::addTypeFromAttributes(const char **attrs, bool encoder) {
    if (mCurrentCodec == mCodecMap.end()) {
        return BAD_VALUE;
    }

    const char *name = nullptr;
    const char *update = nullptr;

    size_t i = 0;
    while (attrs[i] != nullptr) {
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addTypeFromAttributes: name is null");
                return BAD_VALUE;
            }
            name = attrs[i];
        } else if (strEq(attrs[i], "update")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addTypeFromAttributes: update is null");
                return BAD_VALUE;
            }
            update = attrs[i];
        } else {
            ALOGE("addTypeFromAttributes: unrecognized attribute: %s", attrs[i]);
            return BAD_VALUE;
        }
        ++i;
    }

    if (name == nullptr) {
        return BAD_VALUE;
    }

    mCurrentCodec->second.isEncoder = encoder;
    mCurrentType = mCurrentCodec->second.typeMap.find(name);
    if (!mUpdate) {
        if (mCurrentType != mCurrentCodec->second.typeMap.end()) {
            ALOGW("addTypeFromAttributes: trying to update "
                  "existing type \"%s\"", name);
            return ALREADY_EXISTS;
        }
        mCurrentType = mCurrentCodec->second.typeMap.insert(
                Type(name, AttributeMap())).first;
    } else if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
        ALOGE("addTypeFromAttributes: updating non-existing type");
        return BAD_VALUE;
    }
    return OK;
}

status_t MediaCodecsXmlParser::addLimit(const char **attrs) {
    if (mCurrentCodec == mCodecMap.end()) {
        return BAD_VALUE;
    }
    if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
        return BAD_VALUE;
    }

    const char* a_name = nullptr;
    const char* a_default = nullptr;
    const char* a_in = nullptr;
    const char* a_max = nullptr;
    const char* a_min = nullptr;
    const char* a_range = nullptr;
    const char* a_ranges = nullptr;
    const char* a_scale = nullptr;
    const char* a_value = nullptr;

    size_t i = 0;
    while (attrs[i] != nullptr) {
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: name is null");
                return BAD_VALUE;
            }
            a_name = attrs[i];
        } else if (strEq(attrs[i], "default")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: default is null");
                return BAD_VALUE;
            }
            a_default = attrs[i];
        } else if (strEq(attrs[i], "in")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: in is null");
                return BAD_VALUE;
            }
            a_in = attrs[i];
        } else if (strEq(attrs[i], "max")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: max is null");
                return BAD_VALUE;
            }
            a_max = attrs[i];
        } else if (strEq(attrs[i], "min")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: min is null");
                return BAD_VALUE;
            }
            a_min = attrs[i];
        } else if (strEq(attrs[i], "range")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: range is null");
                return BAD_VALUE;
            }
            a_range = attrs[i];
        } else if (strEq(attrs[i], "ranges")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: ranges is null");
                return BAD_VALUE;
            }
            a_ranges = attrs[i];
        } else if (strEq(attrs[i], "scale")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: scale is null");
                return BAD_VALUE;
            }
            a_scale = attrs[i];
        } else if (strEq(attrs[i], "value")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: value is null");
                return BAD_VALUE;
            }
            a_value = attrs[i];
        } else {
            ALOGE("addLimit: unrecognized limit: %s", attrs[i]);
            return BAD_VALUE;
        }
        ++i;
    }

    if (a_name == nullptr) {
        ALOGE("limit with no 'name' attribute");
        return BAD_VALUE;
    }

    // size, blocks, bitrate, frame-rate, blocks-per-second, aspect-ratio,
    // measured-frame-rate, measured-blocks-per-second: range
    // quality: range + default + [scale]
    // complexity: range + default
    std::string range;
    if (strEq(a_name, "aspect-ratio") ||
            strEq(a_name, "bitrate") ||
            strEq(a_name, "block-count") ||
            strEq(a_name, "blocks-per-second") ||
            strEq(a_name, "complexity") ||
            strEq(a_name, "frame-rate") ||
            strEq(a_name, "quality") ||
            strEq(a_name, "size") ||
            strEq(a_name, "measured-blocks-per-second") ||
            strHasPrefix(a_name, "measured-frame-rate-")) {
        // "range" is specified in exactly one of the following forms:
        // 1) min-max
        // 2) value-value
        // 3) range
        if (a_min != nullptr && a_max != nullptr) {
            // min-max
            if (a_range != nullptr || a_value != nullptr) {
                return limitError(a_name, "has 'min' and 'max' as well as 'range' or "
                        "'value' attributes");
            }
            range = a_min;
            range += '-';
            range += a_max;
        } else if (a_min != nullptr || a_max != nullptr) {
            return limitError(a_name, "has only 'min' or 'max' attribute");
        } else if (a_value != nullptr) {
            // value-value
            if (a_range != nullptr) {
                return limitError(a_name, "has both 'range' and 'value' attributes");
            }
            range = a_value;
            range += '-';
            range += a_value;
        } else if (a_range == nullptr) {
            return limitError(a_name, "with no 'range', 'value' or 'min'/'max' attributes");
        } else {
            // range
            range = a_range;
        }

        // "aspect-ratio" requires some special treatment.
        if (strEq(a_name, "aspect-ratio")) {
            // "aspect-ratio" must have "in".
            if (a_in == nullptr) {
                return limitFoundMissingAttr(a_name, "in", false);
            }
            // "in" must be either "pixels" or "blocks".
            if (!strEq(a_in, "pixels") && !strEq(a_in, "blocks")) {
                return limitInvalidAttr(a_name, "in", a_in);
            }
            // name will be "pixel-aspect-ratio-range" or
            // "block-aspect-ratio-range".
            mCurrentType->second[
                    std::string(a_in).substr(0, strlen(a_in) - 1) +
                    "-aspect-ratio-range"] = range;
        } else {
            // For everything else (apart from "aspect-ratio"), simply append
            // "-range" to the name for the range-type property.
            mCurrentType->second[std::string(a_name) + "-range"] = range;

            // Only "quality" may have "scale".
            if (!strEq(a_name, "quality") && a_scale != nullptr) {
                return limitFoundMissingAttr(a_name, "scale");
            } else if (strEq(a_name, "quality")) {
                // The default value of "quality-scale" is "linear".
                mCurrentType->second["quality-scale"] = a_scale == nullptr ?
                        "linear" : a_scale;
            }

            // "quality" and "complexity" must have "default".
            // Other limits must not have "default".
            if (strEq(a_name, "quality") || strEq(a_name, "complexity")) {
                if (a_default == nullptr) {
                    return limitFoundMissingAttr(a_name, "default", false);
                }
                // name will be "quality-default" or "complexity-default".
                mCurrentType->second[std::string(a_name) + "-default"] = a_default;
            } else if (a_default != nullptr) {
                return limitFoundMissingAttr(a_name, "default", true);
            }
        }
    } else {
        if (a_default != nullptr) {
            return limitFoundMissingAttr(a_name, "default");
        }
        if (a_in != nullptr) {
            return limitFoundMissingAttr(a_name, "in");
        }
        if (a_scale != nullptr) {
            return limitFoundMissingAttr(a_name, "scale");
        }
        if (a_range != nullptr) {
            return limitFoundMissingAttr(a_name, "range");
        }
        if (a_min != nullptr) {
            return limitFoundMissingAttr(a_name, "min");
        }

        if (a_max != nullptr) {
            // "max" must exist if and only if name is "channel-count" or
            // "concurrent-instances".
            // "min" is not ncessary.
            if (strEq(a_name, "channel-count") ||
                    strEq(a_name, "concurrent-instances")) {
                mCurrentType->second[std::string("max-") + a_name] = a_max;
            } else {
                return limitFoundMissingAttr(a_name, "max", false);
            }
        } else if (strEq(a_name, "channel-count") ||
                strEq(a_name, "concurrent-instances")) {
            return limitFoundMissingAttr(a_name, "max");
        }

        if (a_ranges != nullptr) {
            // "ranges" must exist if and only if name is "sample-rate".
            if (strEq(a_name, "sample-rate")) {
                mCurrentType->second["sample-rate-ranges"] = a_ranges;
            } else {
                return limitFoundMissingAttr(a_name, "ranges", false);
            }
        } else if (strEq(a_name, "sample-rate")) {
            return limitFoundMissingAttr(a_name, "ranges");
        }

        if (a_value != nullptr) {
            // "value" must exist if and only if name is "alignment" or
            // "block-size".
            if (strEq(a_name, "alignment") || strEq(a_name, "block-size")) {
                mCurrentType->second[a_name] = a_value;
            } else {
                return limitFoundMissingAttr(a_name, "value", false);
            }
        } else if (strEq(a_name, "alignment") || strEq(a_name, "block-size")) {
            return limitFoundMissingAttr(a_name, "value", false);
        }

    }

    return OK;
}

status_t MediaCodecsXmlParser::addFeature(const char **attrs) {
    if (mCurrentCodec == mCodecMap.end()) {
        return BAD_VALUE;
    }
    if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
        return BAD_VALUE;
    }

    size_t i = 0;
    const char *name = nullptr;
    int32_t optional = -1;
    int32_t required = -1;
    const char *value = nullptr;

    while (attrs[i] != nullptr) {
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addFeature: name is null");
                return BAD_VALUE;
            }
            name = attrs[i];
        } else if (strEq(attrs[i], "optional")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addFeature: optional is null");
                return BAD_VALUE;
            }
            optional = parseBoolean(attrs[i]) ? 1 : 0;
        } else if (strEq(attrs[i], "required")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addFeature: required is null");
                return BAD_VALUE;
            }
            required = parseBoolean(attrs[i]) ? 1 : 0;
        } else if (strEq(attrs[i], "value")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addFeature: value is null");
                return BAD_VALUE;
            }
            value = attrs[i];
        } else {
            ALOGE("addFeature: unrecognized attribute: %s", attrs[i]);
            return BAD_VALUE;
        }
        ++i;
    }

    // Every feature must have a name.
    if (name == nullptr) {
        ALOGE("feature with no 'name' attribute");
        return BAD_VALUE;
    }

    if ((optional != -1) || (required != -1)) {
        if (optional == required) {
            ALOGE("feature '%s' is both/neither optional and required", name);
            return BAD_VALUE;
        }
        if ((optional == 1) || (required == 1)) {
            if (value != nullptr) {
                ALOGE("feature '%s' cannot have extra 'value'", name);
                return BAD_VALUE;
            }
            mCurrentType->second[std::string("feature-") + name] =
                    optional == 1 ? "0" : "1";
            return OK;
        }
    }
    mCurrentType->second[std::string("feature-") + name] = value == nullptr ?
            "0" : value;
    return OK;
}

const MediaCodecsXmlParser::AttributeMap&
        MediaCodecsXmlParser::getServiceAttributeMap() const {
    return mServiceAttributeMap;
}

const MediaCodecsXmlParser::CodecMap&
        MediaCodecsXmlParser::getCodecMap() const {
    return mCodecMap;
}

const MediaCodecsXmlParser::RoleMap&
        MediaCodecsXmlParser::getRoleMap() const {
    if (mRoleMap.empty()) {
        generateRoleMap();
    }
    return mRoleMap;
}

const char* MediaCodecsXmlParser::getCommonPrefix() const {
    if (mCommonPrefix.empty()) {
        generateCommonPrefix();
    }
    return mCommonPrefix.data();
}

status_t MediaCodecsXmlParser::getParsingStatus() const {
    return mParsingStatus;
}

void MediaCodecsXmlParser::generateRoleMap() const {
    for (const auto& codec : mCodecMap) {
        const auto& codecName = codec.first;
        bool isEncoder = codec.second.isEncoder;
        size_t order = codec.second.order;
        const auto& typeMap = codec.second.typeMap;
        for (const auto& type : typeMap) {
            const auto& typeName = type.first;
            const char* roleName = GetComponentRole(isEncoder, typeName.data());
            if (roleName == nullptr) {
                ALOGE("Cannot find the role for %s of type %s",
                        isEncoder ? "an encoder" : "a decoder",
                        typeName.data());
                continue;
            }
            const auto& typeAttributeMap = type.second;

            auto roleIterator = mRoleMap.find(roleName);
            std::multimap<size_t, NodeInfo>* nodeList;
            if (roleIterator == mRoleMap.end()) {
                RoleProperties roleProperties;
                roleProperties.type = typeName;
                roleProperties.isEncoder = isEncoder;
                auto insertResult = mRoleMap.insert(
                        std::make_pair(roleName, roleProperties));
                if (!insertResult.second) {
                    ALOGE("Cannot add role %s", roleName);
                    continue;
                }
                nodeList = &insertResult.first->second.nodeList;
            } else {
                if (roleIterator->second.type != typeName) {
                    ALOGE("Role %s has mismatching types: %s and %s",
                            roleName,
                            roleIterator->second.type.data(),
                            typeName.data());
                    continue;
                }
                if (roleIterator->second.isEncoder != isEncoder) {
                    ALOGE("Role %s cannot be both an encoder and a decoder",
                            roleName);
                    continue;
                }
                nodeList = &roleIterator->second.nodeList;
            }

            NodeInfo nodeInfo;
            nodeInfo.name = codecName;
            nodeInfo.attributeList.reserve(typeAttributeMap.size());
            for (const auto& attribute : typeAttributeMap) {
                nodeInfo.attributeList.push_back(
                        Attribute{attribute.first, attribute.second});
            }
            nodeList->insert(std::make_pair(
                    std::move(order), std::move(nodeInfo)));
        }
    }
}

void MediaCodecsXmlParser::generateCommonPrefix() const {
    if (mCodecMap.empty()) {
        return;
    }
    auto i = mCodecMap.cbegin();
    auto first = i->first.cbegin();
    auto last = i->first.cend();
    for (++i; i != mCodecMap.cend(); ++i) {
        last = std::mismatch(
                first, last, i->first.cbegin(), i->first.cend()).first;
    }
    mCommonPrefix.insert(mCommonPrefix.begin(), first, last);
}

} // namespace android

