Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: third_party/WebKit/Source/modules/mediastream/RTCDataChannel.cpp

Issue 2097563002: Split the mediastream module in Blink into mediastream and peerconnection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add DEPS file Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN Y
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN Y
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O N
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25 #include "modules/mediastream/RTCDataChannel.h"
26
27 #include "bindings/core/v8/ExceptionState.h"
28 #include "core/dom/DOMArrayBuffer.h"
29 #include "core/dom/DOMArrayBufferView.h"
30 #include "core/dom/ExceptionCode.h"
31 #include "core/dom/ExecutionContext.h"
32 #include "core/events/MessageEvent.h"
33 #include "core/fileapi/Blob.h"
34 #include "modules/mediastream/RTCPeerConnection.h"
35 #include "public/platform/WebRTCPeerConnectionHandler.h"
36 #include "wtf/PtrUtil.h"
37 #include <memory>
38
39 namespace blink {
40
41 static void throwNotOpenException(ExceptionState& exceptionState)
42 {
43 exceptionState.throwDOMException(InvalidStateError, "RTCDataChannel.readySta te is not 'open'");
44 }
45
46 static void throwCouldNotSendDataException(ExceptionState& exceptionState)
47 {
48 exceptionState.throwDOMException(NetworkError, "Could not send data");
49 }
50
51 static void throwNoBlobSupportException(ExceptionState& exceptionState)
52 {
53 exceptionState.throwDOMException(NotSupportedError, "Blob support not implem ented yet");
54 }
55
56 RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, std::unique_pt r<WebRTCDataChannelHandler> handler)
57 {
58 DCHECK(handler);
59 RTCDataChannel* channel = new RTCDataChannel(context, std::move(handler));
60 channel->suspendIfNeeded();
61
62 return channel;
63 }
64
65 RTCDataChannel* RTCDataChannel::create(ExecutionContext* context, WebRTCPeerConn ectionHandler* peerConnectionHandler, const String& label, const WebRTCDataChann elInit& init, ExceptionState& exceptionState)
66 {
67 std::unique_ptr<WebRTCDataChannelHandler> handler = wrapUnique(peerConnectio nHandler->createDataChannel(label, init));
68 if (!handler) {
69 exceptionState.throwDOMException(NotSupportedError, "RTCDataChannel is n ot supported");
70 return nullptr;
71 }
72 RTCDataChannel* channel = new RTCDataChannel(context, std::move(handler));
73 channel->suspendIfNeeded();
74
75 return channel;
76 }
77
78 RTCDataChannel::RTCDataChannel(ExecutionContext* context, std::unique_ptr<WebRTC DataChannelHandler> handler)
79 : ActiveScriptWrappable(this)
80 , ActiveDOMObject(context)
81 , m_handler(std::move(handler))
82 , m_readyState(ReadyStateConnecting)
83 , m_binaryType(BinaryTypeArrayBuffer)
84 , m_scheduledEventTimer(this, &RTCDataChannel::scheduledEventTimerFired)
85 , m_bufferedAmountLowThreshold(0U)
86 , m_stopped(false)
87 {
88 ThreadState::current()->registerPreFinalizer(this);
89 m_handler->setClient(this);
90 }
91
92 RTCDataChannel::~RTCDataChannel()
93 {
94 }
95
96 void RTCDataChannel::dispose()
97 {
98 if (m_stopped)
99 return;
100
101 // Promptly clears a raw reference from content/ to an on-heap object
102 // so that content/ doesn't access it in a lazy sweeping phase.
103 m_handler->setClient(nullptr);
104 m_handler.reset();
105 }
106
107 RTCDataChannel::ReadyState RTCDataChannel::getHandlerState() const
108 {
109 return m_handler->state();
110 }
111
112 String RTCDataChannel::label() const
113 {
114 return m_handler->label();
115 }
116
117 bool RTCDataChannel::reliable() const
118 {
119 return m_handler->isReliable();
120 }
121
122 bool RTCDataChannel::ordered() const
123 {
124 return m_handler->ordered();
125 }
126
127 unsigned short RTCDataChannel::maxRetransmitTime() const
128 {
129 return m_handler->maxRetransmitTime();
130 }
131
132 unsigned short RTCDataChannel::maxRetransmits() const
133 {
134 return m_handler->maxRetransmits();
135 }
136
137 String RTCDataChannel::protocol() const
138 {
139 return m_handler->protocol();
140 }
141
142 bool RTCDataChannel::negotiated() const
143 {
144 return m_handler->negotiated();
145 }
146
147 unsigned short RTCDataChannel::id() const
148 {
149 return m_handler->id();
150 }
151
152 String RTCDataChannel::readyState() const
153 {
154 switch (m_readyState) {
155 case ReadyStateConnecting:
156 return "connecting";
157 case ReadyStateOpen:
158 return "open";
159 case ReadyStateClosing:
160 return "closing";
161 case ReadyStateClosed:
162 return "closed";
163 }
164
165 NOTREACHED();
166 return String();
167 }
168
169 unsigned RTCDataChannel::bufferedAmount() const
170 {
171 return m_handler->bufferedAmount();
172 }
173
174 unsigned RTCDataChannel::bufferedAmountLowThreshold() const
175 {
176 return m_bufferedAmountLowThreshold;
177 }
178
179 void RTCDataChannel::setBufferedAmountLowThreshold(unsigned threshold)
180 {
181 m_bufferedAmountLowThreshold = threshold;
182 }
183
184 String RTCDataChannel::binaryType() const
185 {
186 switch (m_binaryType) {
187 case BinaryTypeBlob:
188 return "blob";
189 case BinaryTypeArrayBuffer:
190 return "arraybuffer";
191 }
192 NOTREACHED();
193 return String();
194 }
195
196 void RTCDataChannel::setBinaryType(const String& binaryType, ExceptionState& exc eptionState)
197 {
198 if (binaryType == "blob")
199 throwNoBlobSupportException(exceptionState);
200 else if (binaryType == "arraybuffer")
201 m_binaryType = BinaryTypeArrayBuffer;
202 else
203 exceptionState.throwDOMException(TypeMismatchError, "Unknown binary type : " + binaryType);
204 }
205
206 void RTCDataChannel::send(const String& data, ExceptionState& exceptionState)
207 {
208 if (m_readyState != ReadyStateOpen) {
209 throwNotOpenException(exceptionState);
210 return;
211 }
212 if (!m_handler->sendStringData(data)) {
213 // FIXME: This should not throw an exception but instead forcefully clos e the data channel.
214 throwCouldNotSendDataException(exceptionState);
215 }
216 }
217
218 void RTCDataChannel::send(DOMArrayBuffer* data, ExceptionState& exceptionState)
219 {
220 if (m_readyState != ReadyStateOpen) {
221 throwNotOpenException(exceptionState);
222 return;
223 }
224
225 size_t dataLength = data->byteLength();
226 if (!dataLength)
227 return;
228
229 if (!m_handler->sendRawData(static_cast<const char*>((data->data())), dataLe ngth)) {
230 // FIXME: This should not throw an exception but instead forcefully clos e the data channel.
231 throwCouldNotSendDataException(exceptionState);
232 }
233 }
234
235 void RTCDataChannel::send(DOMArrayBufferView* data, ExceptionState& exceptionSta te)
236 {
237 if (!m_handler->sendRawData(static_cast<const char*>(data->baseAddress()), d ata->byteLength())) {
238 // FIXME: This should not throw an exception but instead forcefully clos e the data channel.
239 throwCouldNotSendDataException(exceptionState);
240 }
241 }
242
243 void RTCDataChannel::send(Blob* data, ExceptionState& exceptionState)
244 {
245 // FIXME: implement
246 throwNoBlobSupportException(exceptionState);
247 }
248
249 void RTCDataChannel::close()
250 {
251 m_handler->close();
252 }
253
254 void RTCDataChannel::didChangeReadyState(WebRTCDataChannelHandlerClient::ReadySt ate newState)
255 {
256 if (m_readyState == ReadyStateClosed)
257 return;
258
259 m_readyState = newState;
260
261 switch (m_readyState) {
262 case ReadyStateOpen:
263 scheduleDispatchEvent(Event::create(EventTypeNames::open));
264 break;
265 case ReadyStateClosed:
266 scheduleDispatchEvent(Event::create(EventTypeNames::close));
267 break;
268 default:
269 break;
270 }
271 }
272
273 void RTCDataChannel::didDecreaseBufferedAmount(unsigned previousAmount)
274 {
275 if (previousAmount > m_bufferedAmountLowThreshold
276 && bufferedAmount() <= m_bufferedAmountLowThreshold) {
277 scheduleDispatchEvent(Event::create(EventTypeNames::bufferedamountlow));
278 }
279 }
280
281 void RTCDataChannel::didReceiveStringData(const WebString& text)
282 {
283 scheduleDispatchEvent(MessageEvent::create(text));
284 }
285
286 void RTCDataChannel::didReceiveRawData(const char* data, size_t dataLength)
287 {
288 if (m_binaryType == BinaryTypeBlob) {
289 // FIXME: Implement.
290 return;
291 }
292 if (m_binaryType == BinaryTypeArrayBuffer) {
293 DOMArrayBuffer* buffer = DOMArrayBuffer::create(data, dataLength);
294 scheduleDispatchEvent(MessageEvent::create(buffer));
295 return;
296 }
297 NOTREACHED();
298 }
299
300 void RTCDataChannel::didDetectError()
301 {
302 scheduleDispatchEvent(Event::create(EventTypeNames::error));
303 }
304
305 const AtomicString& RTCDataChannel::interfaceName() const
306 {
307 return EventTargetNames::RTCDataChannel;
308 }
309
310 ExecutionContext* RTCDataChannel::getExecutionContext() const
311 {
312 return ActiveDOMObject::getExecutionContext();
313 }
314
315 // ActiveDOMObject
316 void RTCDataChannel::suspend()
317 {
318 m_scheduledEventTimer.stop();
319 }
320
321 void RTCDataChannel::resume()
322 {
323 if (!m_scheduledEvents.isEmpty() && !m_scheduledEventTimer.isActive())
324 m_scheduledEventTimer.startOneShot(0, BLINK_FROM_HERE);
325 }
326
327 void RTCDataChannel::stop()
328 {
329 if (m_stopped)
330 return;
331
332 m_stopped = true;
333 m_handler->setClient(nullptr);
334 m_handler.reset();
335 }
336
337 // ActiveScriptWrappable
338 bool RTCDataChannel::hasPendingActivity() const
339 {
340 if (m_stopped)
341 return false;
342
343 // A RTCDataChannel object must not be garbage collected if its
344 // * readyState is connecting and at least one event listener is registered
345 // for open events, message events, error events, or close events.
346 // * readyState is open and at least one event listener is registered for
347 // message events, error events, or close events.
348 // * readyState is closing and at least one event listener is registered for
349 // error events, or close events.
350 // * underlying data transport is established and data is queued to be
351 // transmitted.
352 bool hasValidListeners = false;
353 switch (m_readyState) {
354 case ReadyStateConnecting:
355 hasValidListeners |= hasEventListeners(EventTypeNames::open);
356 // fallthrough intended
357 case ReadyStateOpen:
358 hasValidListeners |= hasEventListeners(EventTypeNames::message);
359 // fallthrough intended
360 case ReadyStateClosing:
361 hasValidListeners |= hasEventListeners(EventTypeNames::error) || hasEven tListeners(EventTypeNames::close);
362 break;
363 default:
364 break;
365 }
366
367 if (hasValidListeners)
368 return true;
369
370 return m_readyState != ReadyStateClosed && bufferedAmount() > 0;
371 }
372
373 void RTCDataChannel::scheduleDispatchEvent(Event* event)
374 {
375 m_scheduledEvents.append(event);
376
377 if (!m_scheduledEventTimer.isActive())
378 m_scheduledEventTimer.startOneShot(0, BLINK_FROM_HERE);
379 }
380
381 void RTCDataChannel::scheduledEventTimerFired(Timer<RTCDataChannel>*)
382 {
383 HeapVector<Member<Event>> events;
384 events.swap(m_scheduledEvents);
385
386 HeapVector<Member<Event>>::iterator it = events.begin();
387 for (; it != events.end(); ++it)
388 dispatchEvent((*it).release());
389
390 events.clear();
391 }
392
393 DEFINE_TRACE(RTCDataChannel)
394 {
395 visitor->trace(m_scheduledEvents);
396 EventTargetWithInlineData::trace(visitor);
397 ActiveDOMObject::trace(visitor);
398 }
399
400 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698