Index: third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp |
diff --git a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp |
index 854a5babc9d35c6b9a4521f59b7bde8c605c4088..9321257fa3a73a2fa6c376dc58ebb81b790bc32f 100644 |
--- a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp |
+++ b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp |
@@ -35,10 +35,15 @@ |
#include "bindings/core/v8/ExceptionState.h" |
#include "bindings/core/v8/Nullable.h" |
#include "bindings/core/v8/ScriptPromiseResolver.h" |
+#include "bindings/core/v8/ScriptState.h" |
+#include "bindings/core/v8/ScriptValue.h" |
+#include "bindings/core/v8/V8ThrowException.h" |
+#include "bindings/modules/v8/UnionTypesModules.h" |
#include "bindings/modules/v8/V8RTCCertificate.h" |
#include "core/dom/Document.h" |
#include "core/dom/ExceptionCode.h" |
#include "core/dom/ExecutionContext.h" |
+#include "core/dom/Microtask.h" |
#include "core/frame/LocalFrame.h" |
#include "core/frame/UseCounter.h" |
#include "core/html/VoidCallback.h" |
@@ -54,10 +59,13 @@ |
#include "modules/mediastream/RTCIceCandidateEvent.h" |
#include "modules/mediastream/RTCSessionDescription.h" |
#include "modules/mediastream/RTCSessionDescriptionCallback.h" |
+#include "modules/mediastream/RTCSessionDescriptionInit.h" |
#include "modules/mediastream/RTCSessionDescriptionRequestImpl.h" |
#include "modules/mediastream/RTCStatsCallback.h" |
#include "modules/mediastream/RTCStatsRequestImpl.h" |
#include "modules/mediastream/RTCVoidRequestImpl.h" |
+#include "modules/mediastream/RTCVoidRequestPromiseImpl.h" |
+#include "platform/Timer.h" |
philipj_slow
2016/02/11 14:31:01
platform/Timer.h no longer needed?
Guido Urdaneta
2016/02/11 20:00:05
Done.
|
#include "platform/mediastream/RTCConfiguration.h" |
#include "platform/mediastream/RTCOfferOptions.h" |
#include "public/platform/Platform.h" |
@@ -81,16 +89,60 @@ namespace blink { |
namespace { |
-static bool throwExceptionIfSignalingStateClosed(RTCPeerConnection::SignalingState state, ExceptionState& exceptionState) |
+const char kSignalingStateClosedMsg[] = "The RTCPeerConnection's signalingState is 'closed'."; |
+const char kDefaultErrorName[] = "AbortError"; |
philipj_slow
2016/02/11 14:31:01
See comment about DOMException and ExceptionCode,
Guido Urdaneta
2016/02/11 17:00:13
Done.
|
+const char kSessionDescriptionErrorName[] = "InvalidSessionDescription"; |
+ |
+bool throwExceptionIfSignalingStateClosed(RTCPeerConnection::SignalingState state, ExceptionState& exceptionState) |
+{ |
+ if (state == RTCPeerConnection::SignalingStateClosed) { |
+ exceptionState.throwDOMException(InvalidStateError, kSignalingStateClosedMsg); |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
+ |
+void asyncCallErrorCallback(RTCErrorCallback* errorCallback, const String& errorMsg) |
+{ |
+ Microtask::enqueueMicrotask(WTF::bind(&RTCErrorCallback::handleEvent, errorCallback, errorMsg)); |
philipj_slow
2016/02/11 14:31:01
I think this probably will not keep the RTCErrorCa
Guido Urdaneta
2016/02/11 17:00:13
I think you are right. Rewritten using a Task that
|
+} |
+ |
+bool callErrorCallbackIfSignalingStateClosed(RTCPeerConnection::SignalingState state, RTCErrorCallback* errorCallback) |
{ |
if (state == RTCPeerConnection::SignalingStateClosed) { |
- exceptionState.throwDOMException(InvalidStateError, "The RTCPeerConnection's signalingState is 'closed'."); |
+ if (errorCallback) |
+ asyncCallErrorCallback(errorCallback, kSignalingStateClosedMsg); |
+ |
return true; |
} |
return false; |
} |
+bool isIceCandidateMissingSdp(const RTCIceCandidateInitOrRTCIceCandidate& candidate) |
+{ |
+ if (candidate.isRTCIceCandidateInit()) { |
+ const RTCIceCandidateInit& iceCandidateInit = candidate.getAsRTCIceCandidateInit(); |
+ return !iceCandidateInit.hasSdpMid() && !iceCandidateInit.hasSdpMLineIndex(); |
+ } |
+ |
+ ASSERT(candidate.isRTCIceCandidate()); |
+ return false; |
+} |
+ |
+WebRTCICECandidate convertToWebRTCIceCandidate(const RTCIceCandidateInitOrRTCIceCandidate& candidate) |
+{ |
+ if (candidate.isRTCIceCandidateInit()) { |
+ const RTCIceCandidateInit& iceCandidateInit = candidate.getAsRTCIceCandidateInit(); |
+ return WebRTCICECandidate(iceCandidateInit.candidate(), iceCandidateInit.sdpMid(), iceCandidateInit.sdpMLineIndex()); |
+ } |
+ |
+ ASSERT(candidate.isRTCIceCandidate()); |
+ return candidate.getAsRTCIceCandidate()->webCandidate(); |
+} |
+ |
// Helper class for RTCPeerConnection::generateCertificate. |
class WebRTCCertificateObserver : public WebCallbacks<WebRTCCertificate*, void> { |
public: |
@@ -460,8 +512,21 @@ void RTCPeerConnection::createAnswer(ExecutionContext* context, RTCSessionDescri |
m_peerHandler->createAnswer(request, constraints); |
} |
-void RTCPeerConnection::setLocalDescription(ExecutionContext* context, RTCSessionDescription* sessionDescription, VoidCallback* successCallback, RTCErrorCallback* errorCallback, ExceptionState& exceptionState) |
+ScriptPromise RTCPeerConnection::setLocalDescription(ScriptState* scriptState, const RTCSessionDescriptionInit& sessionDescriptionInit) |
{ |
+ if (m_signalingState == SignalingStateClosed) |
+ return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, kSignalingStateClosedMsg)); |
+ |
+ ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
+ ScriptPromise promise = resolver->promise(); |
+ RTCVoidRequest* request = RTCVoidRequestPromiseImpl::create(this, resolver, kSessionDescriptionErrorName); |
+ m_peerHandler->setLocalDescription(request, WebRTCSessionDescription(sessionDescriptionInit.type(), sessionDescriptionInit.sdp())); |
+ return promise; |
+} |
+ |
+ScriptPromise RTCPeerConnection::setLocalDescription(ScriptState* scriptState, RTCSessionDescription* sessionDescription, VoidCallback* successCallback, RTCErrorCallback* errorCallback) |
+{ |
+ ExecutionContext* context = scriptState->executionContext(); |
if (successCallback && errorCallback) { |
UseCounter::count(context, UseCounter::RTCPeerConnectionSetLocalDescriptionLegacyCompliant); |
} else { |
@@ -471,13 +536,14 @@ void RTCPeerConnection::setLocalDescription(ExecutionContext* context, RTCSessio |
UseCounter::count(context, UseCounter::RTCPeerConnectionSetLocalDescriptionLegacyNoFailureCallback); |
} |
- if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) |
- return; |
+ if (callErrorCallbackIfSignalingStateClosed(m_signalingState, errorCallback)) |
+ return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate())); |
ASSERT(sessionDescription); |
RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), this, successCallback, errorCallback); |
m_peerHandler->setLocalDescription(request, sessionDescription->webSessionDescription()); |
+ return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate())); |
} |
RTCSessionDescription* RTCPeerConnection::localDescription() |
@@ -489,8 +555,21 @@ RTCSessionDescription* RTCPeerConnection::localDescription() |
return RTCSessionDescription::create(webSessionDescription); |
} |
-void RTCPeerConnection::setRemoteDescription(ExecutionContext* context, RTCSessionDescription* sessionDescription, VoidCallback* successCallback, RTCErrorCallback* errorCallback, ExceptionState& exceptionState) |
+ScriptPromise RTCPeerConnection::setRemoteDescription(ScriptState* scriptState, const RTCSessionDescriptionInit& sessionDescriptionInit) |
{ |
+ if (m_signalingState == SignalingStateClosed) |
+ return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, kSignalingStateClosedMsg)); |
+ |
+ ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
+ ScriptPromise promise = resolver->promise(); |
+ RTCVoidRequest* request = RTCVoidRequestPromiseImpl::create(this, resolver, kSessionDescriptionErrorName); |
+ m_peerHandler->setRemoteDescription(request, WebRTCSessionDescription(sessionDescriptionInit.type(), sessionDescriptionInit.sdp())); |
+ return promise; |
+} |
+ |
+ScriptPromise RTCPeerConnection::setRemoteDescription(ScriptState* scriptState, RTCSessionDescription* sessionDescription, VoidCallback* successCallback, RTCErrorCallback* errorCallback) |
+{ |
+ ExecutionContext* context = scriptState->executionContext(); |
if (successCallback && errorCallback) { |
UseCounter::count(context, UseCounter::RTCPeerConnectionSetRemoteDescriptionLegacyCompliant); |
} else { |
@@ -500,13 +579,14 @@ void RTCPeerConnection::setRemoteDescription(ExecutionContext* context, RTCSessi |
UseCounter::count(context, UseCounter::RTCPeerConnectionSetRemoteDescriptionLegacyNoFailureCallback); |
} |
- if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) |
- return; |
+ if (callErrorCallbackIfSignalingStateClosed(m_signalingState, errorCallback)) |
+ return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate())); |
ASSERT(sessionDescription); |
RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), this, successCallback, errorCallback); |
m_peerHandler->setRemoteDescription(request, sessionDescription->webSessionDescription()); |
+ return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate())); |
} |
RTCSessionDescription* RTCPeerConnection::remoteDescription() |
@@ -608,33 +688,41 @@ ScriptPromise RTCPeerConnection::generateCertificate(ScriptState* scriptState, c |
return promise; |
} |
-void RTCPeerConnection::addIceCandidate(RTCIceCandidate* iceCandidate, ExceptionState& exceptionState) |
+ScriptPromise RTCPeerConnection::addIceCandidate(ScriptState* scriptState, const RTCIceCandidateInitOrRTCIceCandidate& candidate) |
{ |
- if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) |
- return; |
+ if (m_signalingState == SignalingStateClosed) |
+ return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, kSignalingStateClosedMsg)); |
- ASSERT(iceCandidate); |
+ if (isIceCandidateMissingSdp(candidate)) |
+ return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Candidate missing values for both sdpMid and sdpMLineIndex")); |
- bool valid = m_peerHandler->addICECandidate(iceCandidate->webCandidate()); |
- if (!valid) |
- exceptionState.throwDOMException(SyntaxError, "The ICE candidate could not be added."); |
+ ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
+ ScriptPromise promise = resolver->promise(); |
+ RTCVoidRequest* request = RTCVoidRequestPromiseImpl::create(this, resolver, kDefaultErrorName); |
+ WebRTCICECandidate webCandidate = convertToWebRTCIceCandidate(candidate); |
+ bool implemented = m_peerHandler->addICECandidate(request, webCandidate); |
+ // TODO(guidou): replace NotSupportedError when error handling in the spec is finalized. crbug.com/585621 |
+ if (!implemented) |
+ resolver->reject(DOMException::create(NotSupportedError, "This method is not yet implemented.")); |
+ |
+ return promise; |
} |
-void RTCPeerConnection::addIceCandidate(RTCIceCandidate* iceCandidate, VoidCallback* successCallback, RTCErrorCallback* errorCallback, ExceptionState& exceptionState) |
+ScriptPromise RTCPeerConnection::addIceCandidate(ScriptState* scriptState, RTCIceCandidate* iceCandidate, VoidCallback* successCallback, RTCErrorCallback* errorCallback) |
{ |
- if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) |
- return; |
- |
ASSERT(iceCandidate); |
ASSERT(successCallback); |
ASSERT(errorCallback); |
- RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), this, successCallback, errorCallback); |
+ if (callErrorCallbackIfSignalingStateClosed(m_signalingState, errorCallback)) |
+ return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate())); |
+ RTCVoidRequest* request = RTCVoidRequestImpl::create(executionContext(), this, successCallback, errorCallback); |
bool implemented = m_peerHandler->addICECandidate(request, iceCandidate->webCandidate()); |
- if (!implemented) { |
- exceptionState.throwDOMException(NotSupportedError, "This method is not yet implemented."); |
- } |
+ if (!implemented) |
+ asyncCallErrorCallback(errorCallback, "This method is not yet implemented."); |
+ |
+ return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate())); |
} |
String RTCPeerConnection::signalingState() const |