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

Commit 1fc768da authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Relax error handling in MediaCodecsXmlParser"

parents fd771a4f ea39c524
Loading
Loading
Loading
Loading
+99 −84
Original line number Diff line number Diff line
@@ -92,18 +92,18 @@ bool parseBoolean(const char* s) {
status_t limitFoundMissingAttr(const char* name, const char *attr, bool found = true) {
    ALOGE("limit '%s' with %s'%s' attribute", name,
            (found ? "" : "no "), attr);
    return -EINVAL;
    return BAD_VALUE;
}

status_t limitError(const char* name, const char *msg) {
    ALOGE("limit '%s' %s", name, msg);
    return -EINVAL;
    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 -EINVAL;
    return BAD_VALUE;
}

}; // unnamed namespace
@@ -232,12 +232,12 @@ status_t MediaCodecsXmlParser::includeXMLFile(const char **attrs) {
    while (attrs[i] != nullptr) {
        if (strEq(attrs[i], "href")) {
            if (attrs[++i] == nullptr) {
                return -EINVAL;
                return BAD_VALUE;
            }
            href = attrs[i];
        } else {
            ALOGE("includeXMLFile: unrecognized attribute: %s", attrs[i]);
            return -EINVAL;
            return BAD_VALUE;
        }
        ++i;
    }
@@ -252,32 +252,32 @@ status_t MediaCodecsXmlParser::includeXMLFile(const char **attrs) {
            continue;
        }
        ALOGE("invalid include file name: %s", href);
        return -EINVAL;
        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 -EINVAL;
        return BAD_VALUE;
    }
    filename.insert(0, mHrefBase);

    status_t oldParsingStatus = mParsingStatus;

    parseXMLFile(filename.c_str());
    return mParsingStatus;

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

