15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    in the documentation and/or other materials provided with the
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    distribution.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 3. Neither the name of Google Inc. nor the names of its contributors
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    may be used to endorse or promote products derived from this
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    software without specific prior written permission.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCPeerConnection.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
34197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ArrayValue.h"
35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionMessages.h"
36197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h"
391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/ExecutionContext.h"
40d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/VoidCallback.h"
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/FrameLoader.h"
4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/FrameLoaderClient.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/MediaConstraintsImpl.h"
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/MediaStreamEvent.h"
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCDTMFSender.h"
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCDataChannel.h"
4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCDataChannelEvent.h"
4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCErrorCallback.h"
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCIceCandidateEvent.h"
5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCSessionDescription.h"
5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCSessionDescriptionCallback.h"
5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCSessionDescriptionRequestImpl.h"
5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCStatsCallback.h"
5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCStatsRequestImpl.h"
5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCVoidRequestImpl.h"
5719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)#include "platform/mediastream/RTCConfiguration.h"
58197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "platform/mediastream/RTCOfferOptions.h"
5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/Platform.h"
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/WebMediaStream.h"
6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/WebRTCConfiguration.h"
6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/WebRTCDataChannelHandler.h"
635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebRTCDataChannelInit.h"
645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebRTCICECandidate.h"
65197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "public/platform/WebRTCOfferOptions.h"
665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebRTCSessionDescription.h"
6709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/WebRTCSessionDescriptionRequest.h"
6809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/WebRTCStatsRequest.h"
6909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/WebRTCVoidRequest.h"
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
71c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
73d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)namespace {
74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static bool throwExceptionIfSignalingStateClosed(RTCPeerConnection::SignalingState state, ExceptionState& exceptionState)
76d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
77d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (state == RTCPeerConnection::SignalingStateClosed) {
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(InvalidStateError, "The RTCPeerConnection's signalingState is 'closed'.");
79d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
80d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
81d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
82d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return false;
83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
84d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
85d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} // namespace
86d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRTCConfiguration* RTCPeerConnection::parseConfiguration(const Dictionary& configuration, ExceptionState& exceptionState)
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (configuration.isUndefinedOrNull())
907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
92197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    RTCIceTransports iceTransports = RTCIceTransportsAll;
93197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String iceTransportsString;
94197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (DictionaryHelper::get(configuration, "iceTransports", iceTransportsString)) {
95197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (iceTransportsString == "none") {
96197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            iceTransports = RTCIceTransportsNone;
97197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        } else if (iceTransportsString == "relay") {
98197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            iceTransports = RTCIceTransportsRelay;
99197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        } else if (iceTransportsString != "all") {
100197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            exceptionState.throwTypeError("Malformed RTCIceTransports");
1017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return 0;
102197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
103197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
104197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ArrayValue iceServers;
106197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    bool ok = DictionaryHelper::get(configuration, "iceServers", iceServers);
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!ok || iceServers.isUndefinedOrNull()) {
10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        exceptionState.throwTypeError("Malformed RTCConfiguration");
1097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t numberOfServers;
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ok = iceServers.length(numberOfServers);
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!ok) {
11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        exceptionState.throwTypeError("Malformed RTCConfiguration");
1167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCConfiguration* rtcConfiguration = RTCConfiguration::create();
120197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    rtcConfiguration->setIceTransports(iceTransports);
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < numberOfServers; ++i) {
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Dictionary iceServer;
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ok = iceServers.get(i, iceServer);
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!ok) {
12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            exceptionState.throwTypeError("Malformed RTCIceServer");
1277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return 0;
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        Vector<String> names;
13109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        iceServer.getOwnPropertyNames(names);
13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
13309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        Vector<String> urlStrings;
13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (names.contains("urls")) {
135197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (!DictionaryHelper::get(iceServer, "urls", urlStrings) || !urlStrings.size()) {
13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                String urlString;
137197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                if (DictionaryHelper::get(iceServer, "urls", urlString)) {
13809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    urlStrings.append(urlString);
13909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                } else {
14009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    exceptionState.throwTypeError("Malformed RTCIceServer");
1417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                    return 0;
14209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                }
14309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
14409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        } else if (names.contains("url")) {
14509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            String urlString;
146197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (DictionaryHelper::get(iceServer, "url", urlString)) {
14709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                urlStrings.append(urlString);
14809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            } else {
14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                exceptionState.throwTypeError("Malformed RTCIceServer");
1507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                return 0;
15109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
15209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        } else {
15309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            exceptionState.throwTypeError("Malformed RTCIceServer");
1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return 0;
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        String username, credential;
158197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        DictionaryHelper::get(iceServer, "username", username);
159197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        DictionaryHelper::get(iceServer, "credential", credential);
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (Vector<String>::iterator iter = urlStrings.begin(); iter != urlStrings.end(); ++iter) {
16209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            KURL url(KURL(), *iter);
16309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!url.isValid() || !(url.protocolIs("turn") || url.protocolIs("turns") || url.protocolIs("stun"))) {
16409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                exceptionState.throwTypeError("Malformed URL");
1657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                return 0;
16609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
16709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
16809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            rtcConfiguration->appendServer(RTCIceServer::create(url, username, credential));
16909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return rtcConfiguration;
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRTCOfferOptions* RTCPeerConnection::parseOfferOptions(const Dictionary& options, ExceptionState& exceptionState)
176197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
177197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (options.isUndefinedOrNull())
1787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
179197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
180197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Vector<String> propertyNames;
181197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    options.getOwnPropertyNames(propertyNames);
182197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
183197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Treat |options| as MediaConstraints if it is empty or has "optional" or "mandatory" properties for compatibility.
184197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // TODO(jiayl): remove constraints when RTCOfferOptions reaches Stable and client code is ready.
185197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (propertyNames.isEmpty() || propertyNames.contains("optional") || propertyNames.contains("mandatory"))
1867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
187197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
188c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    int32_t offerToReceiveVideo = -1;
189c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    int32_t offerToReceiveAudio = -1;
190197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    bool voiceActivityDetection = true;
191197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    bool iceRestart = false;
192197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
193c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (DictionaryHelper::get(options, "offerToReceiveVideo", offerToReceiveVideo) && offerToReceiveVideo < 0) {
194c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        exceptionState.throwTypeError("Invalid offerToReceiveVideo");
1957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
196c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
197c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
198c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (DictionaryHelper::get(options, "offerToReceiveAudio", offerToReceiveAudio) && offerToReceiveAudio < 0) {
199c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        exceptionState.throwTypeError("Invalid offerToReceiveAudio");
2007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
201c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
202c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
203197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DictionaryHelper::get(options, "voiceActivityDetection", voiceActivityDetection);
204197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DictionaryHelper::get(options, "iceRestart", iceRestart);
205197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
2067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCOfferOptions* rtcOfferOptions = RTCOfferOptions::create(offerToReceiveVideo, offerToReceiveAudio, voiceActivityDetection, iceRestart);
2077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return rtcOfferOptions;
208197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
209197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
210197021e6b966cfb06891637935ef33fff06433d1Ben MurdochRTCPeerConnection* RTCPeerConnection::create(ExecutionContext* context, const Dictionary& rtcConfiguration, const Dictionary& mediaConstraints, ExceptionState& exceptionState)
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCConfiguration* configuration = parseConfiguration(rtcConfiguration, exceptionState);
21351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
2147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
216e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
21751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
2187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCPeerConnection* peerConnection = adoptRefCountedGarbageCollectedWillBeNoop(new RTCPeerConnection(context, configuration, constraints, exceptionState));
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    peerConnection->suspendIfNeeded();
22251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
2237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return 0;
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
225197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return peerConnection;
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRTCPeerConnection::RTCPeerConnection(ExecutionContext* context, RTCConfiguration* configuration, WebMediaConstraints constraints, ExceptionState& exceptionState)
229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    : ActiveDOMObject(context)
230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_signalingState(SignalingStateStable)
23109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    , m_iceGatheringState(ICEGatheringStateNew)
23209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    , m_iceConnectionState(ICEConnectionStateNew)
233f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    , m_dispatchScheduledEventRunner(this, &RTCPeerConnection::dispatchScheduledEvent)
234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_stopped(false)
2355d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    , m_closed(false)
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    Document* document = toDocument(executionContext());
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2395d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // If we fail, set |m_closed| and |m_stopped| to true, to avoid hitting the assert in the destructor.
2405d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!document->frame()) {
2425d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        m_closed = true;
2435d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        m_stopped = true;
244d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(NotSupportedError, "PeerConnections may not be created in detached documents.");
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
248e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    m_peerHandler = adoptPtr(Platform::current()->createRTCPeerConnectionHandler(this));
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_peerHandler) {
2505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        m_closed = true;
2515d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        m_stopped = true;
252d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(NotSupportedError, "No PeerConnection handler can be created, perhaps WebRTC is disabled?");
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
256f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    document->frame()->loader().client()->dispatchWillStartUsingPeerConnectionHandler(m_peerHandler.get());
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_peerHandler->initialize(configuration, constraints)) {
2595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        m_closed = true;
2605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        m_stopped = true;
261d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(NotSupportedError, "Failed to initialize native PeerConnection.");
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RTCPeerConnection::~RTCPeerConnection()
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // This checks that close() or stop() is called before the destructor.
2695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // We are assuming that a wrapper is always created when RTCPeerConnection is created.
2705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    ASSERT(m_closed || m_stopped);
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RTCPeerConnection::createOffer(RTCSessionDescriptionCallback* successCallback, RTCErrorCallback* errorCallback, const Dictionary& rtcOfferOptions, ExceptionState& exceptionState)
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
275d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
278d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(successCallback);
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCOfferOptions* offerOptions = parseOfferOptions(rtcOfferOptions, exceptionState);
281c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (exceptionState.hadException())
282c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return;
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCSessionDescriptionRequest* request = RTCSessionDescriptionRequestImpl::create(executionContext(), this, successCallback, errorCallback);
285197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
286197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (offerOptions) {
2877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_peerHandler->createOffer(request, offerOptions);
288197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else {
289e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        WebMediaConstraints constraints = MediaConstraintsImpl::create(rtcOfferOptions, exceptionState);
290197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (exceptionState.hadException())
291197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return;
292197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
2937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_peerHandler->createOffer(request, constraints);
294197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RTCPeerConnection::createAnswer(RTCSessionDescriptionCallback* successCallback, RTCErrorCallback* errorCallback, const Dictionary& mediaConstraints, ExceptionState& exceptionState)
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
299d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
302d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(successCallback);
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
304e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
30551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCSessionDescriptionRequest* request = RTCSessionDescriptionRequestImpl::create(executionContext(), this, successCallback, errorCallback);
3097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_peerHandler->createAnswer(request, constraints);
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RTCPeerConnection::setLocalDescription(RTCSessionDescription* sessionDescription, VoidCallback* successCallback, RTCErrorCallback* errorCallback, ExceptionState& exceptionState)
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
314d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!sessionDescription) {
318d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "RTCSessionDescription"));
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), this, successCallback, errorCallback);
3237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_peerHandler->setLocalDescription(request, sessionDescription->webSessionDescription());
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
326197021e6b966cfb06891637935ef33fff06433d1Ben MurdochRTCSessionDescription* RTCPeerConnection::localDescription(ExceptionState& exceptionState)
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
328e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    WebRTCSessionDescription webSessionDescription = m_peerHandler->localDescription();
32993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (webSessionDescription.isNull())
330d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
332d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return RTCSessionDescription::create(webSessionDescription);
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RTCPeerConnection::setRemoteDescription(RTCSessionDescription* sessionDescription, VoidCallback* successCallback, RTCErrorCallback* errorCallback, ExceptionState& exceptionState)
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
337d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!sessionDescription) {
341d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "RTCSessionDescription"));
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), this, successCallback, errorCallback);
3467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_peerHandler->setRemoteDescription(request, sessionDescription->webSessionDescription());
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
349197021e6b966cfb06891637935ef33fff06433d1Ben MurdochRTCSessionDescription* RTCPeerConnection::remoteDescription(ExceptionState& exceptionState)
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
351e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    WebRTCSessionDescription webSessionDescription = m_peerHandler->remoteDescription();
35293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (webSessionDescription.isNull())
353d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
355d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return RTCSessionDescription::create(webSessionDescription);
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, const Dictionary& mediaConstraints, ExceptionState& exceptionState)
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
360d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCConfiguration* configuration = parseConfiguration(rtcConfiguration, exceptionState);
36451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
367e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
36851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool valid = m_peerHandler->updateICE(configuration, constraints);
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!valid)
373d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(SyntaxError, "Could not update the ICE Agent with the given configuration.");
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void RTCPeerConnection::addIceCandidate(RTCIceCandidate* iceCandidate, ExceptionState& exceptionState)
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
378d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!iceCandidate) {
382d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "RTCIceCandidate"));
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
38609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    bool valid = m_peerHandler->addICECandidate(iceCandidate->webCandidate());
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!valid)
388d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(SyntaxError, "The ICE candidate could not be added.");
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RTCPeerConnection::addIceCandidate(RTCIceCandidate* iceCandidate, VoidCallback* successCallback, RTCErrorCallback* errorCallback, ExceptionState& exceptionState)
3928abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){
393d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
3948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        return;
3958abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
396d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!iceCandidate) {
397d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "RTCIceCandidate"));
3988abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        return;
3998abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
400d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(successCallback);
401d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(errorCallback);
4028abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
4037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), this, successCallback, errorCallback);
4048abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
4057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool implemented = m_peerHandler->addICECandidate(request, iceCandidate->webCandidate());
4065d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!implemented) {
407d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(NotSupportedError, "This method is not yet implemented.");
4085d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    }
4098abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
4108abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
411926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)String RTCPeerConnection::signalingState() const
412926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
413926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    switch (m_signalingState) {
414926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case SignalingStateStable:
4153c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "stable";
416926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case SignalingStateHaveLocalOffer:
4173c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "have-local-offer";
418926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case SignalingStateHaveRemoteOffer:
4193c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "have-remote-offer";
420926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case SignalingStateHaveLocalPrAnswer:
4213c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "have-local-pranswer";
422926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case SignalingStateHaveRemotePrAnswer:
4233c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "have-remote-pranswer";
424926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case SignalingStateClosed:
4253c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "closed";
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
429926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return String();
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
432926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)String RTCPeerConnection::iceGatheringState() const
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
434926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    switch (m_iceGatheringState) {
43509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case ICEGatheringStateNew:
4363c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "new";
43709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case ICEGatheringStateGathering:
4383c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "gathering";
43909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case ICEGatheringStateComplete:
4403c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "complete";
441926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
442926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
443926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT_NOT_REACHED();
444926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return String();
445926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
446926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
447926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)String RTCPeerConnection::iceConnectionState() const
448926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
449926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    switch (m_iceConnectionState) {
45009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case ICEConnectionStateNew:
4513c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "new";
45209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case ICEConnectionStateChecking:
4533c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "checking";
45409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case ICEConnectionStateConnected:
4553c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "connected";
45609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case ICEConnectionStateCompleted:
4573c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "completed";
45809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case ICEConnectionStateFailed:
4593c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "failed";
46009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case ICEConnectionStateDisconnected:
4613c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "disconnected";
46209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case ICEConnectionStateClosed:
4633c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "closed";
4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
467926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return String();
4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
470197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RTCPeerConnection::addStream(MediaStream* stream, const Dictionary& mediaConstraints, ExceptionState& exceptionState)
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
472d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!stream) {
476d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "MediaStream"));
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
480926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_localStreams.contains(stream))
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
483e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
48451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
487926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_localStreams.append(stream);
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool valid = m_peerHandler->addStream(stream->descriptor(), constraints);
4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!valid)
491d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(SyntaxError, "Unable to add the provided stream.");
4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
494197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RTCPeerConnection::removeStream(MediaStream* stream, ExceptionState& exceptionState)
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
496d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
499197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!stream) {
500d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "MediaStream"));
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
504926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    size_t pos = m_localStreams.find(stream);
50506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (pos == kNotFound)
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
508926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_localStreams.remove(pos);
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_peerHandler->removeStream(stream->descriptor());
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
513926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)MediaStreamVector RTCPeerConnection::getLocalStreams() const
5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
515926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return m_localStreams;
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
518926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)MediaStreamVector RTCPeerConnection::getRemoteStreams() const
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
520926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return m_remoteStreams;
521926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
522926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
523926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)MediaStream* RTCPeerConnection::getStreamById(const String& streamId)
524926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
525926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (MediaStreamVector::iterator iter = m_localStreams.begin(); iter != m_localStreams.end(); ++iter) {
526926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if ((*iter)->id() == streamId)
527926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return iter->get();
528926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
529926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
530926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (MediaStreamVector::iterator iter = m_remoteStreams.begin(); iter != m_remoteStreams.end(); ++iter) {
531926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if ((*iter)->id() == streamId)
532926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return iter->get();
533926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
534926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
535926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return 0;
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RTCPeerConnection::getStats(RTCStatsCallback* successCallback, MediaStreamTrack* selector)
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RTCStatsRequest* statsRequest = RTCStatsRequestImpl::create(executionContext(), this, successCallback, selector);
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Add passing selector as part of the statsRequest.
5427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_peerHandler->getStats(statsRequest);
5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
545197021e6b966cfb06891637935ef33fff06433d1Ben MurdochRTCDataChannel* RTCPeerConnection::createDataChannel(String label, const Dictionary& options, ExceptionState& exceptionState)
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
547d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
548d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
550e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    WebRTCDataChannelInit init;
551197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DictionaryHelper::get(options, "ordered", init.ordered);
552197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DictionaryHelper::get(options, "negotiated", init.negotiated);
5535267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
5545267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    unsigned short value = 0;
555197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (DictionaryHelper::get(options, "id", value))
5565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        init.id = value;
557197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (DictionaryHelper::get(options, "maxRetransmits", value))
5585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        init.maxRetransmits = value;
559197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (DictionaryHelper::get(options, "maxRetransmitTime", value))
5605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        init.maxRetransmitTime = value;
5615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
5625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    String protocolString;
563197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DictionaryHelper::get(options, "protocol", protocolString);
5645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    init.protocol = protocolString;
5655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
566197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    RTCDataChannel* channel = RTCDataChannel::create(executionContext(), this, m_peerHandler.get(), label, init, exceptionState);
56751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
568d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_dataChannels.append(channel);
570197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return channel;
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
573926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool RTCPeerConnection::hasLocalStreamWithTrackId(const String& trackId)
574926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
575926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (MediaStreamVector::iterator iter = m_localStreams.begin(); iter != m_localStreams.end(); ++iter) {
576926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if ((*iter)->getTrackById(trackId))
577926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return true;
578926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
579926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return false;
580926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
581926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
582197021e6b966cfb06891637935ef33fff06433d1Ben MurdochRTCDTMFSender* RTCPeerConnection::createDTMFSender(MediaStreamTrack* track, ExceptionState& exceptionState)
583926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
584d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
585d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
586926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
587197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!track) {
588d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(1, "MediaStreamTrack"));
589d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
590926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
591926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
592926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!hasLocalStreamWithTrackId(track->id())) {
593d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        exceptionState.throwDOMException(SyntaxError, "No local stream is available for the track provided.");
594d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
595926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
596926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
597197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    RTCDTMFSender* dtmfSender = RTCDTMFSender::create(executionContext(), m_peerHandler.get(), track, exceptionState);
59851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
599d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
600197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return dtmfSender;
601926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
602926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
60351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void RTCPeerConnection::close(ExceptionState& exceptionState)
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
605d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6089e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    closeInternal();
6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RTCPeerConnection::negotiationNeeded()
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6135d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    ASSERT(!m_closed);
6141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleDispatchEvent(Event::create(EventTypeNames::negotiationneeded));
6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
617e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RTCPeerConnection::didGenerateICECandidate(const WebRTCICECandidate& webCandidate)
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6195d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    ASSERT(!m_closed);
6201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(executionContext()->isContextThread());
62193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (webCandidate.isNull())
622d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, nullptr));
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
624197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        RTCIceCandidate* iceCandidate = RTCIceCandidate::create(webCandidate);
625197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, iceCandidate));
6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
629926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RTCPeerConnection::didChangeSignalingState(SignalingState newState)
630926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
6315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    ASSERT(!m_closed);
6321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(executionContext()->isContextThread());
633926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    changeSignalingState(newState);
634926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
635926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
63609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void RTCPeerConnection::didChangeICEGatheringState(ICEGatheringState newState)
6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6385d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    ASSERT(!m_closed);
6391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(executionContext()->isContextThread());
640926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    changeIceGatheringState(newState);
6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
64309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void RTCPeerConnection::didChangeICEConnectionState(ICEConnectionState newState)
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6455d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    ASSERT(!m_closed);
6461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(executionContext()->isContextThread());
647926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    changeIceConnectionState(newState);
6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
650e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RTCPeerConnection::didAddRemoteStream(const WebMediaStream& remoteStream)
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6525d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    ASSERT(!m_closed);
6531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(executionContext()->isContextThread());
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_signalingState == SignalingStateClosed)
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
658197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    MediaStream* stream = MediaStream::create(executionContext(), remoteStream);
659926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_remoteStreams.append(stream);
6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
661197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    scheduleDispatchEvent(MediaStreamEvent::create(EventTypeNames::addstream, false, false, stream));
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
664e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RTCPeerConnection::didRemoveRemoteStream(const WebMediaStream& remoteStream)
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    ASSERT(!m_closed);
6671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(executionContext()->isContextThread());
66809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
66909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    MediaStreamDescriptor* streamDescriptor = remoteStream;
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(streamDescriptor->client());
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
672197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    MediaStream* stream = static_cast<MediaStream*>(streamDescriptor->client());
6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    stream->streamEnded();
6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
675926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_signalingState == SignalingStateClosed)
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
678926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    size_t pos = m_remoteStreams.find(stream);
67906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(pos != kNotFound);
680926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_remoteStreams.remove(pos);
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
682197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    scheduleDispatchEvent(MediaStreamEvent::create(EventTypeNames::removestream, false, false, stream));
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
685e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RTCPeerConnection::didAddRemoteDataChannel(WebRTCDataChannelHandler* handler)
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6875d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    ASSERT(!m_closed);
6881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(executionContext()->isContextThread());
6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
690926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_signalingState == SignalingStateClosed)
6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
693197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    RTCDataChannel* channel = RTCDataChannel::create(executionContext(), this, adoptPtr(handler));
6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_dataChannels.append(channel);
6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
696197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    scheduleDispatchEvent(RTCDataChannelEvent::create(EventTypeNames::datachannel, false, false, channel));
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
699d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void RTCPeerConnection::releasePeerConnectionHandler()
700d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
701d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    stop();
702d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
703d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
7049e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)void RTCPeerConnection::closePeerConnection()
7059e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles){
7069e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    ASSERT(m_signalingState != RTCPeerConnection::SignalingStateClosed);
7079e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    closeInternal();
7089e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)}
7099e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const AtomicString& RTCPeerConnection::interfaceName() const
7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return EventTargetNames::RTCPeerConnection;
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)ExecutionContext* RTCPeerConnection::executionContext() const
7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return ActiveDOMObject::executionContext();
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
720f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RTCPeerConnection::suspend()
721f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
722f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_dispatchScheduledEventRunner.suspend();
723f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
724f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
725f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RTCPeerConnection::resume()
726f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
727f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_dispatchScheduledEventRunner.resume();
728f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
729f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RTCPeerConnection::stop()
7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
732926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_stopped)
733926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
734926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
735926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_stopped = true;
73609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_iceConnectionState = ICEConnectionStateClosed;
737926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_signalingState = SignalingStateClosed;
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
739197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HeapVector<Member<RTCDataChannel> >::iterator i = m_dataChannels.begin();
7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (; i != m_dataChannels.end(); ++i)
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        (*i)->stop();
742d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    m_dataChannels.clear();
743f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
744f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_dispatchScheduledEventRunner.stop();
745d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
746d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    m_peerHandler.clear();
7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
749926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RTCPeerConnection::changeSignalingState(SignalingState signalingState)
7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
751926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_signalingState != SignalingStateClosed && m_signalingState != signalingState) {
752926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_signalingState = signalingState;
7531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        scheduleDispatchEvent(Event::create(EventTypeNames::signalingstatechange));
7545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
75709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void RTCPeerConnection::changeIceGatheringState(ICEGatheringState iceGatheringState)
7585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
759926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_iceGatheringState = iceGatheringState;
760926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
76209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void RTCPeerConnection::changeIceConnectionState(ICEConnectionState iceConnectionState)
763926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
76409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (m_iceConnectionState != ICEConnectionStateClosed && m_iceConnectionState != iceConnectionState) {
765926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_iceConnectionState = iceConnectionState;
7661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        scheduleDispatchEvent(Event::create(EventTypeNames::iceconnectionstatechange));
767926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7709e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)void RTCPeerConnection::closeInternal()
7719e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles){
7729e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    ASSERT(m_signalingState != RTCPeerConnection::SignalingStateClosed);
7739e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    m_peerHandler->stop();
7749e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    m_closed = true;
7759e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
7769e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    changeIceConnectionState(ICEConnectionStateClosed);
7779e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    changeIceGatheringState(ICEGatheringStateComplete);
7789e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    changeSignalingState(SignalingStateClosed);
7799e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)}
7809e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
781a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochvoid RTCPeerConnection::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
7825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_scheduledEvents.append(event);
7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
785f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_dispatchScheduledEventRunner.runAsync();
7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
788f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RTCPeerConnection::dispatchScheduledEvent()
7895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
790926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_stopped)
791926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
792926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
793a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WillBeHeapVector<RefPtrWillBeMember<Event> > events;
7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    events.swap(m_scheduledEvents);
7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
796a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WillBeHeapVector<RefPtrWillBeMember<Event> >::iterator it = events.begin();
7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (; it != events.end(); ++it)
7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        dispatchEvent((*it).release());
7995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    events.clear();
8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
803d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void RTCPeerConnection::trace(Visitor* visitor)
804d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
805d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_localStreams);
806d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_remoteStreams);
807d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_dataChannels);
808197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(OILPAN)
809d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_scheduledEvents);
810197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif
811d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    EventTargetWithInlineData::trace(visitor);
812d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
813d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
814c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
815