Index: Source/modules/mediastream/RTCDataChannel.cpp |
diff --git a/Source/modules/mediastream/RTCDataChannel.cpp b/Source/modules/mediastream/RTCDataChannel.cpp |
index 9a0ec1b246913bb4ac02b0e4d0f6f5a6f4b241b1..0b9276f9ed198ce0733d739088c44819e34bca74 100644 |
--- a/Source/modules/mediastream/RTCDataChannel.cpp |
+++ b/Source/modules/mediastream/RTCDataChannel.cpp |
@@ -30,6 +30,7 @@ |
#include "core/dom/ExecutionContext.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" |
@@ -51,29 +52,30 @@ static void throwNoBlobSupportException(ExceptionState& exceptionState) |
exceptionState.throwDOMException(NotSupportedError, "Blob support not implemented yet"); |
} |
-PassRefPtrWillBeRawPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, PassOwnPtr<blink::WebRTCDataChannelHandler> handler) |
+PassRefPtrWillBeRawPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, WeakPtrWillBeRawPtr<RTCPeerConnection> creator, PassOwnPtr<blink::WebRTCDataChannelHandler> handler) |
{ |
ASSERT(handler); |
- return adoptRefWillBeRefCountedGarbageCollected(new RTCDataChannel(context, handler)); |
+ return adoptRefWillBeRefCountedGarbageCollected(new RTCDataChannel(context, creator, handler)); |
} |
-PassRefPtrWillBeRawPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, blink::WebRTCPeerConnectionHandler* peerConnectionHandler, const String& label, const blink::WebRTCDataChannelInit& init, ExceptionState& exceptionState) |
+PassRefPtrWillBeRawPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, WeakPtrWillBeRawPtr<RTCPeerConnection> creator, blink::WebRTCPeerConnectionHandler* peerConnectionHandler, const String& label, const blink::WebRTCDataChannelInit& init, ExceptionState& exceptionState) |
{ |
OwnPtr<blink::WebRTCDataChannelHandler> handler = adoptPtr(peerConnectionHandler->createDataChannel(label, init)); |
if (!handler) { |
exceptionState.throwDOMException(NotSupportedError, "RTCDataChannel is not supported"); |
return nullptr; |
} |
- return adoptRefWillBeRefCountedGarbageCollected(new RTCDataChannel(context, handler.release())); |
+ return adoptRefWillBeRefCountedGarbageCollected(new RTCDataChannel(context, creator, handler.release())); |
} |
-RTCDataChannel::RTCDataChannel(ExecutionContext* context, PassOwnPtr<blink::WebRTCDataChannelHandler> handler) |
+RTCDataChannel::RTCDataChannel(ExecutionContext* context, WeakPtrWillBeRawPtr<RTCPeerConnection> creator, PassOwnPtr<blink::WebRTCDataChannelHandler> handler) |
: m_executionContext(context) |
, m_handler(handler) |
, m_stopped(false) |
, m_readyState(ReadyStateConnecting) |
, m_binaryType(BinaryTypeArrayBuffer) |
, m_scheduledEventTimer(this, &RTCDataChannel::scheduledEventTimerFired) |
+ , m_creator(creator) |
{ |
ScriptWrappable::init(this); |
m_handler->setClient(this); |
@@ -222,6 +224,7 @@ void RTCDataChannel::close() |
void RTCDataChannel::didChangeReadyState(blink::WebRTCDataChannelHandlerClient::ReadyState newState) |
{ |
+ stopAndFireCloseEventIfCreatorWasDeleted(); |
if (m_stopped || m_readyState == ReadyStateClosed) |
return; |
@@ -241,6 +244,7 @@ void RTCDataChannel::didChangeReadyState(blink::WebRTCDataChannelHandlerClient:: |
void RTCDataChannel::didReceiveStringData(const blink::WebString& text) |
{ |
+ stopAndFireCloseEventIfCreatorWasDeleted(); |
if (m_stopped) |
return; |
@@ -249,6 +253,7 @@ void RTCDataChannel::didReceiveStringData(const blink::WebString& text) |
void RTCDataChannel::didReceiveRawData(const char* data, size_t dataLength) |
{ |
+ stopAndFireCloseEventIfCreatorWasDeleted(); |
if (m_stopped) |
return; |
@@ -266,6 +271,7 @@ void RTCDataChannel::didReceiveRawData(const char* data, size_t dataLength) |
void RTCDataChannel::didDetectError() |
{ |
+ stopAndFireCloseEventIfCreatorWasDeleted(); |
if (m_stopped) |
return; |
@@ -316,7 +322,18 @@ void RTCDataChannel::scheduledEventTimerFired(Timer<RTCDataChannel>*) |
void RTCDataChannel::trace(Visitor* visitor) |
{ |
visitor->trace(m_scheduledEvents); |
+ visitor->trace(m_creator); |
EventTargetWithInlineData::trace(visitor); |
} |
+void RTCDataChannel::stopAndFireCloseEventIfCreatorWasDeleted() |
+{ |
+ if (!m_creator) { |
+ // When the RTCPeerConnection creator is gone, we must stop this data |
+ // channel and fire a closed event. |
+ dispatchEvent(Event::create(EventTypeNames::close)); |
+ stop(); |
+ } |
+} |
+ |
} // namespace WebCore |