Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / mediastream / RTCDataChannel.cpp
index 1941333..e6c3402 100644 (file)
 #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
@@ -160,32 +163,32 @@ String RTCDataChannel::binaryType() 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;
     }
 
@@ -195,24 +198,24 @@ void RTCDataChannel::send(PassRefPtr<ArrayBuffer> prpData, ExceptionState& es)
     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()
@@ -223,7 +226,7 @@ void RTCDataChannel::close()
     m_handler->close();
 }
 
-void RTCDataChannel::didChangeReadyState(ReadyState newState)
+void RTCDataChannel::didChangeReadyState(WebRTCDataChannelHandlerClient::ReadyState newState)
 {
     if (m_stopped || m_readyState == ReadyStateClosed)
         return;
@@ -242,7 +245,7 @@ void RTCDataChannel::didChangeReadyState(ReadyState newState)
     }
 }
 
-void RTCDataChannel::didReceiveStringData(const String& text)
+void RTCDataChannel::didReceiveStringData(const WebString& text)
 {
     if (m_stopped)
         return;
@@ -293,12 +296,12 @@ void RTCDataChannel::stop()
     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>*)
@@ -306,14 +309,29 @@ 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