#include "config.h"
#include "modules/mediastream/RTCDataChannel.h"
-#include "bindings/v8/ExceptionState.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include "core/dom/DOMArrayBuffer.h"
+#include "core/dom/DOMArrayBufferView.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
-#include "core/events/Event.h"
#include "core/events/MessageEvent.h"
#include "core/fileapi/Blob.h"
+#include "modules/mediastream/RTCPeerConnection.h"
#include "public/platform/WebRTCPeerConnectionHandler.h"
-#include "wtf/ArrayBuffer.h"
-#include "wtf/ArrayBufferView.h"
-namespace WebCore {
+namespace blink {
static void throwNotOpenException(ExceptionState& exceptionState)
{
exceptionState.throwDOMException(NotSupportedError, "Blob support not implemented yet");
}
-PassRefPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, PassOwnPtr<blink::WebRTCDataChannelHandler> handler)
+RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, RTCPeerConnection* connection, PassOwnPtr<WebRTCDataChannelHandler> handler)
{
ASSERT(handler);
- return adoptRef(new RTCDataChannel(context, handler));
+ return new RTCDataChannel(context, connection, handler);
}
-PassRefPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, blink::WebRTCPeerConnectionHandler* peerConnectionHandler, const String& label, const blink::WebRTCDataChannelInit& init, ExceptionState& exceptionState)
+RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, RTCPeerConnection* connection, WebRTCPeerConnectionHandler* peerConnectionHandler, const String& label, const WebRTCDataChannelInit& init, ExceptionState& exceptionState)
{
- OwnPtr<blink::WebRTCDataChannelHandler> handler = adoptPtr(peerConnectionHandler->createDataChannel(label, init));
+ OwnPtr<WebRTCDataChannelHandler> handler = adoptPtr(peerConnectionHandler->createDataChannel(label, init));
if (!handler) {
exceptionState.throwDOMException(NotSupportedError, "RTCDataChannel is not supported");
return nullptr;
}
- return adoptRef(new RTCDataChannel(context, handler.release()));
+ return new RTCDataChannel(context, connection, handler.release());
}
-RTCDataChannel::RTCDataChannel(ExecutionContext* context, PassOwnPtr<blink::WebRTCDataChannelHandler> handler)
+RTCDataChannel::RTCDataChannel(ExecutionContext* context, RTCPeerConnection* connection, PassOwnPtr<WebRTCDataChannelHandler> handler)
: m_executionContext(context)
, m_handler(handler)
, m_stopped(false)
, m_readyState(ReadyStateConnecting)
, m_binaryType(BinaryTypeArrayBuffer)
, m_scheduledEventTimer(this, &RTCDataChannel::scheduledEventTimerFired)
+ , m_connection(connection)
{
- ScriptWrappable::init(this);
m_handler->setClient(this);
}
RTCDataChannel::~RTCDataChannel()
{
+ // If the peer connection and the data channel die in the same
+ // GC cycle stop has not been called and we need to notify the
+ // client that the channel is gone.
+ if (!m_stopped)
+ m_handler->setClient(0);
}
String RTCDataChannel::label() const
}
}
-void RTCDataChannel::send(PassRefPtr<ArrayBuffer> prpData, ExceptionState& exceptionState)
+void RTCDataChannel::send(PassRefPtr<DOMArrayBuffer> prpData, ExceptionState& exceptionState)
{
if (m_readyState != ReadyStateOpen) {
throwNotOpenException(exceptionState);
return;
}
- RefPtr<ArrayBuffer> data = prpData;
+ RefPtr<DOMArrayBuffer> data = prpData;
size_t dataLength = data->byteLength();
if (!dataLength)
return;
- const char* dataPointer = static_cast<const char*>(data->data());
-
- if (!m_handler->sendRawData(dataPointer, dataLength)) {
+ if (!m_handler->sendRawData(static_cast<const char*>((data->data())), dataLength)) {
// FIXME: This should not throw an exception but instead forcefully close the data channel.
throwCouldNotSendDataException(exceptionState);
}
}
-void RTCDataChannel::send(PassRefPtr<ArrayBufferView> data, ExceptionState& exceptionState)
+void RTCDataChannel::send(PassRefPtr<DOMArrayBufferView> data, ExceptionState& exceptionState)
{
- RefPtr<ArrayBuffer> arrayBuffer(data->buffer());
- send(arrayBuffer.release(), exceptionState);
+ if (!m_handler->sendRawData(static_cast<const char*>(data->baseAddress()), data->byteLength())) {
+ // FIXME: This should not throw an exception but instead forcefully close the data channel.
+ throwCouldNotSendDataException(exceptionState);
+ }
}
-void RTCDataChannel::send(PassRefPtrWillBeRawPtr<Blob> data, ExceptionState& exceptionState)
+void RTCDataChannel::send(Blob* data, ExceptionState& exceptionState)
{
// FIXME: implement
throwNoBlobSupportException(exceptionState);
m_handler->close();
}
-void RTCDataChannel::didChangeReadyState(blink::WebRTCDataChannelHandlerClient::ReadyState newState)
+void RTCDataChannel::didChangeReadyState(WebRTCDataChannelHandlerClient::ReadyState newState)
{
if (m_stopped || m_readyState == ReadyStateClosed)
return;
}
}
-void RTCDataChannel::didReceiveStringData(const blink::WebString& text)
+void RTCDataChannel::didReceiveStringData(const WebString& text)
{
if (m_stopped)
return;
return;
}
if (m_binaryType == BinaryTypeArrayBuffer) {
- RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(data, dataLength);
+ RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(data, dataLength);
scheduleDispatchEvent(MessageEvent::create(buffer.release()));
return;
}
m_executionContext = 0;
}
-void RTCDataChannel::scheduleDispatchEvent(PassRefPtr<Event> event)
+void RTCDataChannel::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
{
m_scheduledEvents.append(event);
if (m_stopped)
return;
- Vector<RefPtr<Event> > events;
+ WillBeHeapVector<RefPtrWillBeMember<Event> > events;
events.swap(m_scheduledEvents);
- Vector<RefPtr<Event> >::iterator it = events.begin();
+ WillBeHeapVector<RefPtrWillBeMember<Event> >::iterator it = events.begin();
for (; it != events.end(); ++it)
dispatchEvent((*it).release());
events.clear();
}
-} // namespace WebCore
+void RTCDataChannel::clearWeakMembers(Visitor* visitor)
+{
+ if (visitor->isAlive(m_connection))
+ return;
+ stop();
+ m_connection = nullptr;
+}
+
+void RTCDataChannel::trace(Visitor* visitor)
+{
+ visitor->trace(m_scheduledEvents);
+ visitor->registerWeakMembers<RTCDataChannel, &RTCDataChannel::clearWeakMembers>(this);
+ EventTargetWithInlineData::trace(visitor);
+}
+
+} // namespace blink