/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name of Google Inc. nor the names of its contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "modules/mediastream/MediaConstraintsImpl.h"

#include "bindings/core/v8/ArrayValue.h"
#include "bindings/core/v8/Dictionary.h"
#include "bindings/core/v8/ExceptionState.h"
#include "core/dom/ExceptionCode.h"
#include "modules/mediastream/MediaTrackConstraintSet.h"
#include "platform/Logging.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/HashMap.h"
#include "wtf/Vector.h"
#include "wtf/text/StringHash.h"

namespace blink {

namespace MediaConstraintsImpl {

// Legal constraint names.
// Temporary Note: Comments about source are where they are copied from.
// Once the chrome parts use the new-style constraint values, they will
// be deleted from the files mentioned.
// TODO(hta): remove comments before https://crbug.com/543997 is closed.

// From content/renderer/media/media_stream_video_source.cc
const char kMinAspectRatio[] = "minAspectRatio";
const char kMaxAspectRatio[] = "maxAspectRatio";
const char kMaxWidth[] = "maxWidth";
const char kMinWidth[] = "minWidth";
const char kMaxHeight[] = "maxHeight";
const char kMinHeight[] = "minHeight";
const char kMaxFrameRate[] = "maxFrameRate";
const char kMinFrameRate[] = "minFrameRate";
// From content/common/media/media_stream_options.cc
const char kMediaStreamSource[] = "chromeMediaSource";
const char kMediaStreamSourceId[] = "chromeMediaSourceId"; // mapped to deviceId
const char kMediaStreamSourceInfoId[] = "sourceId"; // mapped to deviceId
const char kMediaStreamRenderToAssociatedSink[] = "chromeRenderToAssociatedSink";
// RenderToAssociatedSink will be going away in M50-M60 some time.
const char kMediaStreamAudioHotword[] = "googHotword";
// TODO(hta): googHotword should go away. https://crbug.com/577627
// From content/renderer/media/media_stream_audio_processor_options.cc
const char kEchoCancellation[] = "echoCancellation";
const char kGoogEchoCancellation[] = "googEchoCancellation";
const char kGoogExperimentalEchoCancellation[] = "googEchoCancellation2";
const char kGoogAutoGainControl[] = "googAutoGainControl";
const char kGoogExperimentalAutoGainControl[] = "googAutoGainControl2";
const char kGoogNoiseSuppression[] = "googNoiseSuppression";
const char kGoogExperimentalNoiseSuppression[] = "googNoiseSuppression2";
const char kGoogBeamforming[] = "googBeamforming";
const char kGoogArrayGeometry[] = "googArrayGeometry";
const char kGoogHighpassFilter[] = "googHighpassFilter";
const char kGoogTypingNoiseDetection[] = "googTypingNoiseDetection";
const char kGoogAudioMirroring[] = "googAudioMirroring";

// From third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface.cc
// Audio constraints.
// const char kExtendedFilterEchoCancellation[] = "googEchoCancellation2"; // duplicate k-name
const char kDAEchoCancellation[] = "googDAEchoCancellation";
// const char kNoiseSuppression[] = "googNoiseSuppression"; // duplicate k-name
// const char kExperimentalNoiseSuppression[] = "googNoiseSuppression2"; // duplicate k-name
// const char kHighpassFilter[] = "googHighpassFilter"; // duplicate k-name
// const char kTypingNoiseDetection[] = "googTypingNoiseDetection"; // duplicate k-name
// const char kAudioMirroring[] = "googAudioMirroring"; // duplicate k-name
const char kAecDump[] = "audioDebugRecording";

// Google-specific constraint keys for a local video source (getUserMedia).
const char kNoiseReduction[] = "googNoiseReduction";

// Constraint keys for CreateOffer / CreateAnswer defined in W3C specification.
const char kOfferToReceiveAudio[] = "OfferToReceiveAudio";
const char kOfferToReceiveVideo[] = "OfferToReceiveVideo";
const char kVoiceActivityDetection[] = "VoiceActivityDetection";
const char kIceRestart[] = "IceRestart";
// Google specific constraint for BUNDLE enable/disable.
const char kUseRtpMux[] = "googUseRtpMUX";
// Below constraints should be used during PeerConnection construction.
const char kEnableDtlsSrtp[] = "DtlsSrtpKeyAgreement";
const char kEnableRtpDataChannels[] = "RtpDataChannels";
// Google-specific constraint keys.
const char kEnableDscp[] = "googDscp";
const char kEnableIPv6[] = "googIPv6";
const char kEnableVideoSuspendBelowMinBitrate[] = "googSuspendBelowMinBitrate";
const char kNumUnsignalledRecvStreams[] = "googNumUnsignalledRecvStreams";
const char kCombinedAudioVideoBwe[] = "googCombinedAudioVideoBwe";
const char kScreencastMinBitrate[] = "googScreencastMinBitrate";
const char kCpuOveruseDetection[] = "googCpuOveruseDetection";
const char kCpuUnderuseThreshold[] = "googCpuUnderuseThreshold";
const char kCpuOveruseThreshold[] = "googCpuOveruseThreshold";
const char kCpuUnderuseEncodeRsdThreshold[] = "googCpuUnderuseEncodeRsdThreshold";
const char kCpuOveruseEncodeRsdThreshold[] = "googCpuOveruseEncodeRsdThreshold";
const char kCpuOveruseEncodeUsage[] = "googCpuOveruseEncodeUsage";
const char kHighStartBitrate[] = "googHighStartBitrate";
const char kPayloadPadding[] = "googPayloadPadding";
// End of names from libjingle

// Names used for testing.
const char kTestConstraint1[] = "valid_and_supported_1";
const char kTestConstraint2[] = "valid_and_supported_2";

static bool parseMandatoryConstraintsDictionary(const Dictionary& mandatoryConstraintsDictionary, WebVector<WebMediaConstraint>& mandatory)
{
    Vector<WebMediaConstraint> mandatoryConstraintsVector;
    HashMap<String, String> mandatoryConstraintsHashMap;
    bool ok = mandatoryConstraintsDictionary.getOwnPropertiesAsStringHashMap(mandatoryConstraintsHashMap);
    if (!ok)
        return false;

    for (const auto& iter : mandatoryConstraintsHashMap)
        mandatoryConstraintsVector.append(WebMediaConstraint(iter.key, iter.value));
    mandatory.assign(mandatoryConstraintsVector);
    return true;
}

static bool parseOptionalConstraintsVectorElement(const Dictionary& constraint, Vector<WebMediaConstraint>& optionalConstraintsVector)
{
    Vector<String> localNames;
    bool ok = constraint.getPropertyNames(localNames);
    if (!ok)
        return false;
    if (localNames.size() != 1)
        return false;
    const String& key = localNames[0];
    String value;
    ok = DictionaryHelper::get(constraint, key, value);
    if (!ok)
        return false;
    optionalConstraintsVector.append(WebMediaConstraint(key, value));
    return true;
}

// 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;
}

static bool parse(const MediaTrackConstraintSet& constraintsIn, WebVector<WebMediaConstraint>& optional, WebVector<WebMediaConstraint>& mandatory)
{
    Vector<WebMediaConstraint> mandatoryConstraintsVector;
    if (constraintsIn.hasMandatory()) {
        bool ok = parseMandatoryConstraintsDictionary(constraintsIn.mandatory(), mandatory);
        if (!ok)
            return false;
    }

    Vector<WebMediaConstraint> optionalConstraintsVector;
    if (constraintsIn.hasOptional()) {
        const Vector<Dictionary>& optionalConstraints = constraintsIn.optional();

        for (const auto& constraint : optionalConstraints) {
            if (constraint.isUndefinedOrNull())
                return false;
            bool ok = parseOptionalConstraintsVectorElement(constraint, optionalConstraintsVector);
            if (!ok)
                return false;
        }
        optional.assign(optionalConstraintsVector);
    }
    return true;
}

static bool toBoolean(const WebString& asWebString)
{
    return asWebString.equals("true");
    // TODO(hta): Check against "false" and return error if it's neither.
    // https://crbug.com/576582
}

static void parseOldStyleNames(const WebVector<WebMediaConstraint>& oldNames, WebMediaTrackConstraintSet& result, MediaErrorState& errorState)
{
    for (const WebMediaConstraint& constraint : oldNames) {
        if (constraint.m_name.equals(kMinAspectRatio)) {
            result.aspectRatio.setMin(atof(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kMaxAspectRatio)) {
            result.aspectRatio.setMax(atof(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kMaxWidth)) {
            result.width.setMax(atoi(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kMinWidth)) {
            result.width.setMin(atoi(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kMaxHeight)) {
            result.height.setMax(atoi(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kMinHeight)) {
            result.height.setMin(atoi(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kMinFrameRate)) {
            result.frameRate.setMin(atof(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kMaxFrameRate)) {
            result.frameRate.setMax(atof(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kEchoCancellation)) {
            result.echoCancellation.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kMediaStreamSource)) {
            // TODO(hta): This has only a few legal values. Should be
            // represented as an enum, and cause type errors.
            // https://crbug.com/576582
            result.mediaStreamSource.setExact(constraint.m_value);
        } else if (constraint.m_name.equals(kMediaStreamSourceId)
            || constraint.m_name.equals(kMediaStreamSourceInfoId)) {
            result.deviceId.setExact(constraint.m_value);
        } else if (constraint.m_name.equals(kMediaStreamRenderToAssociatedSink)) {
            // TODO(hta): This is a boolean represented as string.
            // Should give TypeError when it's not parseable.
            // https://crbug.com/576582
            result.renderToAssociatedSink.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kMediaStreamAudioHotword)) {
            result.hotwordEnabled.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kGoogEchoCancellation)) {
            result.googEchoCancellation.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kGoogExperimentalEchoCancellation)) {
            result.googExperimentalEchoCancellation.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kGoogAutoGainControl)) {
            result.googAutoGainControl.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kGoogExperimentalAutoGainControl)) {
            result.googExperimentalAutoGainControl.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kGoogNoiseSuppression)) {
            result.googNoiseSuppression.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kGoogExperimentalNoiseSuppression)) {
            result.googExperimentalNoiseSuppression.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kGoogBeamforming)) {
            result.googBeamforming.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kGoogArrayGeometry)) {
            result.googArrayGeometry.setExact(constraint.m_value);
        } else if (constraint.m_name.equals(kGoogHighpassFilter)) {
            result.googHighpassFilter.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kGoogTypingNoiseDetection)) {
            result.googTypingNoiseDetection.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kGoogAudioMirroring)) {
            result.googAudioMirroring.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kDAEchoCancellation)) {
            result.googDAEchoCancellation.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kAecDump)) {
            result.googAecDump.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kNoiseReduction)) {
            result.googNoiseReduction.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kOfferToReceiveAudio)) {
            result.offerToReceiveAudio.setExact(constraint.m_value);
        } else if (constraint.m_name.equals(kOfferToReceiveVideo)) {
            result.offerToReceiveVideo.setExact(constraint.m_value);
        } else if (constraint.m_name.equals(kVoiceActivityDetection)) {
            result.voiceActivityDetection.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kIceRestart)) {
            result.iceRestart.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kUseRtpMux)) {
            result.googUseRtpMux.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kEnableDtlsSrtp)) {
            result.enableDtlsSrtp.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kEnableRtpDataChannels)) {
            result.enableRtpDataChannels.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kEnableDscp)) {
            result.enableDscp.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kEnableIPv6)) {
            result.enableIPv6.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kEnableVideoSuspendBelowMinBitrate)) {
            result.googEnableVideoSuspendBelowMinBitrate.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kNumUnsignalledRecvStreams)) {
            result.googNumUnsignalledRecvStreams.setExact(atoi(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kCombinedAudioVideoBwe)) {
            result.googCombinedAudioVideoBwe.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kScreencastMinBitrate)) {
            result.googScreencastMinBitrate.setExact(atoi(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kCpuOveruseDetection)) {
            result.googCpuOveruseDetection.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kCpuUnderuseThreshold)) {
            result.googCpuUnderuseThreshold.setExact(atoi(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kCpuOveruseThreshold)) {
            result.googCpuOveruseThreshold.setExact(atoi(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kCpuUnderuseEncodeRsdThreshold)) {
            result.googCpuUnderuseEncodeRsdThreshold.setExact(atoi(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kCpuOveruseEncodeRsdThreshold)) {
            result.googCpuOveruseEncodeRsdThreshold.setExact(atoi(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kCpuOveruseEncodeUsage)) {
            result.googCpuOveruseEncodeUsage.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kHighStartBitrate)) {
            result.googHighStartBitrate.setExact(atoi(constraint.m_value.utf8().c_str()));
        } else if (constraint.m_name.equals(kPayloadPadding)) {
            result.googPayloadPadding.setExact(toBoolean(constraint.m_value));
        } else if (constraint.m_name.equals(kTestConstraint1)
            || constraint.m_name.equals(kTestConstraint2)) {
            // These constraints are only for testing parsing. Ignore them.
        } else {
            // TODO(hta): UMA stats for unknown constraints passed.
            // https://crbug.com/576613
            WTF_LOG(Media, "Unknown constraint name detected");
            errorState.throwConstraintError("Unknown name of constraint detected", constraint.m_name);
        }
    }
}

static WebMediaConstraints createFromNamedConstraints(WebVector<WebMediaConstraint>& mandatory, const WebVector<WebMediaConstraint>& optional, MediaErrorState& errorState)
{
    WebMediaTrackConstraintSet basic;
    WebMediaTrackConstraintSet advanced;
    WebMediaConstraints constraints;
    parseOldStyleNames(mandatory, basic, errorState);
    if (errorState.hadException())
        return constraints;
    // We ignore errors in optional constraints.
    MediaErrorState ignoredErrorState;
    parseOldStyleNames(optional, advanced, ignoredErrorState);
    WebVector<WebMediaTrackConstraintSet> advancedVector(&advanced, 1);
    // Use the 4-argument initializer until Chrome has been converted.
    constraints.initialize(optional, mandatory, basic, advancedVector);
    return constraints;
}

// Deprecated.
WebMediaConstraints create(const Dictionary& constraintsDictionary, MediaErrorState& errorState)
{
    WebVector<WebMediaConstraint> optional;
    WebVector<WebMediaConstraint> mandatory;
    if (!parse(constraintsDictionary, optional, mandatory)) {
        errorState.throwTypeError("Malformed constraints object.");
        return WebMediaConstraints();
    }
    return createFromNamedConstraints(mandatory, optional, errorState);
}

void copyLongConstraint(ConstrainLongRange blinkForm, LongConstraint& webForm)
{
    if (blinkForm.hasMin()) {
        webForm.setMin(blinkForm.min());
    }
    if (blinkForm.hasMax()) {
        webForm.setMax(blinkForm.max());
    }
    if (blinkForm.hasIdeal()) {
        webForm.setIdeal(blinkForm.ideal());
    }
    if (blinkForm.hasExact()) {
        webForm.setExact(blinkForm.exact());
    }
}

void copyDoubleConstraint(ConstrainDoubleRange blinkForm, DoubleConstraint& webForm)
{
    if (blinkForm.hasMin()) {
        webForm.setMin(blinkForm.min());
    }
    if (blinkForm.hasMax()) {
        webForm.setMax(blinkForm.max());
    }
    if (blinkForm.hasIdeal()) {
        webForm.setIdeal(blinkForm.ideal());
    }
    if (blinkForm.hasExact()) {
        webForm.setExact(blinkForm.exact());
    }
}

void copyStringConstraint(ConstrainDOMStringParameters blinkForm, StringConstraint& webForm)
{
    WebVector<WebString> ideal;
    WebVector<WebString> exact;
    if (blinkForm.hasIdeal()) {
        ideal = WebVector<WebString>(blinkForm.ideal());
    }
    if (blinkForm.hasExact()) {
        exact = WebVector<WebString>(blinkForm.exact());
    }
    webForm = StringConstraint(ideal, exact);
}

void copyBooleanConstraint(ConstrainBooleanParameters blinkForm, BooleanConstraint& webForm)
{
    if (blinkForm.hasIdeal()) {
        webForm.setIdeal(blinkForm.ideal());
    }
    if (blinkForm.hasExact()) {
        webForm.setExact(blinkForm.exact());
    }
}

void copyConstraints(const MediaTrackConstraintSet& constraintsIn, WebMediaTrackConstraintSet& constraintBuffer)
{
    if (constraintsIn.hasWidth()) {
        copyLongConstraint(constraintsIn.width(), constraintBuffer.width);
    }
    if (constraintsIn.hasHeight()) {
        copyLongConstraint(constraintsIn.height(), constraintBuffer.height);
    }
    if (constraintsIn.hasAspectRatio()) {
        copyDoubleConstraint(constraintsIn.aspectRatio(), constraintBuffer.aspectRatio);
    }
    if (constraintsIn.hasFrameRate()) {
        copyDoubleConstraint(constraintsIn.frameRate(), constraintBuffer.frameRate);
    }
    if (constraintsIn.hasFacingMode()) {
        copyStringConstraint(constraintsIn.facingMode(), constraintBuffer.facingMode);
    }
    if (constraintsIn.hasVolume()) {
        copyDoubleConstraint(constraintsIn.volume(), constraintBuffer.volume);
    }
    if (constraintsIn.hasSampleRate()) {
        copyLongConstraint(constraintsIn.sampleRate(), constraintBuffer.sampleRate);
    }
    if (constraintsIn.hasSampleSize()) {
        copyLongConstraint(constraintsIn.sampleSize(), constraintBuffer.sampleSize);
    }
    if (constraintsIn.hasEchoCancellation()) {
        copyBooleanConstraint(constraintsIn.echoCancellation(), constraintBuffer.echoCancellation);
    }
    if (constraintsIn.hasLatency()) {
        copyDoubleConstraint(constraintsIn.latency(), constraintBuffer.latency);
    }
    if (constraintsIn.hasChannelCount()) {
        copyLongConstraint(constraintsIn.channelCount(), constraintBuffer.channelCount);
    }
    if (constraintsIn.hasDeviceId()) {
        copyStringConstraint(constraintsIn.deviceId(), constraintBuffer.deviceId);
    }
    if (constraintsIn.hasGroupId()) {
        copyStringConstraint(constraintsIn.groupId(), constraintBuffer.groupId);
    }
}

WebMediaConstraints create(const MediaTrackConstraintSet& constraintsIn, MediaErrorState& errorState)
{
    WebMediaConstraints constraints;
    WebMediaTrackConstraintSet constraintBuffer;
    WebVector<WebMediaTrackConstraintSet> advancedBuffer;
    copyConstraints(constraintsIn, constraintBuffer);
    // TODO(hta): Add initialization of advanced constraints once present.
    // https://crbug.com/253412
    if (constraintsIn.hasOptional() || constraintsIn.hasMandatory()) {
        if (!constraintBuffer.isEmpty()) {
            errorState.throwTypeError("Malformed constraint: Cannot use both optional/mandatory and specific constraints.");
            return WebMediaConstraints();
        }
        WebVector<WebMediaConstraint> optional;
        WebVector<WebMediaConstraint> mandatory;
        if (!parse(constraintsIn, optional, mandatory)) {
            errorState.throwTypeError("Malformed constraints object.");
            return WebMediaConstraints();
        }
        return createFromNamedConstraints(mandatory, optional, errorState);
    }
    constraints.initialize(constraintBuffer, advancedBuffer);
    return constraints;
}

WebMediaConstraints create()
{
    WebMediaConstraints constraints;
    constraints.initialize();
    return constraints;
}

} // namespace MediaConstraintsImpl
} // namespace blink
