#include "config.h"
#include "modules/mediastream/RTCDataChannel.h"
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
-#include "core/events/Event.h"
+#include "bindings/core/v8/ExceptionState.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
#include "core/events/MessageEvent.h"
#include "core/fileapi/Blob.h"
-#include "core/platform/mediastream/RTCDataChannelHandler.h"
-#include "core/platform/mediastream/RTCPeerConnectionHandler.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& es)
+static void throwNotOpenException(ExceptionState& exceptionState)
{
- es.throwDOMException(InvalidStateError, "RTCDataChannel.readyState is not 'open'");
+ exceptionState.throwDOMException(InvalidStateError, "RTCDataChannel.readyState is not 'open'");
}
-static void throwCouldNotSendDataException(ExceptionState& es)
+static void throwCouldNotSendDataException(ExceptionState& exceptionState)
{
- es.throwDOMException(NetworkError, "Could not send data");
+ exceptionState.throwDOMException(NetworkError, "Could not send data");
}
-static void throwNoBlobSupportException(ExceptionState& es)
+static void throwNoBlobSupportException(ExceptionState& exceptionState)
{
- es.throwDOMException(NotSupportedError, ExceptionMessages::failedToExecute("send", "RTCDataChannel", "Blob support not implemented yet"));
+ exceptionState.throwDOMException(NotSupportedError, "Blob support not implemented yet");
}
-PassRefPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, PassOwnPtr<RTCDataChannelHandler> handler)
+RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, RTCPeerConnection* connection, PassOwnPtr<WebRTCDataChannelHandler> handler)
{
ASSERT(handler);
- return adoptRef(new RTCDataChannel(context, handler));
+ return adoptRefCountedGarbageCollectedWillBeNoop(new RTCDataChannel(context, connection, handler));
}
-PassRefPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, RTCPeerConnectionHandler* peerConnectionHandler, const String& label, const WebKit::WebRTCDataChannelInit& init, ExceptionState& es)
+RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, RTCPeerConnection* connection, WebRTCPeerConnectionHandler* peerConnectionHandler, const String& label, const WebRTCDataChannelInit& init, ExceptionState& exceptionState)
{
- OwnPtr<RTCDataChannelHandler> handler = peerConnectionHandler->createDataChannel(label, init);
+ OwnPtr<WebRTCDataChannelHandler> handler = adoptPtr(peerConnectionHandler->createDataChannel(label, init));
if (!handler) {
- es.throwDOMException(NotSupportedError, "RTCDataChannel is not supported");
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, "RTCDataChannel is not supported");
+ return nullptr;
}
- return adoptRef(new RTCDataChannel(context, handler.release()));
+ return adoptRefCountedGarbageCollectedWillBeNoop(new RTCDataChannel(context, connection, handler.release()));
}
-RTCDataChannel::RTCDataChannel(ExecutionContext* context, PassOwnPtr<RTCDataChannelHandler> 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
return String();
}
-void RTCDataChannel::setBinaryType(const String& binaryType, ExceptionState& es)
+void RTCDataChannel::setBinaryType(const String& binaryType, ExceptionState& exceptionState)
{
if (binaryType == "blob")
- throwNoBlobSupportException(es);
+ throwNoBlobSupportException(exceptionState);
else if (binaryType == "arraybuffer")
m_binaryType = BinaryTypeArrayBuffer;
else
- es.throwDOMException(TypeMismatchError, "Unknown binary type : " + binaryType);
+ exceptionState.throwDOMException(TypeMismatchError, "Unknown binary type : " + binaryType);
}
-void RTCDataChannel::send(const String& data, ExceptionState& es)
+void RTCDataChannel::send(const String& data, ExceptionState& exceptionState)
{
if (m_readyState != ReadyStateOpen) {
- throwNotOpenException(es);
+ throwNotOpenException(exceptionState);
return;
}
if (!m_handler->sendStringData(data)) {
// FIXME: This should not throw an exception but instead forcefully close the data channel.
- throwCouldNotSendDataException(es);
+ throwCouldNotSendDataException(exceptionState);
}
}
-void RTCDataChannel::send(PassRefPtr<ArrayBuffer> prpData, ExceptionState& es)
+void RTCDataChannel::send(PassRefPtr<ArrayBuffer> prpData, ExceptionState& exceptionState)
{
if (m_readyState != ReadyStateOpen) {
- throwNotOpenException(es);
+ throwNotOpenException(exceptionState);
return;
}
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(es);
+ throwCouldNotSendDataException(exceptionState);
}
}
-void RTCDataChannel::send(PassRefPtr<ArrayBufferView> data, ExceptionState& es)
+void RTCDataChannel::send(PassRefPtr<ArrayBufferView> data, ExceptionState& exceptionState)
{
- RefPtr<ArrayBuffer> arrayBuffer(data->buffer());
- send(arrayBuffer.release(), es);
+ 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(PassRefPtr<Blob> data, ExceptionState& es)
+void RTCDataChannel::send(PassRefPtrWillBeRawPtr<Blob> data, ExceptionState& exceptionState)
{
// FIXME: implement
- throwNoBlobSupportException(es);
+ throwNoBlobSupportException(exceptionState);
}
void RTCDataChannel::close()
m_handler->close();
}
-void RTCDataChannel::didChangeReadyState(ReadyState newState)
+void RTCDataChannel::didChangeReadyState(WebRTCDataChannelHandlerClient::ReadyState newState)
{
if (m_stopped || m_readyState == ReadyStateClosed)
return;
}
}
-void RTCDataChannel::didReceiveStringData(const String& text)
+void RTCDataChannel::didReceiveStringData(const WebString& text)
{
if (m_stopped)
return;
m_executionContext = 0;
}
-void RTCDataChannel::scheduleDispatchEvent(PassRefPtr<Event> event)
+void RTCDataChannel::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
{
m_scheduledEvents.append(event);
if (!m_scheduledEventTimer.isActive())
- m_scheduledEventTimer.startOneShot(0);
+ m_scheduledEventTimer.startOneShot(0, FROM_HERE);
}
void RTCDataChannel::scheduledEventTimerFired(Timer<RTCDataChannel>*)
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