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

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

Issue 268923002: Add support of sending blob data for RTCDataChannel Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 7 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
« no previous file with comments | « Source/modules/mediastream/RTCDataChannel.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 13 matching lines...) Expand all
24 24
25 #include "config.h" 25 #include "config.h"
26 #include "modules/mediastream/RTCDataChannel.h" 26 #include "modules/mediastream/RTCDataChannel.h"
27 27
28 #include "bindings/v8/ExceptionState.h" 28 #include "bindings/v8/ExceptionState.h"
29 #include "core/dom/ExceptionCode.h" 29 #include "core/dom/ExceptionCode.h"
30 #include "core/dom/ExecutionContext.h" 30 #include "core/dom/ExecutionContext.h"
31 #include "core/events/Event.h" 31 #include "core/events/Event.h"
32 #include "core/events/MessageEvent.h" 32 #include "core/events/MessageEvent.h"
33 #include "core/fileapi/Blob.h" 33 #include "core/fileapi/Blob.h"
34 #include "core/fileapi/FileReaderLoader.h"
34 #include "public/platform/WebRTCPeerConnectionHandler.h" 35 #include "public/platform/WebRTCPeerConnectionHandler.h"
35 #include "wtf/ArrayBuffer.h" 36 #include "wtf/ArrayBuffer.h"
36 #include "wtf/ArrayBufferView.h" 37 #include "wtf/ArrayBufferView.h"
38 #include "wtf/OwnPtr.h"
37 39
38 namespace WebCore { 40 namespace WebCore {
39 41
40 static void throwNotOpenException(ExceptionState& exceptionState) 42 static void throwNotOpenException(ExceptionState& exceptionState)
41 { 43 {
42 exceptionState.throwDOMException(InvalidStateError, "RTCDataChannel.readySta te is not 'open'"); 44 exceptionState.throwDOMException(InvalidStateError, "RTCDataChannel.readySta te is not 'open'");
43 } 45 }
44 46
45 static void throwCouldNotSendDataException(ExceptionState& exceptionState) 47 static void throwCouldNotSendDataException(ExceptionState& exceptionState)
46 { 48 {
47 exceptionState.throwDOMException(NetworkError, "Could not send data"); 49 exceptionState.throwDOMException(NetworkError, "Could not send data");
48 } 50 }
49 51
50 static void throwNoBlobSupportException(ExceptionState& exceptionState)
51 {
52 exceptionState.throwDOMException(NotSupportedError, "Blob support not implem ented yet");
53 }
54
55 PassRefPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, Pas sOwnPtr<blink::WebRTCDataChannelHandler> handler) 52 PassRefPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, Pas sOwnPtr<blink::WebRTCDataChannelHandler> handler)
56 { 53 {
57 ASSERT(handler); 54 ASSERT(handler);
58 return adoptRef(new RTCDataChannel(context, handler)); 55 return adoptRef(new RTCDataChannel(context, handler));
59 } 56 }
60 57
61 PassRefPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, bli nk::WebRTCPeerConnectionHandler* peerConnectionHandler, const String& label, con st blink::WebRTCDataChannelInit& init, ExceptionState& exceptionState) 58 PassRefPtr<RTCDataChannel> RTCDataChannel::create(ExecutionContext* context, bli nk::WebRTCPeerConnectionHandler* peerConnectionHandler, const String& label, con st blink::WebRTCDataChannelInit& init, ExceptionState& exceptionState)
62 { 59 {
63 OwnPtr<blink::WebRTCDataChannelHandler> handler = adoptPtr(peerConnectionHan dler->createDataChannel(label, init)); 60 OwnPtr<blink::WebRTCDataChannelHandler> handler = adoptPtr(peerConnectionHan dler->createDataChannel(label, init));
64 if (!handler) { 61 if (!handler) {
65 exceptionState.throwDOMException(NotSupportedError, "RTCDataChannel is n ot supported"); 62 exceptionState.throwDOMException(NotSupportedError, "RTCDataChannel is n ot supported");
66 return nullptr; 63 return nullptr;
67 } 64 }
68 return adoptRef(new RTCDataChannel(context, handler.release())); 65 return adoptRef(new RTCDataChannel(context, handler.release()));
69 } 66 }
70 67
71 RTCDataChannel::RTCDataChannel(ExecutionContext* context, PassOwnPtr<blink::WebR TCDataChannelHandler> handler) 68 RTCDataChannel::RTCDataChannel(ExecutionContext* context, PassOwnPtr<blink::WebR TCDataChannelHandler> handler)
72 : m_executionContext(context) 69 : m_executionContext(context)
73 , m_handler(handler) 70 , m_handler(handler)
74 , m_stopped(false) 71 , m_stopped(false)
75 , m_readyState(ReadyStateConnecting) 72 , m_readyState(ReadyStateConnecting)
76 , m_binaryType(BinaryTypeArrayBuffer) 73 , m_binaryType(BinaryTypeBlob)
74 , m_blobLoaderStatus(BlobLoaderNotStarted)
77 , m_scheduledEventTimer(this, &RTCDataChannel::scheduledEventTimerFired) 75 , m_scheduledEventTimer(this, &RTCDataChannel::scheduledEventTimerFired)
78 { 76 {
79 ScriptWrappable::init(this); 77 ScriptWrappable::init(this);
80 m_handler->setClient(this); 78 m_handler->setClient(this);
81 } 79 }
82 80
83 RTCDataChannel::~RTCDataChannel() 81 RTCDataChannel::~RTCDataChannel()
84 { 82 {
85 } 83 }
86 84
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 case BinaryTypeArrayBuffer: 152 case BinaryTypeArrayBuffer:
155 return "arraybuffer"; 153 return "arraybuffer";
156 } 154 }
157 ASSERT_NOT_REACHED(); 155 ASSERT_NOT_REACHED();
158 return String(); 156 return String();
159 } 157 }
160 158
161 void RTCDataChannel::setBinaryType(const String& binaryType, ExceptionState& exc eptionState) 159 void RTCDataChannel::setBinaryType(const String& binaryType, ExceptionState& exc eptionState)
162 { 160 {
163 if (binaryType == "blob") 161 if (binaryType == "blob")
164 throwNoBlobSupportException(exceptionState); 162 m_binaryType = BinaryTypeBlob;
165 else if (binaryType == "arraybuffer") 163 else if (binaryType == "arraybuffer")
166 m_binaryType = BinaryTypeArrayBuffer; 164 m_binaryType = BinaryTypeArrayBuffer;
167 else 165 else
168 exceptionState.throwDOMException(TypeMismatchError, "Unknown binary type : " + binaryType); 166 exceptionState.throwDOMException(TypeMismatchError, "Unknown binary type : " + binaryType);
169 } 167 }
170 168
171 void RTCDataChannel::send(const String& data, ExceptionState& exceptionState) 169 void RTCDataChannel::send(const String& data, ExceptionState& exceptionState)
172 { 170 {
173 if (m_readyState != ReadyStateOpen) { 171 if (m_readyState != ReadyStateOpen) {
174 throwNotOpenException(exceptionState); 172 throwNotOpenException(exceptionState);
(...skipping 27 matching lines...) Expand all
202 void RTCDataChannel::send(PassRefPtr<ArrayBufferView> data, ExceptionState& exce ptionState) 200 void RTCDataChannel::send(PassRefPtr<ArrayBufferView> data, ExceptionState& exce ptionState)
203 { 201 {
204 if (!m_handler->sendRawData(static_cast<const char*>(data->baseAddress()), d ata->byteLength())) { 202 if (!m_handler->sendRawData(static_cast<const char*>(data->baseAddress()), d ata->byteLength())) {
205 // FIXME: This should not throw an exception but instead forcefully clos e the data channel. 203 // FIXME: This should not throw an exception but instead forcefully clos e the data channel.
206 throwCouldNotSendDataException(exceptionState); 204 throwCouldNotSendDataException(exceptionState);
207 } 205 }
208 } 206 }
209 207
210 void RTCDataChannel::send(PassRefPtrWillBeRawPtr<Blob> data, ExceptionState& exc eptionState) 208 void RTCDataChannel::send(PassRefPtrWillBeRawPtr<Blob> data, ExceptionState& exc eptionState)
211 { 209 {
212 // FIXME: implement 210 if (m_readyState != ReadyStateOpen) {
213 throwNoBlobSupportException(exceptionState); 211 throwNotOpenException(exceptionState);
212 return;
213 }
214 m_outgoingBlobQueue.append(data->blobDataHandle());
215 processOutgoingBlobQueue();
214 } 216 }
215 217
216 void RTCDataChannel::close() 218 void RTCDataChannel::close()
217 { 219 {
218 if (m_stopped) 220 if (m_stopped)
219 return; 221 return;
220 222
221 m_handler->close(); 223 m_handler->close();
222 } 224 }
223 225
(...skipping 23 matching lines...) Expand all
247 249
248 scheduleDispatchEvent(MessageEvent::create(text)); 250 scheduleDispatchEvent(MessageEvent::create(text));
249 } 251 }
250 252
251 void RTCDataChannel::didReceiveRawData(const char* data, size_t dataLength) 253 void RTCDataChannel::didReceiveRawData(const char* data, size_t dataLength)
252 { 254 {
253 if (m_stopped) 255 if (m_stopped)
254 return; 256 return;
255 257
256 if (m_binaryType == BinaryTypeBlob) { 258 if (m_binaryType == BinaryTypeBlob) {
257 // FIXME: Implement. 259 OwnPtr<BlobData> blobData = BlobData::create();
260 RefPtr<RawData> rawData = RawData::create();
261 OwnPtr<Vector<char> > binaryData = adoptPtr(new Vector<char>(dataLength) );
michaeln 2014/05/06 02:36:49 this also probably won't work well with large blob
Li Yin 2014/05/06 07:09:37 When blob is large, it needs much memory, do you m
262 memcpy(binaryData->data(), data, dataLength);
263 binaryData->swap(*rawData->mutableData());
264 blobData->appendData(rawData, 0, BlobDataItem::toEndOfFile);
265 RefPtrWillBeRawPtr<Blob> blob = Blob::create(BlobDataHandle::create(blob Data.release(), dataLength));
266 scheduleDispatchEvent(MessageEvent::create(blob.release()));
258 return; 267 return;
259 } 268 }
260 if (m_binaryType == BinaryTypeArrayBuffer) { 269 if (m_binaryType == BinaryTypeArrayBuffer) {
261 RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(data, dataLength); 270 RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(data, dataLength);
262 scheduleDispatchEvent(MessageEvent::create(buffer.release())); 271 scheduleDispatchEvent(MessageEvent::create(buffer.release()));
263 return; 272 return;
264 } 273 }
265 ASSERT_NOT_REACHED(); 274 ASSERT_NOT_REACHED();
266 } 275 }
267 276
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 WillBeHeapVector<RefPtrWillBeMember<Event> > events; 316 WillBeHeapVector<RefPtrWillBeMember<Event> > events;
308 events.swap(m_scheduledEvents); 317 events.swap(m_scheduledEvents);
309 318
310 WillBeHeapVector<RefPtrWillBeMember<Event> >::iterator it = events.begin(); 319 WillBeHeapVector<RefPtrWillBeMember<Event> >::iterator it = events.begin();
311 for (; it != events.end(); ++it) 320 for (; it != events.end(); ++it)
312 dispatchEvent((*it).release()); 321 dispatchEvent((*it).release());
313 322
314 events.clear(); 323 events.clear();
315 } 324 }
316 325
326 void RTCDataChannel::didStartLoading()
327 {
328 ASSERT(m_blobLoader);
329 ASSERT(m_blobLoaderStatus == BlobLoaderStarted);
330 }
331
332 void RTCDataChannel::didReceiveData()
333 {
334 ASSERT(m_blobLoader);
335 ASSERT(m_blobLoaderStatus == BlobLoaderStarted);
336 }
337
338 void RTCDataChannel::didFinishLoading()
339 {
340 ASSERT(m_blobLoader);
341 ASSERT(m_blobLoaderStatus == BlobLoaderStarted);
342 m_blobLoaderStatus = BlobLoaderFinished;
343 processOutgoingBlobQueue();
344 deref();
345 }
346
347 void RTCDataChannel::didFail(FileError::ErrorCode errorCode)
348 {
349 ASSERT(m_blobLoader);
350 ASSERT(m_blobLoaderStatus == BlobLoaderStarted);
351 m_blobLoader.clear();
352 m_blobLoaderStatus = BlobLoaderFailed;
353 close();
354 deref();
355 }
356
357 void RTCDataChannel::processOutgoingBlobQueue()
358 {
359 while (!m_outgoingBlobQueue.isEmpty()) {
360 RefPtr<BlobDataHandle> blobDataHandle = m_outgoingBlobQueue.takeFirst();
361 switch (m_blobLoaderStatus) {
362 case BlobLoaderNotStarted:
363 ref(); // Will be derefed after didFinishLoading() or didFail().
364 ASSERT(!m_blobLoader);
365 m_blobLoader = adoptPtr(new FileReaderLoader(FileReaderLoader::ReadA sArrayBuffer, this));
366 m_blobLoaderStatus = BlobLoaderStarted;
367 m_blobLoader->start(m_executionContext, blobDataHandle.get());
368 m_outgoingBlobQueue.prepend(blobDataHandle.release());
369 return;
370
371 case BlobLoaderStarted:
372 case BlobLoaderFailed:
373 m_outgoingBlobQueue.prepend(blobDataHandle.release());
374 return;
375
376 case BlobLoaderFinished: {
377 RefPtr<ArrayBuffer> result = m_blobLoader->arrayBufferResult();
michaeln 2014/05/06 02:36:49 this probably won't work well with large blobs, ha
Li Yin 2014/05/06 07:09:37 Yeah, your concern looks reasonable, but unfortuna
378 m_blobLoader.clear();
379 m_blobLoaderStatus = BlobLoaderNotStarted;
380 if (!m_handler->sendRawData(static_cast<const char*>(result->data()) , result->byteLength())) {
381 // FIXME: This should forcefully close the data channel.
382 return;
383 }
384 break;
385 }
386 }
387 }
388 }
389
317 } // namespace WebCore 390 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/modules/mediastream/RTCDataChannel.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698