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) * 1.  Redistributions of source code must retain the above copyright
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     documentation and/or other materials provided with the distribution.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/RTCDataChannel.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
28197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h"
301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/ExecutionContext.h"
3106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/MessageEvent.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/Blob.h"
33197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "modules/mediastream/RTCPeerConnection.h"
3409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/WebRTCPeerConnectionHandler.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/ArrayBuffer.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/ArrayBufferView.h"
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static void throwNotOpenException(ExceptionState& exceptionState)
41f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    exceptionState.throwDOMException(InvalidStateError, "RTCDataChannel.readyState is not 'open'");
43f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
44f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
4551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static void throwCouldNotSendDataException(ExceptionState& exceptionState)
46f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
4751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    exceptionState.throwDOMException(NetworkError, "Could not send data");
48f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
49f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
5051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static void throwNoBlobSupportException(ExceptionState& exceptionState)
51f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
52a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    exceptionState.throwDOMException(NotSupportedError, "Blob support not implemented yet");
53f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
54f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
55e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, RTCPeerConnection* connection, PassOwnPtr<WebRTCDataChannelHandler> handler)
565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){
575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ASSERT(handler);
58197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return adoptRefCountedGarbageCollectedWillBeNoop(new RTCDataChannel(context, connection, handler));
595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}
605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
61e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, RTCPeerConnection* connection, WebRTCPeerConnectionHandler* peerConnectionHandler, const String& label, const WebRTCDataChannelInit& init, ExceptionState& exceptionState)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
63e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    OwnPtr<WebRTCDataChannelHandler> handler = adoptPtr(peerConnectionHandler->createDataChannel(label, init));
64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!handler) {
6551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwDOMException(NotSupportedError, "RTCDataChannel is not supported");
66d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
68197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return adoptRefCountedGarbageCollectedWillBeNoop(new RTCDataChannel(context, connection, handler.release()));
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
71e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)RTCDataChannel::RTCDataChannel(ExecutionContext* context, RTCPeerConnection* connection, PassOwnPtr<WebRTCDataChannelHandler> handler)
721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    : m_executionContext(context)
73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_handler(handler)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_stopped(false)
75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_readyState(ReadyStateConnecting)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_binaryType(BinaryTypeArrayBuffer)
77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_scheduledEventTimer(this, &RTCDataChannel::scheduledEventTimerFired)
7876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    , m_connection(connection)
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_handler->setClient(this);
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RTCDataChannel::~RTCDataChannel()
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // If the peer connection and the data channel die in the same
8676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // GC cycle stop has not been called and we need to notify the
8776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // client that the channel is gone.
8876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (!m_stopped)
8976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        m_handler->setClient(0);
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RTCDataChannel::label() const
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return m_handler->label();
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RTCDataChannel::reliable() const
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return m_handler->isReliable();
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
102f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)bool RTCDataChannel::ordered() const
103f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
104f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    return m_handler->ordered();
105f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
106f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
107f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)unsigned short RTCDataChannel::maxRetransmitTime() const
108f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
109f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    return m_handler->maxRetransmitTime();
110f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
111f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
112f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)unsigned short RTCDataChannel::maxRetransmits() const
113f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
114f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    return m_handler->maxRetransmits();
115f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
116f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
117f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)String RTCDataChannel::protocol() const
118f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
119f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    return m_handler->protocol();
120f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
121f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
122f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)bool RTCDataChannel::negotiated() const
123f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
124f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    return m_handler->negotiated();
125f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
126f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
127f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)unsigned short RTCDataChannel::id() const
128f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
129f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    return m_handler->id();
130f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
131f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RTCDataChannel::readyState() const
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    switch (m_readyState) {
135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case ReadyStateConnecting:
1363c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "connecting";
137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case ReadyStateOpen:
1383c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "open";
139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case ReadyStateClosing:
1403c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "closing";
141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case ReadyStateClosed:
1423c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "closed";
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return String();
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long RTCDataChannel::bufferedAmount() const
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return m_handler->bufferedAmount();
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RTCDataChannel::binaryType() const
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (m_binaryType) {
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case BinaryTypeBlob:
1583c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "blob";
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case BinaryTypeArrayBuffer:
1603c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return "arraybuffer";
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return String();
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void RTCDataChannel::setBinaryType(const String& binaryType, ExceptionState& exceptionState)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (binaryType == "blob")
16951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        throwNoBlobSupportException(exceptionState);
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else if (binaryType == "arraybuffer")
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_binaryType = BinaryTypeArrayBuffer;
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
17351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwDOMException(TypeMismatchError, "Unknown binary type : " + binaryType);
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void RTCDataChannel::send(const String& data, ExceptionState& exceptionState)
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_readyState != ReadyStateOpen) {
17951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        throwNotOpenException(exceptionState);
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_handler->sendStringData(data)) {
183f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        // FIXME: This should not throw an exception but instead forcefully close the data channel.
18451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        throwCouldNotSendDataException(exceptionState);
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void RTCDataChannel::send(PassRefPtr<ArrayBuffer> prpData, ExceptionState& exceptionState)
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_readyState != ReadyStateOpen) {
19151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        throwNotOpenException(exceptionState);
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<ArrayBuffer> data = prpData;
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t dataLength = data->byteLength();
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!dataLength)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
201a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    if (!m_handler->sendRawData(static_cast<const char*>((data->data())), dataLength)) {
202f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        // FIXME: This should not throw an exception but instead forcefully close the data channel.
20351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        throwCouldNotSendDataException(exceptionState);
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void RTCDataChannel::send(PassRefPtr<ArrayBufferView> data, ExceptionState& exceptionState)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
209a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    if (!m_handler->sendRawData(static_cast<const char*>(data->baseAddress()), data->byteLength())) {
210a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        // FIXME: This should not throw an exception but instead forcefully close the data channel.
211a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        throwCouldNotSendDataException(exceptionState);
212a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
215d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RTCDataChannel::send(PassRefPtrWillBeRawPtr<Blob> data, ExceptionState& exceptionState)
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: implement
21851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    throwNoBlobSupportException(exceptionState);
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RTCDataChannel::close()
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_stopped)
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
226926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_handler->close();
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
229e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RTCDataChannel::didChangeReadyState(WebRTCDataChannelHandlerClient::ReadyState newState)
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
231926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_stopped || m_readyState == ReadyStateClosed)
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_readyState = newState;
235926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
236926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    switch (m_readyState) {
237926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case ReadyStateOpen:
2381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        scheduleDispatchEvent(Event::create(EventTypeNames::open));
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
240926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    case ReadyStateClosed:
2411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        scheduleDispatchEvent(Event::create(EventTypeNames::close));
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default:
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
248e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RTCDataChannel::didReceiveStringData(const WebString& text)
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_stopped)
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
253926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    scheduleDispatchEvent(MessageEvent::create(text));
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
256926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RTCDataChannel::didReceiveRawData(const char* data, size_t dataLength)
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_stopped)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_binaryType == BinaryTypeBlob) {
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: Implement.
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_binaryType == BinaryTypeArrayBuffer) {
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(data, dataLength);
267926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        scheduleDispatchEvent(MessageEvent::create(buffer.release()));
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
273926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RTCDataChannel::didDetectError()
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_stopped)
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleDispatchEvent(Event::create(EventTypeNames::error));
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const AtomicString& RTCDataChannel::interfaceName() const
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return EventTargetNames::RTCDataChannel;
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)ExecutionContext* RTCDataChannel::executionContext() const
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return m_executionContext;
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RTCDataChannel::stop()
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_stopped = true;
294926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_readyState = ReadyStateClosed;
295926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_handler->setClient(0);
2961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    m_executionContext = 0;
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
299a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochvoid RTCDataChannel::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
300926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
301926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_scheduledEvents.append(event);
302926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
303926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_scheduledEventTimer.isActive())
304d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_scheduledEventTimer.startOneShot(0, FROM_HERE);
305926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
306926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
307926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RTCDataChannel::scheduledEventTimerFired(Timer<RTCDataChannel>*)
308926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
309926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_stopped)
310926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
311926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
312a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WillBeHeapVector<RefPtrWillBeMember<Event> > events;
313926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    events.swap(m_scheduledEvents);
314926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
315a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    WillBeHeapVector<RefPtrWillBeMember<Event> >::iterator it = events.begin();
316926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (; it != events.end(); ++it)
317926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        dispatchEvent((*it).release());
318926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
319926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    events.clear();
320926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
321926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
32276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)void RTCDataChannel::clearWeakMembers(Visitor* visitor)
32376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles){
32476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (visitor->isAlive(m_connection))
32576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        return;
32676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    stop();
32776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    m_connection = nullptr;
32876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)}
32976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)
330d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void RTCDataChannel::trace(Visitor* visitor)
331d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
332d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_scheduledEvents);
33376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    visitor->registerWeakMembers<RTCDataChannel, &RTCDataChannel::clearWeakMembers>(this);
334d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    EventTargetWithInlineData::trace(visitor);
335d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
336d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
337c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
338