*/
#include "config.h"
-
#include "modules/mediastream/RTCPeerConnection.h"
-#include "bindings/v8/ArrayValue.h"
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
+#include "bindings/core/v8/ArrayValue.h"
+#include "bindings/core/v8/ExceptionMessages.h"
+#include "bindings/core/v8/ExceptionState.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
#include "modules/mediastream/RTCStatsRequestImpl.h"
#include "modules/mediastream/RTCVoidRequestImpl.h"
#include "platform/mediastream/RTCConfiguration.h"
+#include "platform/mediastream/RTCOfferOptions.h"
#include "public/platform/Platform.h"
#include "public/platform/WebMediaStream.h"
#include "public/platform/WebRTCConfiguration.h"
#include "public/platform/WebRTCDataChannelHandler.h"
#include "public/platform/WebRTCDataChannelInit.h"
#include "public/platform/WebRTCICECandidate.h"
+#include "public/platform/WebRTCOfferOptions.h"
#include "public/platform/WebRTCSessionDescription.h"
#include "public/platform/WebRTCSessionDescriptionRequest.h"
#include "public/platform/WebRTCStatsRequest.h"
#include "public/platform/WebRTCVoidRequest.h"
-namespace WebCore {
+namespace blink {
namespace {
if (configuration.isUndefinedOrNull())
return nullptr;
+ RTCIceTransports iceTransports = RTCIceTransportsAll;
+ String iceTransportsString;
+ if (DictionaryHelper::get(configuration, "iceTransports", iceTransportsString)) {
+ if (iceTransportsString == "none") {
+ iceTransports = RTCIceTransportsNone;
+ } else if (iceTransportsString == "relay") {
+ iceTransports = RTCIceTransportsRelay;
+ } else if (iceTransportsString != "all") {
+ exceptionState.throwTypeError("Malformed RTCIceTransports");
+ return nullptr;
+ }
+ }
+
ArrayValue iceServers;
- bool ok = configuration.get("iceServers", iceServers);
+ bool ok = DictionaryHelper::get(configuration, "iceServers", iceServers);
if (!ok || iceServers.isUndefinedOrNull()) {
exceptionState.throwTypeError("Malformed RTCConfiguration");
return nullptr;
}
RefPtr<RTCConfiguration> rtcConfiguration = RTCConfiguration::create();
+ rtcConfiguration->setIceTransports(iceTransports);
for (size_t i = 0; i < numberOfServers; ++i) {
Dictionary iceServer;
Vector<String> urlStrings;
if (names.contains("urls")) {
- if (!iceServer.get("urls", urlStrings) || !urlStrings.size()) {
+ if (!DictionaryHelper::get(iceServer, "urls", urlStrings) || !urlStrings.size()) {
String urlString;
- if (iceServer.get("urls", urlString)) {
+ if (DictionaryHelper::get(iceServer, "urls", urlString)) {
urlStrings.append(urlString);
} else {
exceptionState.throwTypeError("Malformed RTCIceServer");
}
} else if (names.contains("url")) {
String urlString;
- if (iceServer.get("url", urlString)) {
+ if (DictionaryHelper::get(iceServer, "url", urlString)) {
urlStrings.append(urlString);
} else {
exceptionState.throwTypeError("Malformed RTCIceServer");
}
String username, credential;
- iceServer.get("username", username);
- iceServer.get("credential", credential);
+ DictionaryHelper::get(iceServer, "username", username);
+ DictionaryHelper::get(iceServer, "credential", credential);
for (Vector<String>::iterator iter = urlStrings.begin(); iter != urlStrings.end(); ++iter) {
KURL url(KURL(), *iter);
return rtcConfiguration.release();
}
-PassRefPtrWillBeRawPtr<RTCPeerConnection> RTCPeerConnection::create(ExecutionContext* context, const Dictionary& rtcConfiguration, const Dictionary& mediaConstraints, ExceptionState& exceptionState)
+PassRefPtr<RTCOfferOptions> RTCPeerConnection::parseOfferOptions(const Dictionary& options, ExceptionState& exceptionState)
+{
+ if (options.isUndefinedOrNull())
+ return nullptr;
+
+ Vector<String> propertyNames;
+ options.getOwnPropertyNames(propertyNames);
+
+ // Treat |options| as MediaConstraints if it is empty or has "optional" or "mandatory" properties for compatibility.
+ // TODO(jiayl): remove constraints when RTCOfferOptions reaches Stable and client code is ready.
+ if (propertyNames.isEmpty() || propertyNames.contains("optional") || propertyNames.contains("mandatory"))
+ return nullptr;
+
+ int32_t offerToReceiveVideo = -1;
+ int32_t offerToReceiveAudio = -1;
+ bool voiceActivityDetection = true;
+ bool iceRestart = false;
+
+ if (DictionaryHelper::get(options, "offerToReceiveVideo", offerToReceiveVideo) && offerToReceiveVideo < 0) {
+ exceptionState.throwTypeError("Invalid offerToReceiveVideo");
+ return nullptr;
+ }
+
+ if (DictionaryHelper::get(options, "offerToReceiveAudio", offerToReceiveAudio) && offerToReceiveAudio < 0) {
+ exceptionState.throwTypeError("Invalid offerToReceiveAudio");
+ return nullptr;
+ }
+
+ DictionaryHelper::get(options, "voiceActivityDetection", voiceActivityDetection);
+ DictionaryHelper::get(options, "iceRestart", iceRestart);
+
+ RefPtr<RTCOfferOptions> rtcOfferOptions = RTCOfferOptions::create(offerToReceiveVideo, offerToReceiveAudio, voiceActivityDetection, iceRestart);
+ return rtcOfferOptions.release();
+}
+
+RTCPeerConnection* RTCPeerConnection::create(ExecutionContext* context, const Dictionary& rtcConfiguration, const Dictionary& mediaConstraints, ExceptionState& exceptionState)
{
RefPtr<RTCConfiguration> configuration = parseConfiguration(rtcConfiguration, exceptionState);
if (exceptionState.hadException())
return nullptr;
- blink::WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
+ WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
if (exceptionState.hadException())
return nullptr;
- RefPtrWillBeRawPtr<RTCPeerConnection> peerConnection = adoptRefWillBeRefCountedGarbageCollected(new RTCPeerConnection(context, configuration.release(), constraints, exceptionState));
+ RTCPeerConnection* peerConnection = adoptRefCountedGarbageCollectedWillBeNoop(new RTCPeerConnection(context, configuration.release(), constraints, exceptionState));
peerConnection->suspendIfNeeded();
if (exceptionState.hadException())
return nullptr;
- return peerConnection.release();
+ return peerConnection;
}
-RTCPeerConnection::RTCPeerConnection(ExecutionContext* context, PassRefPtr<RTCConfiguration> configuration, blink::WebMediaConstraints constraints, ExceptionState& exceptionState)
+RTCPeerConnection::RTCPeerConnection(ExecutionContext* context, PassRefPtr<RTCConfiguration> configuration, WebMediaConstraints constraints, ExceptionState& exceptionState)
: ActiveDOMObject(context)
, m_signalingState(SignalingStateStable)
, m_iceGatheringState(ICEGatheringStateNew)
return;
}
- m_peerHandler = adoptPtr(blink::Platform::current()->createRTCPeerConnectionHandler(this));
+ m_peerHandler = adoptPtr(Platform::current()->createRTCPeerConnectionHandler(this));
if (!m_peerHandler) {
m_closed = true;
m_stopped = true;
// This checks that close() or stop() is called before the destructor.
// We are assuming that a wrapper is always created when RTCPeerConnection is created.
ASSERT(m_closed || m_stopped);
-
-#if !ENABLE(OILPAN)
- stop();
-#endif
}
-void RTCPeerConnection::createOffer(PassOwnPtr<RTCSessionDescriptionCallback> successCallback, PassOwnPtr<RTCErrorCallback> errorCallback, const Dictionary& mediaConstraints, ExceptionState& exceptionState)
+void RTCPeerConnection::createOffer(PassOwnPtr<RTCSessionDescriptionCallback> successCallback, PassOwnPtr<RTCErrorCallback> errorCallback, const Dictionary& rtcOfferOptions, ExceptionState& exceptionState)
{
if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
return;
ASSERT(successCallback);
- blink::WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
+ RefPtr<RTCOfferOptions> offerOptions = parseOfferOptions(rtcOfferOptions, exceptionState);
if (exceptionState.hadException())
return;
RefPtr<RTCSessionDescriptionRequest> request = RTCSessionDescriptionRequestImpl::create(executionContext(), this, successCallback, errorCallback);
- m_peerHandler->createOffer(request.release(), constraints);
+
+ if (offerOptions) {
+ m_peerHandler->createOffer(request.release(), offerOptions.release());
+ } else {
+ WebMediaConstraints constraints = MediaConstraintsImpl::create(rtcOfferOptions, exceptionState);
+ if (exceptionState.hadException())
+ return;
+
+ m_peerHandler->createOffer(request.release(), constraints);
+ }
}
void RTCPeerConnection::createAnswer(PassOwnPtr<RTCSessionDescriptionCallback> successCallback, PassOwnPtr<RTCErrorCallback> errorCallback, const Dictionary& mediaConstraints, ExceptionState& exceptionState)
ASSERT(successCallback);
- blink::WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
+ WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
if (exceptionState.hadException())
return;
m_peerHandler->createAnswer(request.release(), constraints);
}
-void RTCPeerConnection::setLocalDescription(PassRefPtrWillBeRawPtr<RTCSessionDescription> prpSessionDescription, PassOwnPtr<VoidCallback> successCallback, PassOwnPtr<RTCErrorCallback> errorCallback, ExceptionState& exceptionState)
+void RTCPeerConnection::setLocalDescription(RTCSessionDescription* sessionDescription, PassOwnPtr<VoidCallback> successCallback, PassOwnPtr<RTCErrorCallback> errorCallback, ExceptionState& exceptionState)
{
if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
return;
- RefPtrWillBeRawPtr<RTCSessionDescription> sessionDescription = prpSessionDescription;
if (!sessionDescription) {
exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "RTCSessionDescription"));
return;
m_peerHandler->setLocalDescription(request.release(), sessionDescription->webSessionDescription());
}
-PassRefPtrWillBeRawPtr<RTCSessionDescription> RTCPeerConnection::localDescription(ExceptionState& exceptionState)
+RTCSessionDescription* RTCPeerConnection::localDescription(ExceptionState& exceptionState)
{
- blink::WebRTCSessionDescription webSessionDescription = m_peerHandler->localDescription();
+ WebRTCSessionDescription webSessionDescription = m_peerHandler->localDescription();
if (webSessionDescription.isNull())
return nullptr;
return RTCSessionDescription::create(webSessionDescription);
}
-void RTCPeerConnection::setRemoteDescription(PassRefPtrWillBeRawPtr<RTCSessionDescription> prpSessionDescription, PassOwnPtr<VoidCallback> successCallback, PassOwnPtr<RTCErrorCallback> errorCallback, ExceptionState& exceptionState)
+void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* sessionDescription, PassOwnPtr<VoidCallback> successCallback, PassOwnPtr<RTCErrorCallback> errorCallback, ExceptionState& exceptionState)
{
if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
return;
- RefPtrWillBeRawPtr<RTCSessionDescription> sessionDescription = prpSessionDescription;
if (!sessionDescription) {
exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "RTCSessionDescription"));
return;
m_peerHandler->setRemoteDescription(request.release(), sessionDescription->webSessionDescription());
}
-PassRefPtrWillBeRawPtr<RTCSessionDescription> RTCPeerConnection::remoteDescription(ExceptionState& exceptionState)
+RTCSessionDescription* RTCPeerConnection::remoteDescription(ExceptionState& exceptionState)
{
- blink::WebRTCSessionDescription webSessionDescription = m_peerHandler->remoteDescription();
+ WebRTCSessionDescription webSessionDescription = m_peerHandler->remoteDescription();
if (webSessionDescription.isNull())
return nullptr;
if (exceptionState.hadException())
return;
- blink::WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
+ WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
if (exceptionState.hadException())
return;
return String();
}
-void RTCPeerConnection::addStream(PassRefPtrWillBeRawPtr<MediaStream> prpStream, const Dictionary& mediaConstraints, ExceptionState& exceptionState)
+void RTCPeerConnection::addStream(MediaStream* stream, const Dictionary& mediaConstraints, ExceptionState& exceptionState)
{
if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
return;
- RefPtrWillBeRawPtr<MediaStream> stream = prpStream;
if (!stream) {
exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "MediaStream"));
return;
if (m_localStreams.contains(stream))
return;
- blink::WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
+ WebMediaConstraints constraints = MediaConstraintsImpl::create(mediaConstraints, exceptionState);
if (exceptionState.hadException())
return;
exceptionState.throwDOMException(SyntaxError, "Unable to add the provided stream.");
}
-void RTCPeerConnection::removeStream(PassRefPtrWillBeRawPtr<MediaStream> prpStream, ExceptionState& exceptionState)
+void RTCPeerConnection::removeStream(MediaStream* stream, ExceptionState& exceptionState)
{
if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
return;
- if (!prpStream) {
+ if (!stream) {
exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "MediaStream"));
return;
}
- RefPtrWillBeRawPtr<MediaStream> stream = prpStream;
-
size_t pos = m_localStreams.find(stream);
if (pos == kNotFound)
return;
return 0;
}
-void RTCPeerConnection::getStats(PassOwnPtr<RTCStatsCallback> successCallback, PassRefPtr<MediaStreamTrack> selector)
+void RTCPeerConnection::getStats(PassOwnPtr<RTCStatsCallback> successCallback, MediaStreamTrack* selector)
{
RefPtr<RTCStatsRequest> statsRequest = RTCStatsRequestImpl::create(executionContext(), this, successCallback, selector);
// FIXME: Add passing selector as part of the statsRequest.
m_peerHandler->getStats(statsRequest.release());
}
-PassRefPtrWillBeRawPtr<RTCDataChannel> RTCPeerConnection::createDataChannel(String label, const Dictionary& options, ExceptionState& exceptionState)
+RTCDataChannel* RTCPeerConnection::createDataChannel(String label, const Dictionary& options, ExceptionState& exceptionState)
{
if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
return nullptr;
- blink::WebRTCDataChannelInit init;
- options.get("ordered", init.ordered);
- options.get("negotiated", init.negotiated);
+ WebRTCDataChannelInit init;
+ DictionaryHelper::get(options, "ordered", init.ordered);
+ DictionaryHelper::get(options, "negotiated", init.negotiated);
unsigned short value = 0;
- if (options.get("id", value))
+ if (DictionaryHelper::get(options, "id", value))
init.id = value;
- if (options.get("maxRetransmits", value))
+ if (DictionaryHelper::get(options, "maxRetransmits", value))
init.maxRetransmits = value;
- if (options.get("maxRetransmitTime", value))
+ if (DictionaryHelper::get(options, "maxRetransmitTime", value))
init.maxRetransmitTime = value;
String protocolString;
- options.get("protocol", protocolString);
+ DictionaryHelper::get(options, "protocol", protocolString);
init.protocol = protocolString;
- RefPtrWillBeRawPtr<RTCDataChannel> channel = RTCDataChannel::create(executionContext(), this, m_peerHandler.get(), label, init, exceptionState);
+ RTCDataChannel* channel = RTCDataChannel::create(executionContext(), this, m_peerHandler.get(), label, init, exceptionState);
if (exceptionState.hadException())
return nullptr;
m_dataChannels.append(channel);
- return channel.release();
+ return channel;
}
bool RTCPeerConnection::hasLocalStreamWithTrackId(const String& trackId)
return false;
}
-PassRefPtrWillBeRawPtr<RTCDTMFSender> RTCPeerConnection::createDTMFSender(PassRefPtrWillBeRawPtr<MediaStreamTrack> prpTrack, ExceptionState& exceptionState)
+RTCDTMFSender* RTCPeerConnection::createDTMFSender(MediaStreamTrack* track, ExceptionState& exceptionState)
{
if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState))
return nullptr;
- if (!prpTrack) {
+ if (!track) {
exceptionState.throwTypeError(ExceptionMessages::argumentNullOrIncorrectType(1, "MediaStreamTrack"));
return nullptr;
}
- RefPtrWillBeRawPtr<MediaStreamTrack> track = prpTrack;
-
if (!hasLocalStreamWithTrackId(track->id())) {
exceptionState.throwDOMException(SyntaxError, "No local stream is available for the track provided.");
return nullptr;
}
- RefPtrWillBeRawPtr<RTCDTMFSender> dtmfSender = RTCDTMFSender::create(executionContext(), m_peerHandler.get(), track.release(), exceptionState);
+ RTCDTMFSender* dtmfSender = RTCDTMFSender::create(executionContext(), m_peerHandler.get(), track, exceptionState);
if (exceptionState.hadException())
return nullptr;
- return dtmfSender.release();
+ return dtmfSender;
}
void RTCPeerConnection::close(ExceptionState& exceptionState)
scheduleDispatchEvent(Event::create(EventTypeNames::negotiationneeded));
}
-void RTCPeerConnection::didGenerateICECandidate(const blink::WebRTCICECandidate& webCandidate)
+void RTCPeerConnection::didGenerateICECandidate(const WebRTCICECandidate& webCandidate)
{
ASSERT(!m_closed);
ASSERT(executionContext()->isContextThread());
if (webCandidate.isNull())
scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, nullptr));
else {
- RefPtrWillBeRawPtr<RTCIceCandidate> iceCandidate = RTCIceCandidate::create(webCandidate);
- scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, iceCandidate.release()));
+ RTCIceCandidate* iceCandidate = RTCIceCandidate::create(webCandidate);
+ scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, iceCandidate));
}
}
changeIceConnectionState(newState);
}
-void RTCPeerConnection::didAddRemoteStream(const blink::WebMediaStream& remoteStream)
+void RTCPeerConnection::didAddRemoteStream(const WebMediaStream& remoteStream)
{
ASSERT(!m_closed);
ASSERT(executionContext()->isContextThread());
if (m_signalingState == SignalingStateClosed)
return;
- RefPtrWillBeRawPtr<MediaStream> stream = MediaStream::create(executionContext(), remoteStream);
+ MediaStream* stream = MediaStream::create(executionContext(), remoteStream);
m_remoteStreams.append(stream);
- scheduleDispatchEvent(MediaStreamEvent::create(EventTypeNames::addstream, false, false, stream.release()));
+ scheduleDispatchEvent(MediaStreamEvent::create(EventTypeNames::addstream, false, false, stream));
}
-void RTCPeerConnection::didRemoveRemoteStream(const blink::WebMediaStream& remoteStream)
+void RTCPeerConnection::didRemoveRemoteStream(const WebMediaStream& remoteStream)
{
ASSERT(!m_closed);
ASSERT(executionContext()->isContextThread());
MediaStreamDescriptor* streamDescriptor = remoteStream;
ASSERT(streamDescriptor->client());
- RefPtrWillBeRawPtr<MediaStream> stream = static_cast<MediaStream*>(streamDescriptor->client());
+ MediaStream* stream = static_cast<MediaStream*>(streamDescriptor->client());
stream->streamEnded();
if (m_signalingState == SignalingStateClosed)
ASSERT(pos != kNotFound);
m_remoteStreams.remove(pos);
- scheduleDispatchEvent(MediaStreamEvent::create(EventTypeNames::removestream, false, false, stream.release()));
+ scheduleDispatchEvent(MediaStreamEvent::create(EventTypeNames::removestream, false, false, stream));
}
-void RTCPeerConnection::didAddRemoteDataChannel(blink::WebRTCDataChannelHandler* handler)
+void RTCPeerConnection::didAddRemoteDataChannel(WebRTCDataChannelHandler* handler)
{
ASSERT(!m_closed);
ASSERT(executionContext()->isContextThread());
if (m_signalingState == SignalingStateClosed)
return;
- RefPtrWillBeRawPtr<RTCDataChannel> channel = RTCDataChannel::create(executionContext(), this, adoptPtr(handler));
+ RTCDataChannel* channel = RTCDataChannel::create(executionContext(), this, adoptPtr(handler));
m_dataChannels.append(channel);
- scheduleDispatchEvent(RTCDataChannelEvent::create(EventTypeNames::datachannel, false, false, channel.release()));
+ scheduleDispatchEvent(RTCDataChannelEvent::create(EventTypeNames::datachannel, false, false, channel));
}
void RTCPeerConnection::releasePeerConnectionHandler()
m_iceConnectionState = ICEConnectionStateClosed;
m_signalingState = SignalingStateClosed;
- WillBeHeapVector<RefPtrWillBeMember<RTCDataChannel> >::iterator i = m_dataChannels.begin();
+ HeapVector<Member<RTCDataChannel> >::iterator i = m_dataChannels.begin();
for (; i != m_dataChannels.end(); ++i)
(*i)->stop();
m_dataChannels.clear();
visitor->trace(m_localStreams);
visitor->trace(m_remoteStreams);
visitor->trace(m_dataChannels);
+#if ENABLE(OILPAN)
visitor->trace(m_scheduledEvents);
+#endif
EventTargetWithInlineData::trace(visitor);
}
-} // namespace WebCore
+} // namespace blink