bool MediaConstraintsImpl::initialize(const Dictionary& constraints)
{
    if (constraints.isUndefinedOrNull())
        return true;

    Vector<String> names;
    constraints.getOwnPropertyNames(names);

    String mandatory = ASCIILiteral("mandatory");
    String optional = ASCIILiteral("optional");

    for (Vector<String>::iterator it = names.begin(); it != names.end(); ++it) {
        if (*it != mandatory && *it != optional)
            return false;
    }

    if (names.contains(mandatory)) {
        Dictionary mandatoryConstraints;
        bool ok = constraints.get(mandatory, mandatoryConstraints);
        if (!ok || mandatoryConstraints.isUndefinedOrNull())
            return false;

        ok = mandatoryConstraints.getOwnPropertiesAsStringHashMap(m_mandatoryConstraints);
        if (!ok)
            return false;
    }

    if (names.contains(optional)) {
        ArrayValue optionalConstraints;
        bool ok = constraints.get(optional, optionalConstraints);
        if (!ok || optionalConstraints.isUndefinedOrNull())
            return false;

        size_t numberOfConstraints;
        ok = optionalConstraints.length(numberOfConstraints);
        if (!ok)
            return false;

        for (size_t i = 0; i < numberOfConstraints; ++i) {
            Dictionary constraint;
            ok = optionalConstraints.get(i, constraint);
            if (!ok || constraint.isUndefinedOrNull())
                return false;
            Vector<String> localNames;
            constraint.getOwnPropertyNames(localNames);
            if (localNames.size() != 1)
                return false;
            String key = localNames[0];
            String value;
            ok = constraint.get(key, value);
            if (!ok)
                return false;
            m_optionalConstraints.append(MediaConstraint(key, value));
        }
    }

    return true;
}
void RTCConfiguration::initialize(const Dictionary& configuration, ExceptionCode& ec)
{
    ArrayValue iceServers;
    bool ok = configuration.get("iceServers", iceServers);
    if (!ok || iceServers.isUndefinedOrNull()) {
        ec = TYPE_MISMATCH_ERR;
        return;
    }

    size_t numberOfServers;
    ok = iceServers.length(numberOfServers);
    if (!ok || !numberOfServers) {
        ec = !ok ? TYPE_MISMATCH_ERR : INVALID_ACCESS_ERR;
        return;
    }

    for (size_t i = 0; i < numberOfServers; ++i) {
        Dictionary iceServerDict;
        ok = iceServers.get(i, iceServerDict);
        if (!ok) {
            ec = TYPE_MISMATCH_ERR;
            return;
        }

        RefPtr<RTCIceServer> iceServer = parseIceServer(iceServerDict, ec);
        if (!iceServer)
            return;

        m_iceServers.append(WTFMove(iceServer));
    }

    String iceTransportPolicy;
    if (configuration.get("iceTransportPolicy", iceTransportPolicy)) {
        if (iceTransportPolicy == "relay")
            m_iceTransportPolicy = IceTransportPolicy::Relay;
        else if (iceTransportPolicy == "all")
            m_iceTransportPolicy = IceTransportPolicy::All;
        else {
            ec = TypeError;
            return;
        }
    }

    String bundlePolicy;
    if (configuration.get("bundlePolicy", bundlePolicy)) {
        if (bundlePolicy == "balanced")
            m_bundlePolicy = BundlePolicy::Balanced;
        else if (bundlePolicy == "max-compat")
            m_bundlePolicy = BundlePolicy::MaxCompat;
        else if (bundlePolicy == "max-bundle")
            m_bundlePolicy = BundlePolicy::MaxBundle;
        else
            ec = TypeError;
    }
}
// Old style parser. Deprecated.
static bool parse(const Dictionary& constraintsDictionary, WebVector<WebMediaConstraint>& optional, WebVector<WebMediaConstraint>& mandatory)
{
    if (constraintsDictionary.isUndefinedOrNull())
        return true;

    Vector<String> names;
    bool ok = constraintsDictionary.getPropertyNames(names);
    if (!ok)
        return false;

    String mandatoryName("mandatory");
    String optionalName("optional");

    for (Vector<String>::iterator it = names.begin(); it != names.end(); ++it) {
        if (*it != mandatoryName && *it != optionalName)
            return false;
    }

    if (names.contains(mandatoryName)) {
        Dictionary mandatoryConstraintsDictionary;
        bool ok = constraintsDictionary.get(mandatoryName, mandatoryConstraintsDictionary);
        if (!ok || mandatoryConstraintsDictionary.isUndefinedOrNull())
            return false;
        ok = parseMandatoryConstraintsDictionary(mandatoryConstraintsDictionary, mandatory);
        if (!ok)
            return false;
    }

    Vector<WebMediaConstraint> optionalConstraintsVector;
    if (names.contains(optionalName)) {
        ArrayValue optionalConstraints;
        bool ok = DictionaryHelper::get(constraintsDictionary, optionalName, optionalConstraints);
        if (!ok || optionalConstraints.isUndefinedOrNull())
            return false;

        size_t numberOfConstraints;
        ok = optionalConstraints.length(numberOfConstraints);
        if (!ok)
            return false;

        for (size_t i = 0; i < numberOfConstraints; ++i) {
            Dictionary constraint;
            ok = optionalConstraints.get(i, constraint);
            if (!ok || constraint.isUndefinedOrNull())
                return false;
            ok = parseOptionalConstraintsVectorElement(constraint, optionalConstraintsVector);
            if (!ok)
                return false;
        }
        optional.assign(optionalConstraintsVector);
    }

    return true;
}
Example #4
0
ExceptionOr<void> RTCConfiguration::initialize(const Dictionary& configuration)
{
    ArrayValue iceServers;
    bool ok = configuration.get("iceServers", iceServers);
    if (!ok || iceServers.isUndefinedOrNull())
        return Exception { TYPE_MISMATCH_ERR };

    size_t numberOfServers;
    ok = iceServers.length(numberOfServers);
    if (!ok)
        return Exception { TYPE_MISMATCH_ERR };
    if (!numberOfServers)
        return Exception { INVALID_ACCESS_ERR };

    for (size_t i = 0; i < numberOfServers; ++i) {
        Dictionary iceServerDict;
        ok = iceServers.get(i, iceServerDict);
        if (!ok)
            return Exception { TYPE_MISMATCH_ERR };

        auto server = parseIceServer(iceServerDict);
        if (server.hasException())
            return server.releaseException();

        m_iceServers.append(server.releaseReturnValue());
    }

    String iceTransportPolicy;
    if (configuration.get("iceTransportPolicy", iceTransportPolicy)) {
        if (iceTransportPolicy == "relay")
            m_iceTransportPolicy = IceTransportPolicy::Relay;
        else if (iceTransportPolicy == "all")
            m_iceTransportPolicy = IceTransportPolicy::All;
        else
            return Exception { TypeError };
    }

    String bundlePolicy;
    if (configuration.get("bundlePolicy", bundlePolicy)) {
        if (bundlePolicy == "balanced")
            m_bundlePolicy = BundlePolicy::Balanced;
        else if (bundlePolicy == "max-compat")
            m_bundlePolicy = BundlePolicy::MaxCompat;
        else if (bundlePolicy == "max-bundle")
            m_bundlePolicy = BundlePolicy::MaxBundle;
        else
            return Exception { TypeError };
    }

    return { };
}
Example #5
0
PassRefPtr<RTCConfiguration> RTCPeerConnection::parseConfiguration(const Dictionary& configuration, ExceptionCode& ec)
{
    if (configuration.isUndefinedOrNull())
        return nullptr;

    ArrayValue iceServers;
    bool ok = configuration.get("iceServers", iceServers);
    if (!ok || iceServers.isUndefinedOrNull()) {
        ec = TYPE_MISMATCH_ERR;
        return nullptr;
    }

    size_t numberOfServers;
    ok = iceServers.length(numberOfServers);
    if (!ok) {
        ec = TYPE_MISMATCH_ERR;
        return nullptr;
    }

    RefPtr<RTCConfiguration> rtcConfiguration = RTCConfiguration::create();

    for (size_t i = 0; i < numberOfServers; ++i) {
        Dictionary iceServer;
        ok = iceServers.get(i, iceServer);
        if (!ok) {
            ec = TYPE_MISMATCH_ERR;
            return nullptr;
        }

        String urlString, credential, username;
        ok = iceServer.get("url", urlString);
        if (!ok) {
            ec = TYPE_MISMATCH_ERR;
            return nullptr;
        }
        URL url(URL(), urlString);
        if (!url.isValid() || !(url.protocolIs("turn") || url.protocolIs("stun"))) {
            ec = TYPE_MISMATCH_ERR;
            return nullptr;
        }

        iceServer.get("credential", credential);
        iceServer.get("username", username);

        rtcConfiguration->appendServer(RTCIceServer::create(url, credential, username));
    }

    return rtcConfiguration.release();
}
Example #6
0
PassRefPtr<RTCConfiguration> RTCPeerConnection::parseConfiguration(const Dictionary& configuration, ExceptionCode& ec)
{
    if (configuration.isUndefinedOrNull())
        return nullptr;

    ArrayValue iceServers;
    bool ok = configuration.get("iceServers", iceServers);
    if (!ok || iceServers.isUndefinedOrNull()) {
        ec = TYPE_MISMATCH_ERR;
        return nullptr;
    }

    size_t numberOfServers;
    ok = iceServers.length(numberOfServers);
    if (!ok || !numberOfServers) {
        ec = !ok ? TYPE_MISMATCH_ERR : INVALID_ACCESS_ERR;
        return nullptr;
    }

    String iceTransports;
    String requestIdentity;
    configuration.get("iceTransports", iceTransports);
    configuration.get("requestIdentity", requestIdentity);

    RefPtr<RTCConfiguration> rtcConfiguration = RTCConfiguration::create();

    rtcConfiguration->setIceTransports(iceTransports);
    rtcConfiguration->setRequestIdentity(requestIdentity);

    for (size_t i = 0; i < numberOfServers; ++i) {
        Dictionary iceServer;
        ok = iceServers.get(i, iceServer);
        if (!ok) {
            ec = TYPE_MISMATCH_ERR;
            return nullptr;
        }

        ec = processIceServer(iceServer, rtcConfiguration.get());
        if (ec)
            return nullptr;
    }

    return rtcConfiguration.release();
}
static bool parse(const Dictionary& constraintsDictionary, blink::WebVector<blink::WebMediaConstraint>& optional, blink::WebVector<blink::WebMediaConstraint>& mandatory)
{
    if (constraintsDictionary.isUndefinedOrNull())
        return true;

    Vector<String> names;
    constraintsDictionary.getOwnPropertyNames(names);

    String mandatoryName("mandatory");
    String optionalName("optional");

    for (Vector<String>::iterator it = names.begin(); it != names.end(); ++it) {
        if (*it != mandatoryName && *it != optionalName)
            return false;
    }

    Vector<blink::WebMediaConstraint> mandatoryConstraintsVector;
    if (names.contains(mandatoryName)) {
        Dictionary mandatoryConstraintsDictionary;
        bool ok = constraintsDictionary.get(mandatoryName, mandatoryConstraintsDictionary);
        if (!ok || mandatoryConstraintsDictionary.isUndefinedOrNull())
            return false;

        HashMap<String, String> mandatoryConstraintsHashMap;
        ok = mandatoryConstraintsDictionary.getOwnPropertiesAsStringHashMap(mandatoryConstraintsHashMap);
        if (!ok)
            return false;

        HashMap<String, String>::const_iterator iter = mandatoryConstraintsHashMap.begin();
        for (; iter != mandatoryConstraintsHashMap.end(); ++iter)
            mandatoryConstraintsVector.append(blink::WebMediaConstraint(iter->key, iter->value));
    }

    Vector<blink::WebMediaConstraint> optionalConstraintsVector;
    if (names.contains(optionalName)) {
        ArrayValue optionalConstraints;
        bool ok = constraintsDictionary.get(optionalName, optionalConstraints);
        if (!ok || optionalConstraints.isUndefinedOrNull())
            return false;

        size_t numberOfConstraints;
        ok = optionalConstraints.length(numberOfConstraints);
        if (!ok)
            return false;

        for (size_t i = 0; i < numberOfConstraints; ++i) {
            Dictionary constraint;
            ok = optionalConstraints.get(i, constraint);
            if (!ok || constraint.isUndefinedOrNull())
                return false;
            Vector<String> localNames;
            constraint.getOwnPropertyNames(localNames);
            if (localNames.size() != 1)
                return false;
            String key = localNames[0];
            String value;
            ok = constraint.get(key, value);
            if (!ok)
                return false;
            optionalConstraintsVector.append(blink::WebMediaConstraint(key, value));
        }
    }

    optional.assign(optionalConstraintsVector);
    mandatory.assign(mandatoryConstraintsVector);
    return true;
}
Example #8
0
static Optional<StringConstraint> createStringConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
{
    auto constraint = StringConstraint(name, type);

    // Dictionary constraint value.
    Dictionary dictionaryValue;
    if (mediaTrackConstraintSet.get(name, dictionaryValue) && !dictionaryValue.isUndefinedOrNull()) {
        ArrayValue exactArrayValue;
        if (dictionaryValue.get("exact", exactArrayValue) && !exactArrayValue.isUndefinedOrNull())
            initializeStringConstraintWithList(constraint, &StringConstraint::appendExact, exactArrayValue);
        else {
            String exactStringValue;
            if (dictionaryValue.get("exact", exactStringValue))
                constraint.setExact(exactStringValue);
        }

        ArrayValue idealArrayValue;
        if (dictionaryValue.get("ideal", idealArrayValue) && !idealArrayValue.isUndefinedOrNull())
            initializeStringConstraintWithList(constraint, &StringConstraint::appendIdeal, idealArrayValue);
        else {
            String idealStringValue;
            if (!dictionaryValue.get("ideal", idealStringValue))
                constraint.setIdeal(idealStringValue);
        }

        if (constraint.isEmpty()) {
            LOG(Media, "createStringConstraint() - ignoring string constraint '%s' with dictionary value since it has no valid or supported key/value pairs.", name.utf8().data());
            return Nullopt;
        }
        
        return WTFMove(constraint);
    }

    // Array constraint value.
    ArrayValue arrayValue;
    if (mediaTrackConstraintSet.get(name, arrayValue) && !arrayValue.isUndefinedOrNull()) {
        initializeStringConstraintWithList(constraint, &StringConstraint::appendIdeal, arrayValue);

        if (constraint.isEmpty()) {
            LOG(Media, "createStringConstraint() - ignoring string constraint '%s' with array value since it is empty.", name.utf8().data());
            return Nullopt;
        }

        return WTFMove(constraint);
    }

    // Scalar constraint value.
    String value;
    if (mediaTrackConstraintSet.get(name, value)) {
        if (constraintSetType == ConstraintSetType::Mandatory)
            constraint.setIdeal(value);
        else
            constraint.setExact(value);
        
        return WTFMove(constraint);
    }

    // Invalid constraint value.
    LOG(Media, "createStringConstraint() - ignoring string constraint '%s' since it has neither a dictionary nor sequence nor scalar value.", name.utf8().data());
    return Nullopt;
}
Example #9
0
static void parseAdvancedConstraints(const Dictionary& mediaTrackConstraints, Vector<MediaTrackConstraintSetMap>& advancedConstraints)
{
    ArrayValue sequenceOfMediaTrackConstraintSets;
    if (!mediaTrackConstraints.get("advanced", sequenceOfMediaTrackConstraintSets) || sequenceOfMediaTrackConstraintSets.isUndefinedOrNull()) {
        LOG(Media, "parseAdvancedConstraints() - value of advanced key is not a list.");
        return;
    }

    size_t numberOfConstraintSets;
    if (!sequenceOfMediaTrackConstraintSets.length(numberOfConstraintSets)) {
        LOG(Media, "parseAdvancedConstraints() - ignoring empty advanced sequence of MediaTrackConstraintSets.");
        return;
    }

    for (size_t i = 0; i < numberOfConstraintSets; ++i) {
        Dictionary mediaTrackConstraintSet;
        if (!sequenceOfMediaTrackConstraintSets.get(i, mediaTrackConstraintSet) || mediaTrackConstraintSet.isUndefinedOrNull()) {
            LOG(Media, "parseAdvancedConstraints() - ignoring constraint set with index '%zu' in advanced list.", i);
            continue;
        }

        MediaTrackConstraintSetMap map;

        Vector<String> localKeys;
        mediaTrackConstraintSet.getOwnPropertyNames(localKeys);
        for (auto& localKey : localKeys)
            parseMediaTrackConstraintSetForKey(mediaTrackConstraintSet, localKey, map, ConstraintSetType::Advanced);

        if (!map.isEmpty())
            advancedConstraints.append(WTFMove(map));
    }
}
Example #10
0
PassRefPtr<RTCConfiguration> RTCPeerConnection::parseConfiguration(const Dictionary& configuration, ExceptionState& exceptionState)
{
    if (configuration.isUndefinedOrNull())
        return nullptr;

    ArrayValue iceServers;
    bool ok = configuration.get("iceServers", iceServers);
    if (!ok || iceServers.isUndefinedOrNull()) {
        exceptionState.throwTypeError("Malformed RTCConfiguration");
        return nullptr;
    }

    size_t numberOfServers;
    ok = iceServers.length(numberOfServers);
    if (!ok) {
        exceptionState.throwTypeError("Malformed RTCConfiguration");
        return nullptr;
    }

    RefPtr<RTCConfiguration> rtcConfiguration = RTCConfiguration::create();

    for (size_t i = 0; i < numberOfServers; ++i) {
        Dictionary iceServer;
        ok = iceServers.get(i, iceServer);
        if (!ok) {
            exceptionState.throwTypeError("Malformed RTCIceServer");
            return nullptr;
        }

        Vector<String> names;
        iceServer.getOwnPropertyNames(names);

        Vector<String> urlStrings;
        if (names.contains("urls")) {
            if (!iceServer.get("urls", urlStrings) || !urlStrings.size()) {
                String urlString;
                if (iceServer.get("urls", urlString)) {
                    urlStrings.append(urlString);
                } else {
                    exceptionState.throwTypeError("Malformed RTCIceServer");
                    return nullptr;
                }
            }
        } else if (names.contains("url")) {
            String urlString;
            if (iceServer.get("url", urlString)) {
                urlStrings.append(urlString);
            } else {
                exceptionState.throwTypeError("Malformed RTCIceServer");
                return nullptr;
            }
        } else {
            exceptionState.throwTypeError("Malformed RTCIceServer");
            return nullptr;
        }

        String username, credential;
        iceServer.get("username", username);
        iceServer.get("credential", credential);

        for (Vector<String>::iterator iter = urlStrings.begin(); iter != urlStrings.end(); ++iter) {
            KURL url(KURL(), *iter);
            if (!url.isValid() || !(url.protocolIs("turn") || url.protocolIs("turns") || url.protocolIs("stun"))) {
                exceptionState.throwTypeError("Malformed URL");
                return nullptr;
            }

            rtcConfiguration->appendServer(RTCIceServer::create(url, username, credential));
        }
    }

    return rtcConfiguration.release();
}