OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 static void throwCouldNotSendDataException(ExceptionState& exceptionState) | 44 static void throwCouldNotSendDataException(ExceptionState& exceptionState) |
45 { | 45 { |
46 exceptionState.throwDOMException(NetworkError, "Could not send data"); | 46 exceptionState.throwDOMException(NetworkError, "Could not send data"); |
47 } | 47 } |
48 | 48 |
49 static void throwNoBlobSupportException(ExceptionState& exceptionState) | 49 static void throwNoBlobSupportException(ExceptionState& exceptionState) |
50 { | 50 { |
51 exceptionState.throwDOMException(NotSupportedError, "Blob support not implem
ented yet"); | 51 exceptionState.throwDOMException(NotSupportedError, "Blob support not implem
ented yet"); |
52 } | 52 } |
53 | 53 |
54 RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, RTCPeerConnect
ion* connection, PassOwnPtr<WebRTCDataChannelHandler> handler) | 54 RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, PassOwnPtr<Web
RTCDataChannelHandler> handler) |
55 { | 55 { |
56 ASSERT(handler); | 56 ASSERT(handler); |
57 return new RTCDataChannel(context, connection, handler); | 57 return new RTCDataChannel(context, handler); |
58 } | 58 } |
59 | 59 |
60 RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, RTCPeerConnect
ion* connection, WebRTCPeerConnectionHandler* peerConnectionHandler, const Strin
g& label, const WebRTCDataChannelInit& init, ExceptionState& exceptionState) | 60 RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, WebRTCPeerConn
ectionHandler* peerConnectionHandler, const String& label, const WebRTCDataChann
elInit& init, ExceptionState& exceptionState) |
61 { | 61 { |
62 OwnPtr<WebRTCDataChannelHandler> handler = adoptPtr(peerConnectionHandler->c
reateDataChannel(label, init)); | 62 OwnPtr<WebRTCDataChannelHandler> handler = adoptPtr(peerConnectionHandler->c
reateDataChannel(label, init)); |
63 if (!handler) { | 63 if (!handler) { |
64 exceptionState.throwDOMException(NotSupportedError, "RTCDataChannel is n
ot supported"); | 64 exceptionState.throwDOMException(NotSupportedError, "RTCDataChannel is n
ot supported"); |
65 return nullptr; | 65 return nullptr; |
66 } | 66 } |
67 return new RTCDataChannel(context, connection, handler.release()); | 67 return new RTCDataChannel(context, handler.release()); |
68 } | 68 } |
69 | 69 |
70 RTCDataChannel::RTCDataChannel(ExecutionContext* context, RTCPeerConnection* con
nection, PassOwnPtr<WebRTCDataChannelHandler> handler) | 70 RTCDataChannel::RTCDataChannel(ExecutionContext* context, PassOwnPtr<WebRTCDataC
hannelHandler> handler) |
71 : m_executionContext(context) | 71 : m_executionContext(context) |
72 , m_handler(handler) | 72 , m_handler(handler) |
73 , m_stopped(false) | |
74 , m_readyState(ReadyStateConnecting) | 73 , m_readyState(ReadyStateConnecting) |
75 , m_binaryType(BinaryTypeArrayBuffer) | 74 , m_binaryType(BinaryTypeArrayBuffer) |
76 , m_scheduledEventTimer(this, &RTCDataChannel::scheduledEventTimerFired) | 75 , m_scheduledEventTimer(this, &RTCDataChannel::scheduledEventTimerFired) |
77 , m_connection(connection) | |
78 , m_bufferedAmountLowThreshold(0U) | 76 , m_bufferedAmountLowThreshold(0U) |
79 { | 77 { |
80 m_handler->setClient(this); | 78 m_handler->setClient(this); |
81 } | 79 } |
82 | 80 |
83 RTCDataChannel::~RTCDataChannel() | 81 RTCDataChannel::~RTCDataChannel() |
84 { | 82 { |
85 // If the peer connection and the data channel die in the same | 83 // Notify the client that the channel is gone. |
86 // GC cycle stop has not been called and we need to notify the | 84 m_handler->setClient(0); |
87 // client that the channel is gone. | |
88 if (!m_stopped) | |
89 m_handler->setClient(0); | |
90 } | 85 } |
91 | 86 |
92 RTCDataChannel::ReadyState RTCDataChannel::getHandlerState() const | 87 RTCDataChannel::ReadyState RTCDataChannel::getHandlerState() const |
93 { | 88 { |
94 return m_handler->state(); | 89 return m_handler->state(); |
95 } | 90 } |
96 | 91 |
97 String RTCDataChannel::label() const | 92 String RTCDataChannel::label() const |
98 { | 93 { |
99 return m_handler->label(); | 94 return m_handler->label(); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 } | 223 } |
229 | 224 |
230 void RTCDataChannel::send(Blob* data, ExceptionState& exceptionState) | 225 void RTCDataChannel::send(Blob* data, ExceptionState& exceptionState) |
231 { | 226 { |
232 // FIXME: implement | 227 // FIXME: implement |
233 throwNoBlobSupportException(exceptionState); | 228 throwNoBlobSupportException(exceptionState); |
234 } | 229 } |
235 | 230 |
236 void RTCDataChannel::close() | 231 void RTCDataChannel::close() |
237 { | 232 { |
238 if (m_stopped) | |
239 return; | |
240 | |
241 m_handler->close(); | 233 m_handler->close(); |
242 } | 234 } |
243 | 235 |
244 void RTCDataChannel::didChangeReadyState(WebRTCDataChannelHandlerClient::ReadySt
ate newState) | 236 void RTCDataChannel::didChangeReadyState(WebRTCDataChannelHandlerClient::ReadySt
ate newState) |
245 { | 237 { |
246 if (m_stopped || m_readyState == ReadyStateClosed) | 238 if (m_readyState == ReadyStateClosed) |
247 return; | 239 return; |
248 | 240 |
249 m_readyState = newState; | 241 m_readyState = newState; |
250 | 242 |
251 switch (m_readyState) { | 243 switch (m_readyState) { |
252 case ReadyStateOpen: | 244 case ReadyStateOpen: |
253 scheduleDispatchEvent(Event::create(EventTypeNames::open)); | 245 scheduleDispatchEvent(Event::create(EventTypeNames::open)); |
254 break; | 246 break; |
255 case ReadyStateClosed: | 247 case ReadyStateClosed: |
256 scheduleDispatchEvent(Event::create(EventTypeNames::close)); | 248 scheduleDispatchEvent(Event::create(EventTypeNames::close)); |
257 break; | 249 break; |
258 default: | 250 default: |
259 break; | 251 break; |
260 } | 252 } |
261 } | 253 } |
262 | 254 |
263 void RTCDataChannel::didDecreaseBufferedAmount(unsigned previousAmount) | 255 void RTCDataChannel::didDecreaseBufferedAmount(unsigned previousAmount) |
264 { | 256 { |
265 if (previousAmount > m_bufferedAmountLowThreshold | 257 if (previousAmount > m_bufferedAmountLowThreshold |
266 && bufferedAmount() <= m_bufferedAmountLowThreshold) { | 258 && bufferedAmount() <= m_bufferedAmountLowThreshold) { |
267 scheduleDispatchEvent(Event::create(EventTypeNames::bufferedamountlow)); | 259 scheduleDispatchEvent(Event::create(EventTypeNames::bufferedamountlow)); |
268 } | 260 } |
269 } | 261 } |
270 | 262 |
271 void RTCDataChannel::didReceiveStringData(const WebString& text) | 263 void RTCDataChannel::didReceiveStringData(const WebString& text) |
272 { | 264 { |
273 if (m_stopped) | |
274 return; | |
275 | |
276 scheduleDispatchEvent(MessageEvent::create(text)); | 265 scheduleDispatchEvent(MessageEvent::create(text)); |
277 } | 266 } |
278 | 267 |
279 void RTCDataChannel::didReceiveRawData(const char* data, size_t dataLength) | 268 void RTCDataChannel::didReceiveRawData(const char* data, size_t dataLength) |
280 { | 269 { |
281 if (m_stopped) | |
282 return; | |
283 | |
284 if (m_binaryType == BinaryTypeBlob) { | 270 if (m_binaryType == BinaryTypeBlob) { |
285 // FIXME: Implement. | 271 // FIXME: Implement. |
286 return; | 272 return; |
287 } | 273 } |
288 if (m_binaryType == BinaryTypeArrayBuffer) { | 274 if (m_binaryType == BinaryTypeArrayBuffer) { |
289 RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(data, dataLength)
; | 275 RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(data, dataLength)
; |
290 scheduleDispatchEvent(MessageEvent::create(buffer.release())); | 276 scheduleDispatchEvent(MessageEvent::create(buffer.release())); |
291 return; | 277 return; |
292 } | 278 } |
293 ASSERT_NOT_REACHED(); | 279 ASSERT_NOT_REACHED(); |
294 } | 280 } |
295 | 281 |
296 void RTCDataChannel::didDetectError() | 282 void RTCDataChannel::didDetectError() |
297 { | 283 { |
298 if (m_stopped) | |
299 return; | |
300 | |
301 scheduleDispatchEvent(Event::create(EventTypeNames::error)); | 284 scheduleDispatchEvent(Event::create(EventTypeNames::error)); |
302 } | 285 } |
303 | 286 |
304 const AtomicString& RTCDataChannel::interfaceName() const | 287 const AtomicString& RTCDataChannel::interfaceName() const |
305 { | 288 { |
306 return EventTargetNames::RTCDataChannel; | 289 return EventTargetNames::RTCDataChannel; |
307 } | 290 } |
308 | 291 |
309 ExecutionContext* RTCDataChannel::executionContext() const | 292 ExecutionContext* RTCDataChannel::executionContext() const |
310 { | 293 { |
311 return m_executionContext; | 294 return m_executionContext; |
312 } | 295 } |
313 | 296 |
314 void RTCDataChannel::stop() | |
315 { | |
316 m_stopped = true; | |
317 m_readyState = ReadyStateClosed; | |
318 m_handler->setClient(0); | |
319 m_executionContext = 0; | |
320 } | |
321 | |
322 void RTCDataChannel::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> event) | 297 void RTCDataChannel::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> event) |
323 { | 298 { |
324 m_scheduledEvents.append(event); | 299 m_scheduledEvents.append(event); |
325 | 300 |
326 if (!m_scheduledEventTimer.isActive()) | 301 if (!m_scheduledEventTimer.isActive()) |
327 m_scheduledEventTimer.startOneShot(0, BLINK_FROM_HERE); | 302 m_scheduledEventTimer.startOneShot(0, BLINK_FROM_HERE); |
328 } | 303 } |
329 | 304 |
330 void RTCDataChannel::scheduledEventTimerFired(Timer<RTCDataChannel>*) | 305 void RTCDataChannel::scheduledEventTimerFired(Timer<RTCDataChannel>*) |
331 { | 306 { |
332 if (m_stopped) | |
333 return; | |
334 | |
335 WillBeHeapVector<RefPtrWillBeMember<Event>> events; | 307 WillBeHeapVector<RefPtrWillBeMember<Event>> events; |
336 events.swap(m_scheduledEvents); | 308 events.swap(m_scheduledEvents); |
337 | 309 |
338 WillBeHeapVector<RefPtrWillBeMember<Event>>::iterator it = events.begin(); | 310 WillBeHeapVector<RefPtrWillBeMember<Event>>::iterator it = events.begin(); |
339 for (; it != events.end(); ++it) | 311 for (; it != events.end(); ++it) |
340 dispatchEvent((*it).release()); | 312 dispatchEvent((*it).release()); |
341 | 313 |
342 events.clear(); | 314 events.clear(); |
343 } | 315 } |
344 | 316 |
345 void RTCDataChannel::clearWeakMembers(Visitor* visitor) | |
346 { | |
347 if (Heap::isHeapObjectAlive(m_connection)) | |
348 return; | |
349 stop(); | |
350 m_connection = nullptr; | |
351 } | |
352 | |
353 DEFINE_TRACE(RTCDataChannel) | 317 DEFINE_TRACE(RTCDataChannel) |
354 { | 318 { |
355 visitor->trace(m_executionContext); | 319 visitor->trace(m_executionContext); |
356 visitor->trace(m_scheduledEvents); | 320 visitor->trace(m_scheduledEvents); |
357 visitor->template registerWeakMembers<RTCDataChannel, &RTCDataChannel::clear
WeakMembers>(this); | |
358 RefCountedGarbageCollectedEventTargetWithInlineData<RTCDataChannel>::trace(v
isitor); | 321 RefCountedGarbageCollectedEventTargetWithInlineData<RTCDataChannel>::trace(v
isitor); |
359 } | 322 } |
360 | 323 |
361 } // namespace blink | 324 } // namespace blink |
OLD | NEW |