void MediaCodecsXmlParser::startElementHandler(
        const char *name, const char **attrs) {
    if (mParsingStatus != OK) {
        return;
    }

    bool inType = true;

    if (strEq(name, "Include")) {
        mParsingStatus = includeXMLFile(attrs);
        if (mParsingStatus == OK) {
        if (includeXMLFile(attrs) == OK) {
            mSectionStack.push_back(mCurrentSection);
            mCurrentSection = SECTION_INCLUDE;
        }
@@ -300,7 +300,7 @@ void MediaCodecsXmlParser::startElementHandler(
        case SECTION_SETTINGS:
        {
            if (strEq(name, "Setting")) {
                mParsingStatus = addSettingFromAttributes(attrs);
                (void)addSettingFromAttributes(attrs);
            }
            break;
        }
@@ -308,9 +308,7 @@ void MediaCodecsXmlParser::startElementHandler(
        case SECTION_DECODERS:
        {
            if (strEq(name, "MediaCodec")) {
                mParsingStatus =
                    addMediaCodecFromAttributes(false /* encoder */, attrs);

                (void)addMediaCodecFromAttributes(false /* encoder */, attrs);
                mCurrentSection = SECTION_DECODER;
            }
            break;
@@ -319,9 +317,7 @@ void MediaCodecsXmlParser::startElementHandler(
        case SECTION_ENCODERS:
        {
            if (strEq(name, "MediaCodec")) {
                mParsingStatus =
                    addMediaCodecFromAttributes(true /* encoder */, attrs);

                (void)addMediaCodecFromAttributes(true /* encoder */, attrs);
                mCurrentSection = SECTION_ENCODER;
            }
            break;
@@ -331,9 +327,9 @@ void MediaCodecsXmlParser::startElementHandler(
        case SECTION_ENCODER:
        {
            if (strEq(name, "Quirk")) {
                mParsingStatus = addQuirk(attrs);
                (void)addQuirk(attrs);
            } else if (strEq(name, "Type")) {
                mParsingStatus = addTypeFromAttributes(attrs,
                (void)addTypeFromAttributes(attrs,
                        (mCurrentSection == SECTION_ENCODER));
                mCurrentSection =
                        (mCurrentSection == SECTION_DECODER ?
@@ -353,9 +349,9 @@ void MediaCodecsXmlParser::startElementHandler(
                    (strEq(name, "Limit") || strEq(name, "Feature"))) {
                ALOGW("ignoring %s specified outside of a Type", name);
            } else if (strEq(name, "Limit")) {
                mParsingStatus = addLimit(attrs);
                (void)addLimit(attrs);
            } else if (strEq(name, "Feature")) {
                mParsingStatus = addFeature(attrs);
                (void)addFeature(attrs);
            }
            break;
        }
@@ -367,10 +363,6 @@ void MediaCodecsXmlParser::startElementHandler(
}

void MediaCodecsXmlParser::endElementHandler(const char *name) {
    if (mParsingStatus != OK) {
        return;
    }

    switch (mCurrentSection) {
        case SECTION_SETTINGS:
        {
@@ -452,31 +444,31 @@ status_t MediaCodecsXmlParser::addSettingFromAttributes(const char **attrs) {
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addSettingFromAttributes: name is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            name = attrs[i];
        } else if (strEq(attrs[i], "value")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addSettingFromAttributes: value is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            value = attrs[i];
        } else if (strEq(attrs[i], "update")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addSettingFromAttributes: update is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            update = attrs[i];
        } else {
            ALOGE("addSettingFromAttributes: unrecognized attribute: %s", attrs[i]);
            return -EINVAL;
            return BAD_VALUE;
        }
        ++i;
    }

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

    // Boolean values are converted to "0" or "1".
@@ -489,7 +481,7 @@ status_t MediaCodecsXmlParser::addSettingFromAttributes(const char **attrs) {
    if (attribute == mServiceAttributeMap.end()) { // New attribute name
        if (mUpdate) {
            ALOGE("addSettingFromAttributes: updating non-existing setting");
            return -EINVAL;
            return BAD_VALUE;
        }
        mServiceAttributeMap.insert(Attribute(name, value));
    } else { // Existing attribute name
@@ -513,39 +505,40 @@ status_t MediaCodecsXmlParser::addMediaCodecFromAttributes(
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addMediaCodecFromAttributes: name is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            name = attrs[i];
        } else if (strEq(attrs[i], "type")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addMediaCodecFromAttributes: type is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            type = attrs[i];
        } else if (strEq(attrs[i], "update")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addMediaCodecFromAttributes: update is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            update = attrs[i];
        } else {
            ALOGE("addMediaCodecFromAttributes: unrecognized attribute: %s", attrs[i]);
            return -EINVAL;
            return BAD_VALUE;
        }
        ++i;
    }

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

    mUpdate = (update != nullptr) && parseBoolean(update);
    mCurrentCodec = mCodecMap.find(name);
    if (mCurrentCodec == mCodecMap.end()) { // New codec name
        if (mUpdate) {
            ALOGE("addMediaCodecFromAttributes: updating non-existing codec");
            return -EINVAL;
            ALOGW("addMediaCodecFromAttributes: cannot update "
                  "non-existing codec \"%s\".", name);
            return BAD_VALUE;
        }
        // Create a new codec in mCodecMap
        mCurrentCodec = mCodecMap.insert(
@@ -560,18 +553,26 @@ status_t MediaCodecsXmlParser::addMediaCodecFromAttributes(
        mCurrentCodec->second.order = mCodecCounter++;
    } else { // Existing codec name
        if (!mUpdate) {
            ALOGE("addMediaCodecFromAttributes: adding existing codec");
            return -EINVAL;
            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: updating non-existing type");
                return -EINVAL;
                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;
            }
        }
    }

@@ -579,6 +580,10 @@ status_t MediaCodecsXmlParser::addMediaCodecFromAttributes(
}

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

    const char *name = nullptr;

    size_t i = 0;
@@ -586,19 +591,19 @@ status_t MediaCodecsXmlParser::addQuirk(const char **attrs) {
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addQuirk: name is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            name = attrs[i];
        } else {
            ALOGE("addQuirk: unrecognized attribute: %s", attrs[i]);
            return -EINVAL;
            return BAD_VALUE;
        }
        ++i;
    }

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

    mCurrentCodec->second.quirkSet.emplace(name);
@@ -606,6 +611,10 @@ status_t MediaCodecsXmlParser::addQuirk(const char **attrs) {
}

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

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

@@ -614,42 +623,51 @@ status_t MediaCodecsXmlParser::addTypeFromAttributes(const char **attrs, bool en
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addTypeFromAttributes: name is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            name = attrs[i];
        } else if (strEq(attrs[i], "update")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addTypeFromAttributes: update is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            update = attrs[i];
        } else {
            ALOGE("addTypeFromAttributes: unrecognized attribute: %s", attrs[i]);
            return -EINVAL;
            return BAD_VALUE;
        }
        ++i;
    }

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

    mCurrentCodec->second.isEncoder = encoder;
    mCurrentType = mCurrentCodec->second.typeMap.find(name);
    if (!mUpdate) {
        if (mCurrentType != mCurrentCodec->second.typeMap.end()) {
            ALOGE("addTypeFromAttributes: re-defining existing type without update");
            return -EINVAL;
            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;
@@ -665,78 +683,73 @@ status_t MediaCodecsXmlParser::addLimit(const char **attrs) {
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: name is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            a_name = attrs[i];
        } else if (strEq(attrs[i], "default")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: default is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            a_default = attrs[i];
        } else if (strEq(attrs[i], "in")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: in is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            a_in = attrs[i];
        } else if (strEq(attrs[i], "max")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: max is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            a_max = attrs[i];
        } else if (strEq(attrs[i], "min")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: min is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            a_min = attrs[i];
        } else if (strEq(attrs[i], "range")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: range is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            a_range = attrs[i];
        } else if (strEq(attrs[i], "ranges")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: ranges is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            a_ranges = attrs[i];
        } else if (strEq(attrs[i], "scale")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: scale is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            a_scale = attrs[i];
        } else if (strEq(attrs[i], "value")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addLimit: value is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            a_value = attrs[i];
        } else {
            ALOGE("addLimit: unrecognized limit: %s", attrs[i]);
            return -EINVAL;
            return BAD_VALUE;
        }
        ++i;
    }

    if (a_name == nullptr) {
        ALOGE("limit with no 'name' attribute");
        return -EINVAL;
        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
    if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
        ALOGW("ignoring null type");
        return OK;
    }

    std::string range;
    if (strEq(a_name, "aspect-ratio") ||
            strEq(a_name, "bitrate") ||
@@ -880,6 +893,13 @@ status_t MediaCodecsXmlParser::addLimit(const char **attrs) {
}

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;
@@ -890,30 +910,30 @@ status_t MediaCodecsXmlParser::addFeature(const char **attrs) {
        if (strEq(attrs[i], "name")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addFeature: name is null");
                return -EINVAL;
                return BAD_VALUE;
            }
            name = attrs[i];
        } else if (strEq(attrs[i], "optional")) {
            if (attrs[++i] == nullptr) {
                ALOGE("addFeature: optional is null");
                return -EINVAL;
                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 -EINVAL;
                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 -EINVAL;
                return BAD_VALUE;
            }
            value = attrs[i];
        } else {
            ALOGE("addFeature: unrecognized attribute: %s", attrs[i]);
            return -EINVAL;
            return BAD_VALUE;
        }
        ++i;
    }
@@ -921,23 +941,18 @@ status_t MediaCodecsXmlParser::addFeature(const char **attrs) {
    // Every feature must have a name.
    if (name == nullptr) {
        ALOGE("feature with no 'name' attribute");
        return -EINVAL;
    }

    if (mCurrentType == mCurrentCodec->second.typeMap.end()) {
        ALOGW("ignoring null type");
        return OK;
        return BAD_VALUE;
    }

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