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 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 RTCPeerConnection* peerConnection = new RTCPeerConnection(context, configura
tion, constraints, exceptionState); | 234 RTCPeerConnection* peerConnection = new RTCPeerConnection(context, configura
tion, constraints, exceptionState); |
235 peerConnection->suspendIfNeeded(); | 235 peerConnection->suspendIfNeeded(); |
236 if (exceptionState.hadException()) | 236 if (exceptionState.hadException()) |
237 return 0; | 237 return 0; |
238 | 238 |
239 return peerConnection; | 239 return peerConnection; |
240 } | 240 } |
241 | 241 |
242 RTCPeerConnection::RTCPeerConnection(ExecutionContext* context, RTCConfiguration
* configuration, WebMediaConstraints constraints, ExceptionState& exceptionState
) | 242 RTCPeerConnection::RTCPeerConnection(ExecutionContext* context, RTCConfiguration
* configuration, WebMediaConstraints constraints, ExceptionState& exceptionState
) |
243 : ActiveDOMObject(context) | 243 : ActiveDOMObject(context) |
| 244 , m_pendingLocalDescription(nullptr) |
| 245 , m_pendingRemoteDescription(nullptr) |
244 , m_signalingState(SignalingStateStable) | 246 , m_signalingState(SignalingStateStable) |
245 , m_iceGatheringState(ICEGatheringStateNew) | 247 , m_iceGatheringState(ICEGatheringStateNew) |
246 , m_iceConnectionState(ICEConnectionStateNew) | 248 , m_iceConnectionState(ICEConnectionStateNew) |
247 , m_dispatchScheduledEventRunner(this, &RTCPeerConnection::dispatchScheduled
Event) | 249 , m_dispatchScheduledEventRunner(this, &RTCPeerConnection::dispatchScheduled
Event) |
248 , m_stopped(false) | 250 , m_stopped(false) |
249 , m_closed(false) | 251 , m_closed(false) |
250 { | 252 { |
251 Document* document = toDocument(executionContext()); | 253 Document* document = toDocument(executionContext()); |
252 | 254 |
253 // If we fail, set |m_closed| and |m_stopped| to true, to avoid hitting the
assert in the destructor. | 255 // If we fail, set |m_closed| and |m_stopped| to true, to avoid hitting the
assert in the destructor. |
(...skipping 14 matching lines...) Expand all Loading... |
268 } | 270 } |
269 | 271 |
270 document->frame()->loader().client()->dispatchWillStartUsingPeerConnectionHa
ndler(m_peerHandler.get()); | 272 document->frame()->loader().client()->dispatchWillStartUsingPeerConnectionHa
ndler(m_peerHandler.get()); |
271 | 273 |
272 if (!m_peerHandler->initialize(configuration, constraints)) { | 274 if (!m_peerHandler->initialize(configuration, constraints)) { |
273 m_closed = true; | 275 m_closed = true; |
274 m_stopped = true; | 276 m_stopped = true; |
275 exceptionState.throwDOMException(NotSupportedError, "Failed to initializ
e native PeerConnection."); | 277 exceptionState.throwDOMException(NotSupportedError, "Failed to initializ
e native PeerConnection."); |
276 return; | 278 return; |
277 } | 279 } |
| 280 m_localDescription = RTCSessionDescription::create(m_peerHandler->localDescr
iption()); |
| 281 m_remoteDescription = RTCSessionDescription::create(m_peerHandler->remoteDes
cription()); |
278 } | 282 } |
279 | 283 |
280 RTCPeerConnection::~RTCPeerConnection() | 284 RTCPeerConnection::~RTCPeerConnection() |
281 { | 285 { |
282 // This checks that close() or stop() is called before the destructor. | 286 // This checks that close() or stop() is called before the destructor. |
283 // We are assuming that a wrapper is always created when RTCPeerConnection i
s created. | 287 // We are assuming that a wrapper is always created when RTCPeerConnection i
s created. |
284 ASSERT(m_closed || m_stopped); | 288 ASSERT(m_closed || m_stopped); |
285 } | 289 } |
286 | 290 |
287 void RTCPeerConnection::createOffer(RTCSessionDescriptionCallback* successCallba
ck, RTCErrorCallback* errorCallback, const Dictionary& rtcOfferOptions, Exceptio
nState& exceptionState) | 291 void RTCPeerConnection::createOffer(RTCSessionDescriptionCallback* successCallba
ck, RTCErrorCallback* errorCallback, const Dictionary& rtcOfferOptions, Exceptio
nState& exceptionState) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 void RTCPeerConnection::setLocalDescription(RTCSessionDescription* sessionDescri
ption, VoidCallback* successCallback, RTCErrorCallback* errorCallback, Exception
State& exceptionState) | 330 void RTCPeerConnection::setLocalDescription(RTCSessionDescription* sessionDescri
ption, VoidCallback* successCallback, RTCErrorCallback* errorCallback, Exception
State& exceptionState) |
327 { | 331 { |
328 if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) | 332 if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) |
329 return; | 333 return; |
330 | 334 |
331 if (!sessionDescription) { | 335 if (!sessionDescription) { |
332 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "RTCSessionDescription")); | 336 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "RTCSessionDescription")); |
333 return; | 337 return; |
334 } | 338 } |
335 | 339 |
336 RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), thi
s, successCallback, errorCallback); | 340 RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), thi
s, successCallback, errorCallback, RTCVoidRequestImpl::RequestTypeLocal); |
337 m_peerHandler->setLocalDescription(request, sessionDescription->webSessionDe
scription()); | 341 m_peerHandler->setLocalDescription(request, sessionDescription->webSessionDe
scription()); |
| 342 m_pendingLocalDescription = sessionDescription; |
338 } | 343 } |
339 | 344 |
340 RTCSessionDescription* RTCPeerConnection::localDescription(ExceptionState& excep
tionState) | 345 RTCSessionDescription* RTCPeerConnection::localDescription() |
341 { | 346 { |
| 347 if (!m_peerHandler) |
| 348 return nullptr; |
342 WebRTCSessionDescription webSessionDescription = m_peerHandler->localDescrip
tion(); | 349 WebRTCSessionDescription webSessionDescription = m_peerHandler->localDescrip
tion(); |
343 if (webSessionDescription.isNull()) | 350 if (webSessionDescription.isNull()) |
344 return nullptr; | 351 return nullptr; |
345 | 352 |
346 return RTCSessionDescription::create(webSessionDescription); | 353 if (!m_localDescription || m_localDescription->webSessionDescription().isNul
l() |
| 354 || m_localDescription->webSessionDescription() != webSessionDescription)
{ |
| 355 m_localDescription = RTCSessionDescription::create(webSessionDescription
); |
| 356 } |
| 357 |
| 358 return m_localDescription; |
347 } | 359 } |
348 | 360 |
349 void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* sessionDescr
iption, VoidCallback* successCallback, RTCErrorCallback* errorCallback, Exceptio
nState& exceptionState) | 361 void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* sessionDescr
iption, VoidCallback* successCallback, RTCErrorCallback* errorCallback, Exceptio
nState& exceptionState) |
350 { | 362 { |
351 if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) | 363 if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) |
352 return; | 364 return; |
353 | 365 |
354 if (!sessionDescription) { | 366 if (!sessionDescription) { |
355 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "RTCSessionDescription")); | 367 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "RTCSessionDescription")); |
356 return; | 368 return; |
357 } | 369 } |
358 | 370 |
359 RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), thi
s, successCallback, errorCallback); | 371 RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), thi
s, successCallback, errorCallback, RTCVoidRequestImpl::RequestTypeRemote); |
360 m_peerHandler->setRemoteDescription(request, sessionDescription->webSessionD
escription()); | 372 m_peerHandler->setRemoteDescription(request, sessionDescription->webSessionD
escription()); |
| 373 m_pendingRemoteDescription = sessionDescription; |
361 } | 374 } |
362 | 375 |
363 RTCSessionDescription* RTCPeerConnection::remoteDescription(ExceptionState& exce
ptionState) | 376 RTCSessionDescription* RTCPeerConnection::remoteDescription() |
364 { | 377 { |
| 378 if (!m_peerHandler) |
| 379 return nullptr; |
365 WebRTCSessionDescription webSessionDescription = m_peerHandler->remoteDescri
ption(); | 380 WebRTCSessionDescription webSessionDescription = m_peerHandler->remoteDescri
ption(); |
366 if (webSessionDescription.isNull()) | 381 if (webSessionDescription.isNull()) |
367 return nullptr; | 382 return nullptr; |
368 | 383 |
369 return RTCSessionDescription::create(webSessionDescription); | 384 if (!m_remoteDescription || m_remoteDescription->webSessionDescription().isN
ull() |
| 385 || m_remoteDescription->webSessionDescription() != webSessionDescription
) { |
| 386 m_remoteDescription = RTCSessionDescription::create(webSessionDescriptio
n); |
| 387 } |
| 388 |
| 389 return m_remoteDescription; |
370 } | 390 } |
371 | 391 |
372 void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, const Dict
ionary& mediaConstraints, ExceptionState& exceptionState) | 392 void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, const Dict
ionary& mediaConstraints, ExceptionState& exceptionState) |
373 { | 393 { |
374 if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) | 394 if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) |
375 return; | 395 return; |
376 | 396 |
377 RTCConfiguration* configuration = parseConfiguration(rtcConfiguration, excep
tionState); | 397 RTCConfiguration* configuration = parseConfiguration(rtcConfiguration, excep
tionState); |
378 if (exceptionState.hadException()) | 398 if (exceptionState.hadException()) |
379 return; | 399 return; |
(...skipping 27 matching lines...) Expand all Loading... |
407 if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) | 427 if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) |
408 return; | 428 return; |
409 | 429 |
410 if (!iceCandidate) { | 430 if (!iceCandidate) { |
411 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "RTCIceCandidate")); | 431 exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "RTCIceCandidate")); |
412 return; | 432 return; |
413 } | 433 } |
414 ASSERT(successCallback); | 434 ASSERT(successCallback); |
415 ASSERT(errorCallback); | 435 ASSERT(errorCallback); |
416 | 436 |
417 RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), thi
s, successCallback, errorCallback); | 437 RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), thi
s, successCallback, errorCallback, RTCVoidRequestImpl::RequestTypeNone); |
418 | 438 |
419 bool implemented = m_peerHandler->addICECandidate(request, iceCandidate->web
Candidate()); | 439 bool implemented = m_peerHandler->addICECandidate(request, iceCandidate->web
Candidate()); |
420 if (!implemented) { | 440 if (!implemented) { |
421 exceptionState.throwDOMException(NotSupportedError, "This method is not
yet implemented."); | 441 exceptionState.throwDOMException(NotSupportedError, "This method is not
yet implemented."); |
422 } | 442 } |
423 } | 443 } |
424 | 444 |
425 String RTCPeerConnection::signalingState() const | 445 String RTCPeerConnection::signalingState() const |
426 { | 446 { |
427 switch (m_signalingState) { | 447 switch (m_signalingState) { |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 } | 640 } |
621 | 641 |
622 void RTCPeerConnection::close(ExceptionState& exceptionState) | 642 void RTCPeerConnection::close(ExceptionState& exceptionState) |
623 { | 643 { |
624 if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) | 644 if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) |
625 return; | 645 return; |
626 | 646 |
627 closeInternal(); | 647 closeInternal(); |
628 } | 648 } |
629 | 649 |
| 650 void RTCPeerConnection::requestSucceeded(RTCVoidRequestImpl::RequestType request
Type) |
| 651 { |
| 652 if (requestType == RTCVoidRequestImpl::RequestTypeLocal) { |
| 653 commitPendingLocalSessionDescription(); |
| 654 } else if (requestType == RTCVoidRequestImpl::RequestTypeRemote) { |
| 655 commitPendingRemoteSessionDescription(); |
| 656 } |
| 657 } |
| 658 |
630 void RTCPeerConnection::negotiationNeeded() | 659 void RTCPeerConnection::negotiationNeeded() |
631 { | 660 { |
632 ASSERT(!m_closed); | 661 ASSERT(!m_closed); |
633 scheduleDispatchEvent(Event::create(EventTypeNames::negotiationneeded)); | 662 scheduleDispatchEvent(Event::create(EventTypeNames::negotiationneeded)); |
634 } | 663 } |
635 | 664 |
636 void RTCPeerConnection::didGenerateICECandidate(const WebRTCICECandidate& webCan
didate) | 665 void RTCPeerConnection::didGenerateICECandidate(const WebRTCICECandidate& webCan
didate) |
637 { | 666 { |
638 ASSERT(!m_closed); | 667 ASSERT(!m_closed); |
639 ASSERT(executionContext()->isContextThread()); | 668 ASSERT(executionContext()->isContextThread()); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 { | 819 { |
791 ASSERT(m_signalingState != RTCPeerConnection::SignalingStateClosed); | 820 ASSERT(m_signalingState != RTCPeerConnection::SignalingStateClosed); |
792 m_peerHandler->stop(); | 821 m_peerHandler->stop(); |
793 m_closed = true; | 822 m_closed = true; |
794 | 823 |
795 changeIceConnectionState(ICEConnectionStateClosed); | 824 changeIceConnectionState(ICEConnectionStateClosed); |
796 changeIceGatheringState(ICEGatheringStateComplete); | 825 changeIceGatheringState(ICEGatheringStateComplete); |
797 changeSignalingState(SignalingStateClosed); | 826 changeSignalingState(SignalingStateClosed); |
798 } | 827 } |
799 | 828 |
| 829 void RTCPeerConnection::commitPendingLocalSessionDescription() |
| 830 { |
| 831 m_localDescription = m_pendingLocalDescription; |
| 832 } |
| 833 |
| 834 void RTCPeerConnection::commitPendingRemoteSessionDescription() |
| 835 { |
| 836 m_remoteDescription = m_pendingRemoteDescription; |
| 837 } |
| 838 |
800 void RTCPeerConnection::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> even
t) | 839 void RTCPeerConnection::scheduleDispatchEvent(PassRefPtrWillBeRawPtr<Event> even
t) |
801 { | 840 { |
802 m_scheduledEvents.append(event); | 841 m_scheduledEvents.append(event); |
803 | 842 |
804 m_dispatchScheduledEventRunner.runAsync(); | 843 m_dispatchScheduledEventRunner.runAsync(); |
805 } | 844 } |
806 | 845 |
807 void RTCPeerConnection::dispatchScheduledEvent() | 846 void RTCPeerConnection::dispatchScheduledEvent() |
808 { | 847 { |
809 if (m_stopped) | 848 if (m_stopped) |
810 return; | 849 return; |
811 | 850 |
812 WillBeHeapVector<RefPtrWillBeMember<Event>> events; | 851 WillBeHeapVector<RefPtrWillBeMember<Event>> events; |
813 events.swap(m_scheduledEvents); | 852 events.swap(m_scheduledEvents); |
814 | 853 |
815 WillBeHeapVector<RefPtrWillBeMember<Event>>::iterator it = events.begin(); | 854 WillBeHeapVector<RefPtrWillBeMember<Event>>::iterator it = events.begin(); |
816 for (; it != events.end(); ++it) | 855 for (; it != events.end(); ++it) |
817 dispatchEvent((*it).release()); | 856 dispatchEvent((*it).release()); |
818 | 857 |
819 events.clear(); | 858 events.clear(); |
820 } | 859 } |
821 | 860 |
822 DEFINE_TRACE(RTCPeerConnection) | 861 DEFINE_TRACE(RTCPeerConnection) |
823 { | 862 { |
824 visitor->trace(m_localStreams); | 863 visitor->trace(m_localStreams); |
825 visitor->trace(m_remoteStreams); | 864 visitor->trace(m_remoteStreams); |
826 visitor->trace(m_dataChannels); | 865 visitor->trace(m_dataChannels); |
| 866 visitor->trace(m_localDescription); |
| 867 visitor->trace(m_remoteDescription); |
| 868 visitor->trace(m_pendingLocalDescription); |
| 869 visitor->trace(m_pendingRemoteDescription); |
827 #if ENABLE(OILPAN) | 870 #if ENABLE(OILPAN) |
828 visitor->trace(m_scheduledEvents); | 871 visitor->trace(m_scheduledEvents); |
829 #endif | 872 #endif |
830 RefCountedGarbageCollectedEventTargetWithInlineData<RTCPeerConnection>::trac
e(visitor); | 873 RefCountedGarbageCollectedEventTargetWithInlineData<RTCPeerConnection>::trac
e(visitor); |
831 ActiveDOMObject::trace(visitor); | 874 ActiveDOMObject::trace(visitor); |
832 } | 875 } |
833 | 876 |
834 } // namespace blink | 877 } // namespace blink |
OLD | NEW |