summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/mediastream
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/Modules/mediastream')
-rw-r--r--Source/WebCore/Modules/mediastream/AllAudioCapabilities.h59
-rw-r--r--Source/WebCore/Modules/mediastream/AllVideoCapabilities.h57
-rw-r--r--Source/WebCore/Modules/mediastream/AllVideoCapabilities.idl38
-rw-r--r--Source/WebCore/Modules/mediastream/AudioStreamTrack.cpp71
-rw-r--r--Source/WebCore/Modules/mediastream/AudioStreamTrack.h59
-rw-r--r--Source/WebCore/Modules/mediastream/AudioStreamTrack.idl31
-rw-r--r--Source/WebCore/Modules/mediastream/CapabilityRange.cpp92
-rw-r--r--Source/WebCore/Modules/mediastream/CapabilityRange.h60
-rw-r--r--Source/WebCore/Modules/mediastream/CapabilityRange.idl33
-rw-r--r--Source/WebCore/Modules/mediastream/DOMURLMediaStream.cpp5
-rw-r--r--Source/WebCore/Modules/mediastream/DOMURLMediaStream.h7
-rw-r--r--Source/WebCore/Modules/mediastream/DOMURLMediaStream.idl2
-rw-r--r--Source/WebCore/Modules/mediastream/DoubleRange.h (renamed from Source/WebCore/Modules/mediastream/RTCStatsResponse.idl)23
-rw-r--r--Source/WebCore/Modules/mediastream/DoubleRange.idl (renamed from Source/WebCore/Modules/mediastream/RTCStatsCallback.idl)9
-rw-r--r--Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.cpp50
-rw-r--r--Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.h48
-rw-r--r--Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.idl33
-rw-r--r--Source/WebCore/Modules/mediastream/LongRange.h (renamed from Source/WebCore/Modules/mediastream/NavigatorUserMediaErrorCallback.idl)20
-rw-r--r--Source/WebCore/Modules/mediastream/LongRange.idl (renamed from Source/WebCore/Modules/mediastream/NavigatorUserMediaSuccessCallback.idl)9
-rw-r--r--Source/WebCore/Modules/mediastream/MediaConstraintsImpl.cpp119
-rw-r--r--Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h54
-rw-r--r--Source/WebCore/Modules/mediastream/MediaDeviceInfo.cpp (renamed from Source/WebCore/Modules/mediastream/MediaTrackConstraint.cpp)30
-rw-r--r--Source/WebCore/Modules/mediastream/MediaDeviceInfo.h (renamed from Source/WebCore/Modules/mediastream/SourceInfo.h)39
-rw-r--r--Source/WebCore/Modules/mediastream/MediaDeviceInfo.idl42
-rw-r--r--Source/WebCore/Modules/mediastream/MediaDevices.cpp108
-rw-r--r--Source/WebCore/Modules/mediastream/MediaDevices.h (renamed from Source/WebCore/Modules/mediastream/RTCSessionDescriptionRequestImpl.h)53
-rw-r--r--Source/WebCore/Modules/mediastream/MediaDevices.idl46
-rw-r--r--Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp113
-rw-r--r--Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.h71
-rw-r--r--Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp153
-rw-r--r--Source/WebCore/Modules/mediastream/MediaDevicesRequest.h (renamed from Source/WebCore/Modules/mediastream/MediaTrackConstraint.h)49
-rw-r--r--Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp874
-rw-r--r--Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h132
-rw-r--r--Source/WebCore/Modules/mediastream/MediaEndpointSessionDescription.cpp116
-rw-r--r--Source/WebCore/Modules/mediastream/MediaEndpointSessionDescription.h75
-rw-r--r--Source/WebCore/Modules/mediastream/MediaSourceStates.cpp59
-rw-r--r--Source/WebCore/Modules/mediastream/MediaSourceStates.h63
-rw-r--r--Source/WebCore/Modules/mediastream/MediaSourceStates.idl44
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStream.cpp473
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStream.h124
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStream.idl34
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamCapabilities.cpp142
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamCapabilities.h69
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamCapabilities.idl33
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamEvent.cpp35
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamEvent.h29
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamEvent.idl10
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamRegistry.cpp52
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamRegistry.h26
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp387
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamTrack.h147
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamTrack.idl80
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.cpp31
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.h27
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.idl7
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesCallback.idl32
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.cpp72
-rw-r--r--Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.h65
-rw-r--r--Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.cpp53
-rw-r--r--Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.h56
-rw-r--r--Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.idl33
-rw-r--r--Source/WebCore/Modules/mediastream/MediaTrackConstraints.cpp207
-rw-r--r--Source/WebCore/Modules/mediastream/MediaTrackConstraints.h100
-rw-r--r--Source/WebCore/Modules/mediastream/MediaTrackConstraints.idl100
-rw-r--r--Source/WebCore/Modules/mediastream/MediaTrackSupportedConstraints.h53
-rw-r--r--Source/WebCore/Modules/mediastream/MediaTrackSupportedConstraints.idl46
-rw-r--r--Source/WebCore/Modules/mediastream/NavigatorMediaDevices.cpp (renamed from Source/WebCore/Modules/mediastream/RTCVoidRequestImpl.cpp)62
-rw-r--r--Source/WebCore/Modules/mediastream/NavigatorMediaDevices.h (renamed from Source/WebCore/Modules/mediastream/RTCVoidRequestImpl.h)42
-rw-r--r--Source/WebCore/Modules/mediastream/NavigatorMediaDevices.idl (renamed from Source/WebCore/Modules/mediastream/RTCSessionDescriptionCallback.idl)10
-rw-r--r--Source/WebCore/Modules/mediastream/NavigatorMediaStream.cpp71
-rw-r--r--Source/WebCore/Modules/mediastream/NavigatorMediaStream.h50
-rw-r--r--Source/WebCore/Modules/mediastream/NavigatorMediaStream.idl27
-rw-r--r--Source/WebCore/Modules/mediastream/NavigatorUserMedia.idl36
-rw-r--r--Source/WebCore/Modules/mediastream/NavigatorUserMedia.js49
-rw-r--r--Source/WebCore/Modules/mediastream/NavigatorUserMediaError.cpp51
-rw-r--r--Source/WebCore/Modules/mediastream/NavigatorUserMediaErrorCallback.h45
-rw-r--r--Source/WebCore/Modules/mediastream/NavigatorUserMediaSuccessCallback.h46
-rw-r--r--Source/WebCore/Modules/mediastream/OverconstrainedError.h62
-rw-r--r--Source/WebCore/Modules/mediastream/OverconstrainedError.idl (renamed from Source/WebCore/Modules/mediastream/NavigatorUserMediaError.idl)29
-rw-r--r--Source/WebCore/Modules/mediastream/OverconstrainedErrorEvent.h77
-rw-r--r--Source/WebCore/Modules/mediastream/OverconstrainedErrorEvent.idl38
-rw-r--r--Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp312
-rw-r--r--Source/WebCore/Modules/mediastream/PeerConnectionBackend.h146
-rw-r--r--Source/WebCore/Modules/mediastream/RTCConfiguration.h (renamed from Source/WebCore/Modules/mediastream/RTCSessionDescriptionCallback.h)26
-rw-r--r--Source/WebCore/Modules/mediastream/RTCConfiguration.idl (renamed from Source/WebCore/Modules/mediastream/AllAudioCapabilities.idl)21
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDTMFSender.cpp105
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDTMFSender.h69
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDTMFSender.idl20
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.cpp26
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.h26
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.idl12
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDataChannel.cpp190
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDataChannel.h118
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDataChannel.idl32
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDataChannelEvent.cpp31
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDataChannelEvent.h21
-rw-r--r--Source/WebCore/Modules/mediastream/RTCDataChannelEvent.idl2
-rw-r--r--Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp79
-rw-r--r--Source/WebCore/Modules/mediastream/RTCIceCandidate.h41
-rw-r--r--Source/WebCore/Modules/mediastream/RTCIceCandidate.idl21
-rw-r--r--Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.cpp21
-rw-r--r--Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.h15
-rw-r--r--Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.idl2
-rw-r--r--Source/WebCore/Modules/mediastream/RTCIceServer.h (renamed from Source/WebCore/Modules/mediastream/VideoStreamTrack.idl)28
-rw-r--r--Source/WebCore/Modules/mediastream/RTCIceServer.idl (renamed from Source/WebCore/Modules/mediastream/MediaTrackConstraint.idl)16
-rw-r--r--Source/WebCore/Modules/mediastream/RTCIceTransport.h69
-rw-r--r--Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.h (renamed from Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesCallback.h)34
-rw-r--r--Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp736
-rw-r--r--Source/WebCore/Modules/mediastream/RTCPeerConnection.h175
-rw-r--r--Source/WebCore/Modules/mediastream/RTCPeerConnection.idl150
-rw-r--r--Source/WebCore/Modules/mediastream/RTCPeerConnection.js268
-rw-r--r--Source/WebCore/Modules/mediastream/RTCPeerConnectionInternals.js145
-rw-r--r--Source/WebCore/Modules/mediastream/RTCRtpReceiver.cpp (renamed from Source/WebCore/Modules/mediastream/RTCPeerConnectionErrorCallback.h)33
-rw-r--r--Source/WebCore/Modules/mediastream/RTCRtpReceiver.h57
-rw-r--r--Source/WebCore/Modules/mediastream/RTCRtpReceiver.idl (renamed from Source/WebCore/Modules/mediastream/RTCPeerConnectionErrorCallback.idl)19
-rw-r--r--Source/WebCore/Modules/mediastream/RTCRtpSender.cpp87
-rw-r--r--Source/WebCore/Modules/mediastream/RTCRtpSender.h75
-rw-r--r--Source/WebCore/Modules/mediastream/RTCRtpSender.idl38
-rw-r--r--Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.h62
-rw-r--r--Source/WebCore/Modules/mediastream/RTCRtpTransceiver.cpp110
-rw-r--r--Source/WebCore/Modules/mediastream/RTCRtpTransceiver.h113
-rw-r--r--Source/WebCore/Modules/mediastream/RTCRtpTransceiver.idl46
-rw-r--r--Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp74
-rw-r--r--Source/WebCore/Modules/mediastream/RTCSessionDescription.h40
-rw-r--r--Source/WebCore/Modules/mediastream/RTCSessionDescription.idl21
-rw-r--r--Source/WebCore/Modules/mediastream/RTCSessionDescriptionRequestImpl.cpp95
-rw-r--r--Source/WebCore/Modules/mediastream/RTCStatsCallback.h46
-rw-r--r--Source/WebCore/Modules/mediastream/RTCStatsReport.cpp43
-rw-r--r--Source/WebCore/Modules/mediastream/RTCStatsReport.h35
-rw-r--r--Source/WebCore/Modules/mediastream/RTCStatsReport.idl12
-rw-r--r--Source/WebCore/Modules/mediastream/RTCStatsRequestImpl.cpp92
-rw-r--r--Source/WebCore/Modules/mediastream/RTCStatsRequestImpl.h68
-rw-r--r--Source/WebCore/Modules/mediastream/RTCStatsResponse.cpp69
-rw-r--r--Source/WebCore/Modules/mediastream/RTCStatsResponse.h63
-rw-r--r--Source/WebCore/Modules/mediastream/RTCTrackEvent.cpp72
-rw-r--r--Source/WebCore/Modules/mediastream/RTCTrackEvent.h78
-rw-r--r--Source/WebCore/Modules/mediastream/RTCTrackEvent.idl47
-rw-r--r--Source/WebCore/Modules/mediastream/SDPProcessor.cpp547
-rw-r--r--Source/WebCore/Modules/mediastream/SDPProcessor.h78
-rw-r--r--Source/WebCore/Modules/mediastream/SourceInfo.cpp64
-rw-r--r--Source/WebCore/Modules/mediastream/SourceInfo.idl34
-rw-r--r--Source/WebCore/Modules/mediastream/UserMediaClient.h18
-rw-r--r--Source/WebCore/Modules/mediastream/UserMediaController.cpp7
-rw-r--r--Source/WebCore/Modules/mediastream/UserMediaController.h40
-rw-r--r--Source/WebCore/Modules/mediastream/UserMediaRequest.cpp264
-rw-r--r--Source/WebCore/Modules/mediastream/UserMediaRequest.h83
-rw-r--r--Source/WebCore/Modules/mediastream/VideoStreamTrack.cpp71
-rw-r--r--Source/WebCore/Modules/mediastream/VideoStreamTrack.h59
-rw-r--r--Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCDataChannelHandler.cpp114
-rw-r--r--Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCDataChannelHandler.h (renamed from Source/WebCore/Modules/mediastream/NavigatorUserMediaError.h)56
-rw-r--r--Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp527
-rw-r--r--Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h175
-rw-r--r--Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp231
-rw-r--r--Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h97
-rw-r--r--Source/WebCore/Modules/mediastream/sdp.js606
155 files changed, 8683 insertions, 5004 deletions
diff --git a/Source/WebCore/Modules/mediastream/AllAudioCapabilities.h b/Source/WebCore/Modules/mediastream/AllAudioCapabilities.h
deleted file mode 100644
index 532956479..000000000
--- a/Source/WebCore/Modules/mediastream/AllAudioCapabilities.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AllAudioCapabilities_h
-#define AllAudioCapabilities_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamCapabilities.h"
-#include "MediaStreamSourceCapabilities.h"
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class CapabilityRange;
-class MediaStreamSourceCapabilities;
-
-class AllAudioCapabilities : public MediaStreamCapabilities {
-public:
- static RefPtr<AllAudioCapabilities> create(PassRefPtr<MediaStreamSourceCapabilities> capabilities)
- {
- return adoptRef(new AllAudioCapabilities(capabilities));
- }
- virtual ~AllAudioCapabilities() { }
-
-private:
- explicit AllAudioCapabilities(PassRefPtr<MediaStreamSourceCapabilities> capabilities)
- : MediaStreamCapabilities(capabilities)
- {
- }
-};
-
-} // namespace WebCore
-
-#endif // AllAudioCapabilities_h
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/AllVideoCapabilities.h b/Source/WebCore/Modules/mediastream/AllVideoCapabilities.h
deleted file mode 100644
index 667f214f3..000000000
--- a/Source/WebCore/Modules/mediastream/AllVideoCapabilities.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AllVideoCapabilities_h
-#define AllVideoCapabilities_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamCapabilities.h"
-
-namespace WebCore {
-
-class CapabilityRange;
-class MediaStreamSourceCapabilities;
-
-class AllVideoCapabilities : public MediaStreamCapabilities {
-public:
- static RefPtr<AllVideoCapabilities> create(PassRefPtr<MediaStreamSourceCapabilities> capabilities)
- {
- return adoptRef(new AllVideoCapabilities(capabilities));
- }
- virtual ~AllVideoCapabilities() { }
-
-private:
- explicit AllVideoCapabilities(PassRefPtr<MediaStreamSourceCapabilities> capabilities)
- : MediaStreamCapabilities(capabilities)
- {
- }
-};
-
-} // namespace WebCore
-
-#endif // AllVideoCapabilities_h
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/AllVideoCapabilities.idl b/Source/WebCore/Modules/mediastream/AllVideoCapabilities.idl
deleted file mode 100644
index 515137cff..000000000
--- a/Source/WebCore/Modules/mediastream/AllVideoCapabilities.idl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- NoInterfaceObject,
- Conditional=MEDIA_STREAM,
- JSGenerateToJSObject,
-] interface AllVideoCapabilities : MediaStreamCapabilities {
- readonly attribute DOMString[] sourceType;
- readonly attribute DOMString[] sourceId;
- readonly attribute CapabilityRange width;
- readonly attribute CapabilityRange height;
- readonly attribute CapabilityRange frameRate;
- readonly attribute CapabilityRange aspectRatio;
- readonly attribute DOMString[] facingMode;
-};
diff --git a/Source/WebCore/Modules/mediastream/AudioStreamTrack.cpp b/Source/WebCore/Modules/mediastream/AudioStreamTrack.cpp
deleted file mode 100644
index 101b09cb1..000000000
--- a/Source/WebCore/Modules/mediastream/AudioStreamTrack.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "AudioStreamTrack.h"
-
-#include "Dictionary.h"
-#include "ScriptExecutionContext.h"
-#include <wtf/NeverDestroyed.h>
-
-namespace WebCore {
-
-RefPtr<AudioStreamTrack> AudioStreamTrack::create(ScriptExecutionContext& context, const Dictionary& audioConstraints)
-{
- return adoptRef(new AudioStreamTrack(context, *MediaStreamTrackPrivate::create(0), &audioConstraints));
-}
-
-RefPtr<AudioStreamTrack> AudioStreamTrack::create(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack)
-{
- return adoptRef(new AudioStreamTrack(context, privateTrack, 0));
-}
-
-RefPtr<AudioStreamTrack> AudioStreamTrack::create(MediaStreamTrack& track)
-{
- return adoptRef(new AudioStreamTrack(track));
-}
-
-AudioStreamTrack::AudioStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack, const Dictionary* audioConstraints)
- : MediaStreamTrack(context, privateTrack, audioConstraints)
-{
-}
-
-AudioStreamTrack::AudioStreamTrack(MediaStreamTrack& track)
- : MediaStreamTrack(track)
-{
-}
-
-const AtomicString& AudioStreamTrack::kind() const
-{
- static NeverDestroyed<AtomicString> audioKind("audio", AtomicString::ConstructFromLiteral);
- return audioKind;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/AudioStreamTrack.h b/Source/WebCore/Modules/mediastream/AudioStreamTrack.h
deleted file mode 100644
index 79346c38a..000000000
--- a/Source/WebCore/Modules/mediastream/AudioStreamTrack.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AudioStreamTrack_h
-#define AudioStreamTrack_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamTrack.h"
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class MediaStreamSource;
-class ScriptExecutionContext;
-
-class AudioStreamTrack final : public MediaStreamTrack {
-public:
- static RefPtr<AudioStreamTrack> create(ScriptExecutionContext&, const Dictionary&);
- static RefPtr<AudioStreamTrack> create(ScriptExecutionContext&, MediaStreamTrackPrivate&);
- static RefPtr<AudioStreamTrack> create(MediaStreamTrack&);
-
- virtual ~AudioStreamTrack() { }
-
- virtual const AtomicString& kind() const override;
-
-private:
- AudioStreamTrack(ScriptExecutionContext&, MediaStreamTrackPrivate&, const Dictionary*);
- explicit AudioStreamTrack(MediaStreamTrack&);
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // AudioStreamTrack_h
diff --git a/Source/WebCore/Modules/mediastream/AudioStreamTrack.idl b/Source/WebCore/Modules/mediastream/AudioStreamTrack.idl
deleted file mode 100644
index 2f6e5411a..000000000
--- a/Source/WebCore/Modules/mediastream/AudioStreamTrack.idl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Conditional=MEDIA_STREAM,
- Constructor(optional Dictionary audioConstraints),
- ConstructorCallWith=ScriptExecutionContext,
-] interface AudioStreamTrack : MediaStreamTrack {
-};
diff --git a/Source/WebCore/Modules/mediastream/CapabilityRange.cpp b/Source/WebCore/Modules/mediastream/CapabilityRange.cpp
deleted file mode 100644
index 6c125a47d..000000000
--- a/Source/WebCore/Modules/mediastream/CapabilityRange.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "CapabilityRange.h"
-
-#include "JSDOMBinding.h"
-#include "MediaSourceStates.h"
-#include <bindings/ScriptValue.h>
-#include <interpreter/CallFrame.h>
-#include <runtime/JSCJSValue.h>
-
-using namespace JSC;
-
-namespace WebCore {
-
-RefPtr<CapabilityRange> CapabilityRange::create(const MediaStreamSourceCapabilityRange& rangeInfo)
-{
- return adoptRef(new CapabilityRange(rangeInfo));
-}
-
-CapabilityRange::CapabilityRange(const MediaStreamSourceCapabilityRange& rangeInfo)
- : m_rangeInfo(rangeInfo)
-{
-}
-
-static Deprecated::ScriptValue scriptValue(ExecState* exec, const MediaStreamSourceCapabilityRange::ValueUnion& value, MediaStreamSourceCapabilityRange::Type type)
-{
- // NOTE: the spec says:
- // ... an implementation should make a reasonable attempt to translate and scale the hardware's setting
- // onto the mapping provided by this specification. If this is not possible due to the user agent's
- // inability to retrieve a given capability from a source, then for CapabilityRange-typed capabilities,
- // the min and max fields will not be present on the returned dictionary, and the supported field will be false.
- // We don't do this currently because I don't know of an instance where it isn't possible to retrieve a source
- // capability, but when we have to deal with this we will need to mark CapabilityRange.min and CapabilityRange.max as
- // "Custom" and return jsUndefined() from the custom getter to support it.
-
- switch (type) {
- case MediaStreamSourceCapabilityRange::Float:
- return Deprecated::ScriptValue(exec->vm(), JSValue(value.asFloat));
- break;
- case MediaStreamSourceCapabilityRange::ULong:
- return Deprecated::ScriptValue(exec->vm(), JSValue(value.asULong));
- break;
- case MediaStreamSourceCapabilityRange::Undefined:
- return Deprecated::ScriptValue(exec->vm(), jsUndefined());
- break;
- }
-
- ASSERT_NOT_REACHED();
- return Deprecated::ScriptValue(exec->vm(), jsUndefined());
-}
-
-Deprecated::ScriptValue CapabilityRange::min(ExecState* exec) const
-{
- return scriptValue(exec, m_rangeInfo.min(), m_rangeInfo.type());
-}
-
-Deprecated::ScriptValue CapabilityRange::max(ExecState* exec) const
-{
- return scriptValue(exec, m_rangeInfo.max(), m_rangeInfo.type());
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/CapabilityRange.h b/Source/WebCore/Modules/mediastream/CapabilityRange.h
deleted file mode 100644
index 905ae3f02..000000000
--- a/Source/WebCore/Modules/mediastream/CapabilityRange.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef CapabilityRange_h
-#define CapabilityRange_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamSourceCapabilities.h"
-#include "ScriptWrappable.h"
-#include <bindings/ScriptValue.h>
-#include <interpreter/CallFrame.h>
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class CapabilityRange : public RefCounted<CapabilityRange>, public ScriptWrappable {
-public:
- virtual ~CapabilityRange() { }
-
- static RefPtr<CapabilityRange> create(const MediaStreamSourceCapabilityRange&);
-
- Deprecated::ScriptValue min(JSC::ExecState*) const;
- Deprecated::ScriptValue max(JSC::ExecState*) const;
- bool supported() const { return m_rangeInfo.supported(); }
-
-private:
- CapabilityRange(const MediaStreamSourceCapabilityRange&);
-
- MediaStreamSourceCapabilityRange m_rangeInfo;
-};
-
-} // namespace WebCore
-
-#endif // CapabilityRange_h
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/CapabilityRange.idl b/Source/WebCore/Modules/mediastream/CapabilityRange.idl
deleted file mode 100644
index 3dc6f13f0..000000000
--- a/Source/WebCore/Modules/mediastream/CapabilityRange.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- NoInterfaceObject,
- Conditional=MEDIA_STREAM,
-] interface CapabilityRange {
- [CallWith=ScriptState] readonly attribute any max;
- [CallWith=ScriptState] readonly attribute any min;
- readonly attribute boolean supported;
-};
diff --git a/Source/WebCore/Modules/mediastream/DOMURLMediaStream.cpp b/Source/WebCore/Modules/mediastream/DOMURLMediaStream.cpp
index 0eeed9c9f..69dc73042 100644
--- a/Source/WebCore/Modules/mediastream/DOMURLMediaStream.cpp
+++ b/Source/WebCore/Modules/mediastream/DOMURLMediaStream.cpp
@@ -40,13 +40,10 @@
namespace WebCore {
-String DOMURLMediaStream::createObjectURL(ScriptExecutionContext* scriptExecutionContext, MediaStream* stream)
+String DOMURLMediaStream::createObjectURL(ScriptExecutionContext& scriptExecutionContext, MediaStream& stream)
{
// Since WebWorkers cannot obtain Stream objects, we should be on the main thread.
ASSERT(isMainThread());
-
- if (!scriptExecutionContext || !stream)
- return String();
return DOMURL::createPublicURL(scriptExecutionContext, stream);
}
diff --git a/Source/WebCore/Modules/mediastream/DOMURLMediaStream.h b/Source/WebCore/Modules/mediastream/DOMURLMediaStream.h
index 3e2d8c905..560f621e5 100644
--- a/Source/WebCore/Modules/mediastream/DOMURLMediaStream.h
+++ b/Source/WebCore/Modules/mediastream/DOMURLMediaStream.h
@@ -28,8 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DOMURLMediaStream_h
-#define DOMURLMediaStream_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
@@ -42,11 +41,9 @@ class ScriptExecutionContext;
class DOMURLMediaStream {
public:
- static String createObjectURL(ScriptExecutionContext*, MediaStream*);
+ static String createObjectURL(ScriptExecutionContext&, MediaStream&);
};
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // URLMediaStream_h
diff --git a/Source/WebCore/Modules/mediastream/DOMURLMediaStream.idl b/Source/WebCore/Modules/mediastream/DOMURLMediaStream.idl
index 77b689761..d40ce6749 100644
--- a/Source/WebCore/Modules/mediastream/DOMURLMediaStream.idl
+++ b/Source/WebCore/Modules/mediastream/DOMURLMediaStream.idl
@@ -31,5 +31,5 @@
Conditional=MEDIA_STREAM
]
partial interface DOMURL {
- [CallWith=ScriptExecutionContext,TreatReturnedNullStringAs=Null] static DOMString createObjectURL(MediaStream? stream);
+ [CallWith=ScriptExecutionContext] static DOMString createObjectURL(MediaStream stream);
};
diff --git a/Source/WebCore/Modules/mediastream/RTCStatsResponse.idl b/Source/WebCore/Modules/mediastream/DoubleRange.h
index 16634d741..84a46bd60 100644
--- a/Source/WebCore/Modules/mediastream/RTCStatsResponse.idl
+++ b/Source/WebCore/Modules/mediastream/DoubleRange.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -22,10 +22,19 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- NoInterfaceObject,
- Conditional=MEDIA_STREAM,
-] interface RTCStatsResponse {
- sequence<RTCStatsReport> result();
- getter RTCStatsReport namedItem([Default=Undefined] optional DOMString name);
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <wtf/Optional.h>
+
+namespace WebCore {
+
+struct DoubleRange {
+ std::optional<double> max;
+ std::optional<double> min;
};
+
+}
+
+#endif
diff --git a/Source/WebCore/Modules/mediastream/RTCStatsCallback.idl b/Source/WebCore/Modules/mediastream/DoubleRange.idl
index b32f43d2f..1ca3724e0 100644
--- a/Source/WebCore/Modules/mediastream/RTCStatsCallback.idl
+++ b/Source/WebCore/Modules/mediastream/DoubleRange.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,7 +24,8 @@
[
Conditional=MEDIA_STREAM,
-] callback interface RTCStatsCallback {
- boolean handleEvent(RTCStatsResponse response);
+ JSGenerateToJSObject,
+] dictionary DoubleRange {
+ double max;
+ double min;
};
-
diff --git a/Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.cpp b/Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.cpp
deleted file mode 100644
index 1dc905a57..000000000
--- a/Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "HTMLMediaElementMediaStream.h"
-
-#if ENABLE(MEDIA_STREAM) && ENABLE(VIDEO)
-
-#include "HTMLMediaElement.h"
-#include "MediaStream.h"
-
-namespace WebCore {
-
-MediaStream* HTMLMediaElementMediaStream::srcObject(HTMLMediaElement* mediaElement, bool& isNull)
-{
- ASSERT(mediaElement);
- return mediaElement->srcObject();
-}
-
-void HTMLMediaElementMediaStream::setSrcObject(HTMLMediaElement* mediaElement, MediaStream* mediaStream)
-{
- ASSERT(mediaElement);
- mediaElement->setSrcObject(mediaStream);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM) && ENABLE(VIDEO)
diff --git a/Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.h b/Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.h
deleted file mode 100644
index 41bf48418..000000000
--- a/Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLMediaElementMediaStream_h
-#define HTMLMediaElementMediaStream_h
-
-#if ENABLE(MEDIA_STREAM) && ENABLE(VIDEO)
-
-#include <wtf/PassRefPtr.h>
-
-namespace WebCore {
-
-class HTMLMediaElement;
-class MediaStream;
-
-class HTMLMediaElementMediaStream {
-public:
- static MediaStream* srcObject(HTMLMediaElement*, bool& isNull);
- static void setSrcObject(HTMLMediaElement*, MediaStream*);
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM) && ENABLE(VIDEO)
-
-#endif // HTMLMediaElementMediaStream_h
diff --git a/Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.idl b/Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.idl
deleted file mode 100644
index a3ba17d67..000000000
--- a/Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Conditional=VIDEO&MEDIA_STREAM,
-] partial interface HTMLMediaElement
-{
-#if !defined(LANGUAGE_GOBJECT) || !LANGUAGE_GOBJECT
- attribute MediaStream? srcObject;
-#endif
-};
diff --git a/Source/WebCore/Modules/mediastream/NavigatorUserMediaErrorCallback.idl b/Source/WebCore/Modules/mediastream/LongRange.h
index e7754f18a..160ef86b6 100644
--- a/Source/WebCore/Modules/mediastream/NavigatorUserMediaErrorCallback.idl
+++ b/Source/WebCore/Modules/mediastream/LongRange.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -22,9 +22,19 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- Conditional=MEDIA_STREAM,
-] callback interface NavigatorUserMediaErrorCallback {
- boolean handleEvent(NavigatorUserMediaError error);
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <wtf/Optional.h>
+
+namespace WebCore {
+
+struct LongRange {
+ std::optional<int> max;
+ std::optional<int> min;
};
+}
+
+#endif
diff --git a/Source/WebCore/Modules/mediastream/NavigatorUserMediaSuccessCallback.idl b/Source/WebCore/Modules/mediastream/LongRange.idl
index 3912797d3..69ba22410 100644
--- a/Source/WebCore/Modules/mediastream/NavigatorUserMediaSuccessCallback.idl
+++ b/Source/WebCore/Modules/mediastream/LongRange.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,7 +24,8 @@
[
Conditional=MEDIA_STREAM,
-] callback interface NavigatorUserMediaSuccessCallback {
- boolean handleEvent(MediaStream stream);
+ JSGenerateToJSObject,
+] dictionary LongRange {
+ long max;
+ long min;
};
-
diff --git a/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.cpp b/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.cpp
index 10f812bda..f50f758be 100644
--- a/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.cpp
+++ b/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,126 +35,16 @@
#include "MediaConstraintsImpl.h"
-#include "ArrayValue.h"
-#include "Dictionary.h"
-#include "ExceptionCode.h"
-#include <wtf/HashMap.h>
-
namespace WebCore {
-PassRefPtr<MediaConstraintsImpl> MediaConstraintsImpl::create(const Dictionary& constraints, ExceptionCode& ec)
-{
- RefPtr<MediaConstraintsImpl> object = adoptRef(new MediaConstraintsImpl());
- if (!object->initialize(constraints)) {
- ec = TYPE_MISMATCH_ERR;
- return 0;
- }
- return object.release();
-}
-
-PassRefPtr<MediaConstraintsImpl> MediaConstraintsImpl::create()
-{
- return adoptRef(new MediaConstraintsImpl());
-}
-
-bool MediaConstraintsImpl::initialize(const Dictionary& constraints)
-{
- if (constraints.isUndefinedOrNull())
- return true;
-
- Vector<String> names;
- constraints.getOwnPropertyNames(names);
-
- String mandatory = ASCIILiteral("mandatory");
- String optional = ASCIILiteral("optional");
-
- for (Vector<String>::iterator it = names.begin(); it != names.end(); ++it) {
- if (*it != mandatory && *it != optional)
- return false;
- }
-
- if (names.contains(mandatory)) {
- Dictionary mandatoryConstraints;
- bool ok = constraints.get(mandatory, mandatoryConstraints);
- if (!ok || mandatoryConstraints.isUndefinedOrNull())
- return false;
-
- ok = mandatoryConstraints.getOwnPropertiesAsStringHashMap(m_mandatoryConstraints);
- if (!ok)
- return false;
- }
-
- if (names.contains(optional)) {
- ArrayValue optionalConstraints;
- bool ok = constraints.get(optional, optionalConstraints);
- if (!ok || optionalConstraints.isUndefinedOrNull())
- return false;
-
- size_t numberOfConstraints;
- ok = optionalConstraints.length(numberOfConstraints);
- if (!ok)
- return false;
-
- for (size_t i = 0; i < numberOfConstraints; ++i) {
- Dictionary constraint;
- ok = optionalConstraints.get(i, constraint);
- if (!ok || constraint.isUndefinedOrNull())
- return false;
- Vector<String> localNames;
- constraint.getOwnPropertyNames(localNames);
- if (localNames.size() != 1)
- return false;
- String key = localNames[0];
- String value;
- ok = constraint.get(key, value);
- if (!ok)
- return false;
- m_optionalConstraints.append(MediaConstraint(key, value));
- }
- }
-
- return true;
-}
-
-MediaConstraintsImpl::~MediaConstraintsImpl()
+Ref<MediaConstraintsImpl> MediaConstraintsImpl::create(MediaTrackConstraintSetMap&& mandatoryConstraints, Vector<MediaTrackConstraintSetMap>&& advancedConstraints, bool isValid)
{
+ return adoptRef(*new MediaConstraintsImpl(WTFMove(mandatoryConstraints), WTFMove(advancedConstraints), isValid));
}
-void MediaConstraintsImpl::getMandatoryConstraints(Vector<MediaConstraint>& constraints) const
+Ref<MediaConstraintsImpl> MediaConstraintsImpl::create(const MediaConstraintsData& data)
{
- constraints.clear();
- HashMap<String, String>::const_iterator i = m_mandatoryConstraints.begin();
- for (; i != m_mandatoryConstraints.end(); ++i)
- constraints.append(MediaConstraint(i->key, i->value));
-}
-
-void MediaConstraintsImpl::getOptionalConstraints(Vector<MediaConstraint>& constraints) const
-{
- constraints.clear();
- constraints.appendRange(m_optionalConstraints.begin(), m_optionalConstraints.end());
-}
-
-bool MediaConstraintsImpl::getMandatoryConstraintValue(const String& name, String& value) const
-{
- HashMap<String, String>::const_iterator i = m_mandatoryConstraints.find(name);
- if (i == m_mandatoryConstraints.end())
- return false;
-
- value = i->value;
- return true;
-}
-
-bool MediaConstraintsImpl::getOptionalConstraintValue(const String& name, String& value) const
-{
- Vector<MediaConstraint>::const_iterator i = m_optionalConstraints.begin();
- for (; i != m_optionalConstraints.end(); ++i) {
- if (i->m_name == name) {
- value = i->m_value;
- return true;
- }
- }
-
- return false;
+ return adoptRef(*new MediaConstraintsImpl(data));
}
} // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h b/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h
index eeb631ca3..fbee397cd 100644
--- a/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h
+++ b/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h
@@ -28,44 +28,56 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaConstraintsImpl_h
-#define MediaConstraintsImpl_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
#include "ExceptionBase.h"
#include "MediaConstraints.h"
-#include <wtf/HashMap.h>
#include <wtf/Vector.h>
namespace WebCore {
-class Dictionary;
-class MediaConstraintsImpl : public MediaConstraints {
-public:
- static PassRefPtr<MediaConstraintsImpl> create();
- static PassRefPtr<MediaConstraintsImpl> create(const Dictionary&, ExceptionCode&);
+struct MediaConstraintsData {
+ MediaConstraintsData() = default;
+ MediaConstraintsData(MediaTrackConstraintSetMap&& mandatoryConstraints, Vector<MediaTrackConstraintSetMap>&& advancedConstraints, bool isValid)
+ : mandatoryConstraints(WTFMove(mandatoryConstraints))
+ , advancedConstraints(WTFMove(advancedConstraints))
+ , isValid(isValid)
+ {
+ }
+
+ MediaTrackConstraintSetMap mandatoryConstraints;
+ Vector<MediaTrackConstraintSetMap> advancedConstraints;
+ bool isValid { false };
+};
- virtual ~MediaConstraintsImpl();
- bool initialize(const Dictionary&);
+class MediaConstraintsImpl final : public MediaConstraints {
+public:
+ static Ref<MediaConstraintsImpl> create(MediaTrackConstraintSetMap&& mandatoryConstraints, Vector<MediaTrackConstraintSetMap>&& advancedConstraints, bool isValid);
+ WEBCORE_EXPORT static Ref<MediaConstraintsImpl> create(const MediaConstraintsData&);
- virtual void getMandatoryConstraints(Vector<MediaConstraint>&) const override;
- virtual void getOptionalConstraints(Vector<MediaConstraint>&) const override;
+ MediaConstraintsImpl() = default;
+ virtual ~MediaConstraintsImpl() = default;
- virtual bool getMandatoryConstraintValue(const String& name, String& value) const override;
- virtual bool getOptionalConstraintValue(const String& name, String& value) const override;
+ const MediaTrackConstraintSetMap& mandatoryConstraints() const final { return m_data.mandatoryConstraints; }
+ const Vector<MediaTrackConstraintSetMap>& advancedConstraints() const final { return m_data.advancedConstraints; }
+ bool isValid() const final { return m_data.isValid; }
+ const MediaConstraintsData& data() const { return m_data; }
private:
- MediaConstraintsImpl() { }
+ MediaConstraintsImpl(MediaTrackConstraintSetMap&& mandatoryConstraints, Vector<MediaTrackConstraintSetMap>&& advancedConstraints, bool isValid)
+ : m_data({ WTFMove(mandatoryConstraints), WTFMove(advancedConstraints), isValid })
+ {
+ }
+ explicit MediaConstraintsImpl(const MediaConstraintsData& data)
+ : m_data(data)
+ {
+ }
- HashMap<String, String> m_mandatoryConstraints;
- Vector<MediaConstraint> m_optionalConstraints;
+ MediaConstraintsData m_data;
};
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaConstraintsImpl_h
-
-
diff --git a/Source/WebCore/Modules/mediastream/MediaTrackConstraint.cpp b/Source/WebCore/Modules/mediastream/MediaDeviceInfo.cpp
index 453fcebc1..fe760d917 100644
--- a/Source/WebCore/Modules/mediastream/MediaTrackConstraint.cpp
+++ b/Source/WebCore/Modules/mediastream/MediaDeviceInfo.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,42 +10,38 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
+#include "MediaDeviceInfo.h"
#if ENABLE(MEDIA_STREAM)
-#include "MediaTrackConstraint.h"
-
-using namespace JSC;
-
namespace WebCore {
-RefPtr<MediaTrackConstraint> MediaTrackConstraint::create(const Dictionary& constraint)
-{
- return adoptRef(new MediaTrackConstraint(constraint));
-}
-
-MediaTrackConstraint::MediaTrackConstraint(const Dictionary& constraint)
- : m_constraint(constraint)
+inline MediaDeviceInfo::MediaDeviceInfo(ScriptExecutionContext* context, const String& label, const String& deviceId, const String& groupId, Kind kind)
+ : ContextDestructionObserver(context)
+ , m_label(label)
+ , m_deviceId(deviceId)
+ , m_groupId(groupId)
+ , m_kind(kind)
{
}
-MediaTrackConstraint::~MediaTrackConstraint()
+Ref<MediaDeviceInfo> MediaDeviceInfo::create(ScriptExecutionContext* context, const String& label, const String& deviceId, const String& groupId, Kind kind)
{
+ return adoptRef(*new MediaDeviceInfo(context, label, deviceId, groupId, kind));
}
} // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/SourceInfo.h b/Source/WebCore/Modules/mediastream/MediaDeviceInfo.h
index 23f162e37..fc6890433 100644
--- a/Source/WebCore/Modules/mediastream/SourceInfo.h
+++ b/Source/WebCore/Modules/mediastream/MediaDeviceInfo.h
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -24,36 +23,38 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef SourceInfo_h
-#define SourceInfo_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
-#include "MediaStreamTrackSourcesRequestClient.h"
+#include "ContextDestructionObserver.h"
#include "ScriptWrappable.h"
-#include <wtf/Forward.h>
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
-class SourceInfo : public RefCounted<SourceInfo>, public ScriptWrappable {
+class MediaDeviceInfo : public RefCounted<MediaDeviceInfo>, public ScriptWrappable, private ContextDestructionObserver {
public:
- static PassRefPtr<SourceInfo> create(PassRefPtr<TrackSourceInfo>);
+ enum class Kind { Audioinput, Audiooutput, Videoinput };
- const AtomicString& sourceId() const { return m_trackSourceInfo->id(); }
- const AtomicString& label() const { return m_trackSourceInfo->label(); }
- const AtomicString& kind() const;
+ static Ref<MediaDeviceInfo> create(ScriptExecutionContext*, const String&, const String&, const String&, Kind);
+
+ const String& label() const { return m_label; }
+ const String& deviceId() const { return m_deviceId; }
+ const String& groupId() const { return m_groupId; }
+ Kind kind() const { return m_kind; }
private:
- SourceInfo(PassRefPtr<TrackSourceInfo>);
+ MediaDeviceInfo(ScriptExecutionContext*, const String&, const String&, const String&, Kind);
- RefPtr<TrackSourceInfo> m_trackSourceInfo;
+ const String m_label;
+ const String m_deviceId;
+ const String m_groupId;
+ const Kind m_kind;
};
-} // namespace WebCore
+typedef Vector<RefPtr<MediaDeviceInfo>> MediaDeviceInfoVector;
-#endif // SourceInfo_h
+}
#endif
diff --git a/Source/WebCore/Modules/mediastream/MediaDeviceInfo.idl b/Source/WebCore/Modules/mediastream/MediaDeviceInfo.idl
new file mode 100644
index 000000000..927cd7263
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaDeviceInfo.idl
@@ -0,0 +1,42 @@
+/*
+* Copyright (C) 2015 Apple Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+[
+ Conditional=MEDIA_STREAM,
+ Constructor(DOMString deviceId, DOMString label, DOMString groupId, MediaDeviceKind kind),
+ JSGenerateToJSObject,
+ NoInterfaceObject,
+] interface MediaDeviceInfo {
+ readonly attribute DOMString deviceId;
+ readonly attribute DOMString groupId;
+ readonly attribute MediaDeviceKind kind;
+ readonly attribute DOMString label;
+};
+
+enum MediaDeviceKind {
+ "audioinput",
+ "audiooutput",
+ "videoinput"
+};
diff --git a/Source/WebCore/Modules/mediastream/MediaDevices.cpp b/Source/WebCore/Modules/mediastream/MediaDevices.cpp
new file mode 100644
index 000000000..db1ac33e0
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaDevices.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MediaDevices.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "Document.h"
+#include "MediaConstraintsImpl.h"
+#include "MediaDevicesRequest.h"
+#include "MediaTrackSupportedConstraints.h"
+#include "RealtimeMediaSourceCenter.h"
+#include "UserMediaRequest.h"
+
+namespace WebCore {
+
+inline MediaDevices::MediaDevices(Document& document)
+ : ContextDestructionObserver(&document)
+{
+}
+
+Ref<MediaDevices> MediaDevices::create(Document& document)
+{
+ return adoptRef(*new MediaDevices(document));
+}
+
+Document* MediaDevices::document() const
+{
+ return downcast<Document>(scriptExecutionContext());
+}
+
+static Ref<MediaConstraintsImpl> createMediaConstraintsImpl(const Variant<bool, MediaTrackConstraints>& constraints)
+{
+ return WTF::switchOn(constraints,
+ [&] (bool constraints) {
+ return MediaConstraintsImpl::create({ }, { }, constraints);
+ },
+ [&] (const MediaTrackConstraints& constraints) {
+ return createMediaConstraintsImpl(constraints);
+ }
+ );
+}
+
+ExceptionOr<void> MediaDevices::getUserMedia(const StreamConstraints& constraints, Promise&& promise) const
+{
+ auto* document = this->document();
+ if (!document)
+ return Exception { INVALID_STATE_ERR };
+ return UserMediaRequest::start(*document, createMediaConstraintsImpl(constraints.audio), createMediaConstraintsImpl(constraints.video), WTFMove(promise));
+}
+
+void MediaDevices::enumerateDevices(EnumerateDevicesPromise&& promise) const
+{
+ auto* document = this->document();
+ if (!document)
+ return;
+ MediaDevicesRequest::create(*document, WTFMove(promise))->start();
+}
+
+MediaTrackSupportedConstraints MediaDevices::getSupportedConstraints()
+{
+ auto& supported = RealtimeMediaSourceCenter::singleton().supportedConstraints();
+ MediaTrackSupportedConstraints result;
+ result.width = supported.supportsWidth();
+ result.height = supported.supportsHeight();
+ result.aspectRatio = supported.supportsAspectRatio();
+ result.frameRate = supported.supportsFrameRate();
+ result.facingMode = supported.supportsFacingMode();
+ result.volume = supported.supportsVolume();
+ result.sampleRate = supported.supportsSampleRate();
+ result.sampleSize = supported.supportsSampleSize();
+ result.echoCancellation = supported.supportsEchoCancellation();
+ result.deviceId = supported.supportsDeviceId();
+ result.groupId = supported.supportsGroupId();
+ return result;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescriptionRequestImpl.h b/Source/WebCore/Modules/mediastream/MediaDevices.h
index c5624b1c5..0d90d259d 100644
--- a/Source/WebCore/Modules/mediastream/RTCSessionDescriptionRequestImpl.h
+++ b/Source/WebCore/Modules/mediastream/MediaDevices.h
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -12,7 +12,7 @@
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
+ * 3. Neither the name of Ericsson nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@@ -29,44 +29,43 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCSessionDescriptionRequestImpl_h
-#define RTCSessionDescriptionRequestImpl_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
-#include "ActiveDOMObject.h"
-#include "RTCSessionDescriptionRequest.h"
+#include "ExceptionOr.h"
+#include "JSDOMPromise.h"
+#include "MediaTrackConstraints.h"
namespace WebCore {
-class RTCPeerConnectionErrorCallback;
-class RTCPeerConnection;
-class RTCSessionDescriptionCallback;
+class Document;
+class MediaDeviceInfo;
+class MediaStream;
-class RTCSessionDescriptionRequestImpl : public RTCSessionDescriptionRequest, public ActiveDOMObject {
-public:
- static PassRefPtr<RTCSessionDescriptionRequestImpl> create(ScriptExecutionContext*, PassRefPtr<RTCSessionDescriptionCallback>, PassRefPtr<RTCPeerConnectionErrorCallback>);
- virtual ~RTCSessionDescriptionRequestImpl();
+struct MediaTrackSupportedConstraints;
- virtual void requestSucceeded(PassRefPtr<RTCSessionDescriptionDescriptor>) override;
- virtual void requestFailed(const String& error) override;
+class MediaDevices : public ScriptWrappable, public RefCounted<MediaDevices>, public ContextDestructionObserver {
+public:
+ static Ref<MediaDevices> create(Document&);
- // ActiveDOMObject
- virtual void stop() override;
+ Document* document() const;
-private:
- RTCSessionDescriptionRequestImpl(ScriptExecutionContext*, PassRefPtr<RTCSessionDescriptionCallback>, PassRefPtr<RTCPeerConnectionErrorCallback>);
+ using Promise = DOMPromise<IDLInterface<MediaStream>>;
+ using EnumerateDevicesPromise = DOMPromise<IDLSequence<IDLInterface<MediaDeviceInfo>>>;
- void clear();
+ struct StreamConstraints {
+ Variant<bool, MediaTrackConstraints> video;
+ Variant<bool, MediaTrackConstraints> audio;
+ };
+ ExceptionOr<void> getUserMedia(const StreamConstraints&, Promise&&) const;
+ void enumerateDevices(EnumerateDevicesPromise&&) const;
+ MediaTrackSupportedConstraints getSupportedConstraints();
- RefPtr<RTCSessionDescriptionCallback> m_successCallback;
- RefPtr<RTCPeerConnectionErrorCallback> m_errorCallback;
+private:
+ explicit MediaDevices(Document&);
};
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCSessionDescriptionRequestImpl_h
-
-
diff --git a/Source/WebCore/Modules/mediastream/MediaDevices.idl b/Source/WebCore/Modules/mediastream/MediaDevices.idl
new file mode 100644
index 000000000..0c0866295
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaDevices.idl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=MEDIA_STREAM,
+ NoInterfaceObject,
+] interface MediaDevices {
+ MediaTrackSupportedConstraints getSupportedConstraints();
+
+ [PrivateIdentifier, PublicIdentifier] Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints);
+ Promise<sequence<MediaDeviceInfo>> enumerateDevices();
+};
+
+[
+ Conditional=MEDIA_STREAM,
+] dictionary MediaStreamConstraints {
+ (boolean or MediaTrackConstraints) video = false;
+ (boolean or MediaTrackConstraints) audio = false;
+};
diff --git a/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp b/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp
new file mode 100644
index 000000000..c89d43d79
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "MediaDevicesEnumerationRequest.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "CaptureDevice.h"
+#include "Document.h"
+#include "MainFrame.h"
+#include "SecurityOrigin.h"
+#include "UserMediaController.h"
+
+namespace WebCore {
+
+Ref<MediaDevicesEnumerationRequest> MediaDevicesEnumerationRequest::create(Document& document, CompletionHandler&& completionHandler)
+{
+ return adoptRef(*new MediaDevicesEnumerationRequest(document, WTFMove(completionHandler)));
+}
+
+MediaDevicesEnumerationRequest::MediaDevicesEnumerationRequest(ScriptExecutionContext& context, CompletionHandler&& completionHandler)
+ : ContextDestructionObserver(&context)
+ , m_completionHandler(WTFMove(completionHandler))
+{
+}
+
+MediaDevicesEnumerationRequest::~MediaDevicesEnumerationRequest()
+{
+}
+
+SecurityOrigin* MediaDevicesEnumerationRequest::userMediaDocumentOrigin() const
+{
+ if (!scriptExecutionContext())
+ return nullptr;
+
+ return scriptExecutionContext()->securityOrigin();
+}
+
+SecurityOrigin* MediaDevicesEnumerationRequest::topLevelDocumentOrigin() const
+{
+ if (!scriptExecutionContext())
+ return nullptr;
+
+ if (Frame* frame = downcast<Document>(*scriptExecutionContext()).frame()) {
+ if (frame->isMainFrame())
+ return nullptr;
+ }
+
+ return &scriptExecutionContext()->topOrigin();
+}
+
+void MediaDevicesEnumerationRequest::contextDestroyed()
+{
+ cancel();
+ ContextDestructionObserver::contextDestroyed();
+}
+
+void MediaDevicesEnumerationRequest::start()
+{
+ ASSERT(scriptExecutionContext());
+
+ auto& document = downcast<Document>(*scriptExecutionContext());
+ auto* controller = UserMediaController::from(document.page());
+ if (!controller)
+ return;
+
+ Ref<MediaDevicesEnumerationRequest> protectedThis(*this);
+ controller->enumerateMediaDevices(*this);
+}
+
+void MediaDevicesEnumerationRequest::cancel()
+{
+ m_completionHandler = nullptr;
+}
+
+void MediaDevicesEnumerationRequest::setDeviceInfo(const Vector<CaptureDevice>& deviceList, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess)
+{
+ m_deviceList = deviceList;
+ m_deviceIdentifierHashSalt = deviceIdentifierHashSalt;
+ m_originHasPersistentAccess = originHasPersistentAccess;
+
+ if (m_completionHandler)
+ m_completionHandler(m_deviceList, m_deviceIdentifierHashSalt, m_originHasPersistentAccess);
+ m_completionHandler = nullptr;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.h b/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.h
new file mode 100644
index 000000000..ec4df0054
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaDevicesEnumerationRequest.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "ActiveDOMObject.h"
+#include <functional>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class CaptureDevice;
+class Document;
+class SecurityOrigin;
+
+class MediaDevicesEnumerationRequest final : public ContextDestructionObserver, public RefCounted<MediaDevicesEnumerationRequest> {
+public:
+ using CompletionHandler = std::function<void(const Vector<CaptureDevice>&, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess)>;
+
+ static Ref<MediaDevicesEnumerationRequest> create(Document&, CompletionHandler&&);
+
+ virtual ~MediaDevicesEnumerationRequest();
+
+ void start();
+ void cancel();
+
+ WEBCORE_EXPORT void setDeviceInfo(const Vector<CaptureDevice>&, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess);
+
+ WEBCORE_EXPORT SecurityOrigin* userMediaDocumentOrigin() const;
+ WEBCORE_EXPORT SecurityOrigin* topLevelDocumentOrigin() const;
+
+private:
+ MediaDevicesEnumerationRequest(ScriptExecutionContext&, CompletionHandler&&);
+
+ // ContextDestructionObserver
+ void contextDestroyed() final;
+
+ CompletionHandler m_completionHandler;
+ Vector<CaptureDevice> m_deviceList;
+ String m_deviceIdentifierHashSalt;
+ bool m_originHasPersistentAccess { false };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp b/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp
new file mode 100644
index 000000000..4a0b3e19e
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "MediaDevicesRequest.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "CaptureDevice.h"
+#include "Document.h"
+#include "Frame.h"
+#include "JSMediaDeviceInfo.h"
+#include "MediaDevicesEnumerationRequest.h"
+#include "SecurityOrigin.h"
+#include "UserMediaController.h"
+#include <wtf/MainThread.h>
+#include <wtf/SHA1.h>
+
+namespace WebCore {
+
+inline MediaDevicesRequest::MediaDevicesRequest(Document& document, MediaDevices::EnumerateDevicesPromise&& promise)
+ : ContextDestructionObserver(&document)
+ , m_promise(WTFMove(promise))
+{
+}
+
+Ref<MediaDevicesRequest> MediaDevicesRequest::create(Document& document, MediaDevices::EnumerateDevicesPromise&& promise)
+{
+ return adoptRef(*new MediaDevicesRequest(document, WTFMove(promise)));
+}
+
+MediaDevicesRequest::~MediaDevicesRequest()
+{
+ if (m_enumerationRequest)
+ m_enumerationRequest->cancel();
+}
+
+SecurityOrigin* MediaDevicesRequest::securityOrigin() const
+{
+ if (scriptExecutionContext())
+ return scriptExecutionContext()->securityOrigin();
+
+ return nullptr;
+}
+
+void MediaDevicesRequest::contextDestroyed()
+{
+ if (m_enumerationRequest) {
+ m_enumerationRequest->cancel();
+ m_enumerationRequest = nullptr;
+ }
+ ContextDestructionObserver::contextDestroyed();
+}
+
+void MediaDevicesRequest::start()
+{
+ RefPtr<MediaDevicesRequest> protectedThis = this;
+ auto completion = [this, protectedThis = WTFMove(protectedThis)] (const Vector<CaptureDevice>& captureDevices, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess) mutable {
+
+ m_enumerationRequest = nullptr;
+
+ if (!scriptExecutionContext())
+ return;
+
+ Document& document = downcast<Document>(*scriptExecutionContext());
+ UserMediaController* controller = UserMediaController::from(document.page());
+ if (!controller)
+ return;
+
+ m_idHashSalt = deviceIdentifierHashSalt;
+
+ Vector<RefPtr<MediaDeviceInfo>> devices;
+ for (auto& deviceInfo : captureDevices) {
+ auto label = emptyString();
+ if (originHasPersistentAccess || document.hasHadActiveMediaStreamTrack())
+ label = deviceInfo.label();
+
+ auto id = hashID(deviceInfo.persistentId());
+ if (id.isEmpty())
+ continue;
+
+ auto groupId = hashID(deviceInfo.groupId());
+ auto deviceType = deviceInfo.type() == CaptureDevice::DeviceType::Audio ? MediaDeviceInfo::Kind::Audioinput : MediaDeviceInfo::Kind::Videoinput;
+ devices.append(MediaDeviceInfo::create(scriptExecutionContext(), label, id, groupId, deviceType));
+ }
+
+ callOnMainThread([protectedThis = makeRef(*this), devices = WTFMove(devices)]() mutable {
+ protectedThis->m_promise.resolve(devices);
+ });
+ };
+
+ m_enumerationRequest = MediaDevicesEnumerationRequest::create(*downcast<Document>(scriptExecutionContext()), WTFMove(completion));
+ m_enumerationRequest->start();
+}
+
+static void hashString(SHA1& sha1, const String& string)
+{
+ if (string.isEmpty())
+ return;
+
+ if (string.is8Bit() && string.containsOnlyASCII()) {
+ const uint8_t nullByte = 0;
+ sha1.addBytes(string.characters8(), string.length());
+ sha1.addBytes(&nullByte, 1);
+ return;
+ }
+
+ auto utf8 = string.utf8();
+ sha1.addBytes(reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length() + 1); // Include terminating null byte.
+}
+
+String MediaDevicesRequest::hashID(const String& id)
+{
+ if (id.isEmpty() || m_idHashSalt.isEmpty())
+ return emptyString();
+
+ SHA1 sha1;
+
+ hashString(sha1, id);
+ hashString(sha1, m_idHashSalt);
+
+ SHA1::Digest digest;
+ sha1.computeHash(digest);
+
+ return SHA1::hexDigest(digest).data();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/MediaTrackConstraint.h b/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h
index 2a93fc763..d47002fd9 100644
--- a/Source/WebCore/Modules/mediastream/MediaTrackConstraint.h
+++ b/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -13,48 +13,53 @@
* THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-#ifndef MediaTrackConstraint_h
-#define MediaTrackConstraint_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
-#include "Dictionary.h"
-#include "ScriptWrappable.h"
-#include <wtf/RefCounted.h>
-
-namespace Deprecated {
-class ScriptValue;
-}
+#include "MediaDevices.h"
namespace WebCore {
-class MediaTrackConstraint : public RefCounted<MediaTrackConstraint>, public ScriptWrappable {
+class Document;
+class MediaDevicesEnumerationRequest;
+class SecurityOrigin;
+
+class MediaDevicesRequest : public RefCounted<MediaDevicesRequest>, private ContextDestructionObserver {
public:
- static RefPtr<MediaTrackConstraint> create(const Dictionary&);
+ static Ref<MediaDevicesRequest> create(Document&, MediaDevices::EnumerateDevicesPromise&&);
- virtual ~MediaTrackConstraint();
+ virtual ~MediaDevicesRequest();
- const Dictionary& constraint() const { return m_constraint; }
+ void start();
+
+ SecurityOrigin* securityOrigin() const;
private:
- explicit MediaTrackConstraint(const Dictionary&);
-
- const Dictionary& m_constraint;
+ MediaDevicesRequest(Document&, MediaDevices::EnumerateDevicesPromise&&);
+
+ void contextDestroyed() final;
+
+ String hashID(const String&);
+
+ MediaDevices::EnumerateDevicesPromise m_promise;
+ RefPtr<MediaDevicesRequest> m_protector;
+ RefPtr<MediaDevicesEnumerationRequest> m_enumerationRequest;
+
+ String m_idHashSalt;
};
} // namespace WebCore
-#endif // MediaTrackConstraint_h
-
-#endif
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp
new file mode 100644
index 000000000..14ee0f5d3
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp
@@ -0,0 +1,874 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_RTC)
+#include "MediaEndpointPeerConnection.h"
+
+#include "EventNames.h"
+#include "JSRTCSessionDescription.h"
+#include "MediaEndpointSessionConfiguration.h"
+#include "MediaEndpointSessionDescription.h"
+#include "MediaStream.h"
+#include "MediaStreamEvent.h"
+#include "MediaStreamTrack.h"
+#include "NotImplemented.h"
+#include "PeerMediaDescription.h"
+#include "RTCConfiguration.h"
+#include "RTCIceCandidate.h"
+#include "RTCIceCandidateEvent.h"
+#include "RTCOfferAnswerOptions.h"
+#include "RTCPeerConnection.h"
+#include "RTCRtpTransceiver.h"
+#include "RTCTrackEvent.h"
+#include "SDPProcessor.h"
+#include <wtf/MainThread.h>
+#include <wtf/text/Base64.h>
+
+namespace WebCore {
+
+using namespace PeerConnection;
+using namespace PeerConnectionStates;
+
+using MediaDescriptionVector = Vector<PeerMediaDescription>;
+using RtpTransceiverVector = Vector<RefPtr<RTCRtpTransceiver>>;
+
+// We use base64 to generate the random strings so we need a size that avoids padding to get ice-chars.
+static const size_t cnameSize = 18;
+// Size range from 4 to 256 ice-chars defined in RFC 5245.
+static const size_t iceUfragSize = 6;
+// Size range from 22 to 256 ice-chars defined in RFC 5245.
+static const size_t icePasswordSize = 24;
+
+#if !USE(LIBWEBRTC)
+static std::unique_ptr<PeerConnectionBackend> createMediaEndpointPeerConnection(RTCPeerConnection& peerConnection)
+{
+ return std::unique_ptr<PeerConnectionBackend>(new MediaEndpointPeerConnection(peerConnection));
+}
+
+CreatePeerConnectionBackend PeerConnectionBackend::create = createMediaEndpointPeerConnection;
+#endif
+
+static String randomString(size_t size)
+{
+ unsigned char randomValues[size];
+ cryptographicallyRandomValues(randomValues, size);
+ return base64Encode(randomValues, size);
+}
+
+MediaEndpointPeerConnection::MediaEndpointPeerConnection(RTCPeerConnection& peerConnection)
+ : PeerConnectionBackend(peerConnection)
+ , m_mediaEndpoint(MediaEndpoint::create(*this))
+ , m_sdpProcessor(std::make_unique<SDPProcessor>(m_peerConnection.scriptExecutionContext()))
+ , m_cname(randomString(cnameSize))
+ , m_iceUfrag(randomString(iceUfragSize))
+ , m_icePassword(randomString(icePasswordSize))
+{
+ ASSERT(m_mediaEndpoint);
+
+ m_defaultAudioPayloads = m_mediaEndpoint->getDefaultAudioPayloads();
+ m_defaultVideoPayloads = m_mediaEndpoint->getDefaultVideoPayloads();
+
+ // Tasks (see runTask()) will be deferred until we get the DTLS fingerprint.
+ m_mediaEndpoint->generateDtlsInfo();
+}
+
+static RTCRtpTransceiver* matchTransceiver(const RtpTransceiverVector& transceivers, const std::function<bool(RTCRtpTransceiver&)>& matchFunction)
+{
+ for (auto& transceiver : transceivers) {
+ if (matchFunction(*transceiver))
+ return transceiver.get();
+ }
+ return nullptr;
+}
+
+static RTCRtpTransceiver* matchTransceiverByMid(const RtpTransceiverVector& transceivers, const String& mid)
+{
+ return matchTransceiver(transceivers, [&mid] (RTCRtpTransceiver& current) {
+ return current.mid() == mid;
+ });
+}
+
+static bool hasUnassociatedTransceivers(const RtpTransceiverVector& transceivers)
+{
+ return matchTransceiver(transceivers, [] (RTCRtpTransceiver& current) {
+ return current.mid().isNull() && !current.stopped();
+ });
+}
+
+void MediaEndpointPeerConnection::runTask(Function<void ()>&& task)
+{
+ if (m_dtlsFingerprint.isNull()) {
+ // Only one task needs to be deferred since it will hold off any others until completed.
+ ASSERT(!m_initialDeferredTask);
+ m_initialDeferredTask = WTFMove(task);
+ } else
+ callOnMainThread(WTFMove(task));
+}
+
+void MediaEndpointPeerConnection::startRunningTasks()
+{
+ if (!m_initialDeferredTask)
+ return;
+
+ m_initialDeferredTask();
+ m_initialDeferredTask = nullptr;
+}
+
+void MediaEndpointPeerConnection::doCreateOffer(RTCOfferOptions&& options)
+{
+ runTask([this, protectedOptions = WTFMove(options)]() mutable {
+ createOfferTask(protectedOptions);
+ });
+}
+
+void MediaEndpointPeerConnection::createOfferTask(const RTCOfferOptions&)
+{
+ ASSERT(!m_dtlsFingerprint.isEmpty());
+
+ MediaEndpointSessionDescription* localDescription = internalLocalDescription();
+ RefPtr<MediaEndpointSessionConfiguration> configurationSnapshot = localDescription ?
+ localDescription->configuration()->clone() : MediaEndpointSessionConfiguration::create();
+
+ configurationSnapshot->setSessionVersion(m_sdpOfferSessionVersion++);
+
+ auto transceivers = RtpTransceiverVector(m_peerConnection.getTransceivers());
+
+ // Remove any transceiver objects from transceivers that can be matched to an existing media description.
+ for (auto& mediaDescription : configurationSnapshot->mediaDescriptions()) {
+ if (!mediaDescription.port) {
+ // This media description should be recycled.
+ continue;
+ }
+
+ RTCRtpTransceiver* transceiver = matchTransceiverByMid(transceivers, mediaDescription.mid);
+ if (!transceiver)
+ continue;
+
+ mediaDescription.mode = transceiver->directionString();
+ if (transceiver->hasSendingDirection()) {
+ auto& sender = transceiver->sender();
+
+ mediaDescription.mediaStreamId = sender.mediaStreamIds()[0];
+ mediaDescription.mediaStreamTrackId = sender.trackId();
+ }
+
+ transceivers.removeFirst(transceiver);
+ }
+
+ // Add media descriptions for remaining transceivers.
+ for (auto& transceiver : transceivers) {
+ PeerMediaDescription mediaDescription;
+ auto& sender = transceiver->sender();
+
+ mediaDescription.mode = transceiver->directionString();
+ mediaDescription.mid = transceiver->provisionalMid();
+ mediaDescription.mediaStreamId = sender.mediaStreamIds()[0];
+ mediaDescription.type = sender.trackKind();
+ mediaDescription.payloads = sender.trackKind() == "audio" ? m_defaultAudioPayloads : m_defaultVideoPayloads;
+ mediaDescription.dtlsFingerprintHashFunction = m_dtlsFingerprintFunction;
+ mediaDescription.dtlsFingerprint = m_dtlsFingerprint;
+ mediaDescription.cname = m_cname;
+ mediaDescription.addSsrc(cryptographicallyRandomNumber());
+ mediaDescription.iceUfrag = m_iceUfrag;
+ mediaDescription.icePassword = m_icePassword;
+
+ if (sender.track())
+ mediaDescription.mediaStreamTrackId = sender.trackId();
+
+ configurationSnapshot->addMediaDescription(WTFMove(mediaDescription));
+ }
+
+ String sdp;
+ SDPProcessor::Result result = m_sdpProcessor->generate(*configurationSnapshot, sdp);
+ if (result != SDPProcessor::Result::Success) {
+ createOfferFailed(Exception { OperationError, "SDPProcessor internal error" });
+ return;
+ }
+ createOfferSucceeded(WTFMove(sdp));
+}
+
+void MediaEndpointPeerConnection::doCreateAnswer(RTCAnswerOptions&& options)
+{
+ runTask([this, protectedOptions = WTFMove(options)]() mutable {
+ createAnswerTask(protectedOptions);
+ });
+}
+
+void MediaEndpointPeerConnection::createAnswerTask(const RTCAnswerOptions&)
+{
+ ASSERT(!m_dtlsFingerprint.isEmpty());
+
+ if (!internalRemoteDescription()) {
+ createAnswerFailed(Exception { INVALID_STATE_ERR, "No remote description set" });
+ return;
+ }
+
+ MediaEndpointSessionDescription* localDescription = internalLocalDescription();
+ RefPtr<MediaEndpointSessionConfiguration> configurationSnapshot = localDescription ?
+ localDescription->configuration()->clone() : MediaEndpointSessionConfiguration::create();
+
+ configurationSnapshot->setSessionVersion(m_sdpAnswerSessionVersion++);
+
+ auto transceivers = RtpTransceiverVector(m_peerConnection.getTransceivers());
+ auto& remoteMediaDescriptions = internalRemoteDescription()->configuration()->mediaDescriptions();
+
+ for (unsigned i = 0; i < remoteMediaDescriptions.size(); ++i) {
+ auto& remoteMediaDescription = remoteMediaDescriptions[i];
+
+ auto* transceiver = matchTransceiverByMid(transceivers, remoteMediaDescription.mid);
+ if (!transceiver) {
+ LOG_ERROR("Could not find a matching transceiver for remote description while creating answer");
+ continue;
+ }
+
+ if (i >= configurationSnapshot->mediaDescriptions().size()) {
+ PeerMediaDescription newMediaDescription;
+
+ auto& sender = transceiver->sender();
+ if (sender.track()) {
+ if (sender.mediaStreamIds().size())
+ newMediaDescription.mediaStreamId = sender.mediaStreamIds()[0];
+ newMediaDescription.mediaStreamTrackId = sender.trackId();
+ newMediaDescription.addSsrc(cryptographicallyRandomNumber());
+ }
+
+ newMediaDescription.mode = transceiver->directionString();
+ newMediaDescription.type = remoteMediaDescription.type;
+ newMediaDescription.mid = remoteMediaDescription.mid;
+ newMediaDescription.dtlsSetup = remoteMediaDescription.dtlsSetup == "active" ? "passive" : "active";
+ newMediaDescription.dtlsFingerprintHashFunction = m_dtlsFingerprintFunction;
+ newMediaDescription.dtlsFingerprint = m_dtlsFingerprint;
+ newMediaDescription.cname = m_cname;
+ newMediaDescription.iceUfrag = m_iceUfrag;
+ newMediaDescription.icePassword = m_icePassword;
+
+ configurationSnapshot->addMediaDescription(WTFMove(newMediaDescription));
+ }
+
+ PeerMediaDescription& localMediaDescription = configurationSnapshot->mediaDescriptions()[i];
+
+ localMediaDescription.payloads = remoteMediaDescription.payloads;
+ localMediaDescription.rtcpMux = remoteMediaDescription.rtcpMux;
+
+ if (!localMediaDescription.ssrcs.size())
+ localMediaDescription.addSsrc(cryptographicallyRandomNumber());
+
+ if (localMediaDescription.dtlsSetup == "actpass")
+ localMediaDescription.dtlsSetup = "passive";
+
+ transceivers.removeFirst(transceiver);
+ }
+
+ // Unassociated (non-stopped) transceivers need to be negotiated in a follow-up offer.
+ if (hasUnassociatedTransceivers(transceivers))
+ markAsNeedingNegotiation();
+
+ String sdp;
+ SDPProcessor::Result result = m_sdpProcessor->generate(*configurationSnapshot, sdp);
+ if (result != SDPProcessor::Result::Success) {
+ createAnswerFailed(Exception { OperationError, "SDPProcessor internal error" });
+ return;
+ }
+ createAnswerSucceeded(WTFMove(sdp));
+}
+
+static RealtimeMediaSourceMap createSourceMap(const MediaDescriptionVector& remoteMediaDescriptions, unsigned localMediaDescriptionCount, const RtpTransceiverVector& transceivers)
+{
+ RealtimeMediaSourceMap sourceMap;
+
+ for (unsigned i = 0; i < remoteMediaDescriptions.size() && i < localMediaDescriptionCount; ++i) {
+ auto& remoteMediaDescription = remoteMediaDescriptions[i];
+ if (remoteMediaDescription.type != "audio" && remoteMediaDescription.type != "video")
+ continue;
+
+ RTCRtpTransceiver* transceiver = matchTransceiverByMid(transceivers, remoteMediaDescription.mid);
+ if (transceiver) {
+ if (transceiver->hasSendingDirection() && transceiver->sender().track())
+ sourceMap.set(transceiver->mid(), &transceiver->sender().track()->source());
+ }
+ }
+
+ return sourceMap;
+}
+
+void MediaEndpointPeerConnection::doSetLocalDescription(RTCSessionDescription& description)
+{
+ runTask([this, protectedDescription = RefPtr<RTCSessionDescription>(&description)]() mutable {
+ setLocalDescriptionTask(WTFMove(protectedDescription));
+ });
+}
+
+void MediaEndpointPeerConnection::setLocalDescriptionTask(RefPtr<RTCSessionDescription>&& description)
+{
+ if (m_peerConnection.internalSignalingState() == SignalingState::Closed)
+ return;
+
+ auto result = MediaEndpointSessionDescription::create(WTFMove(description), *m_sdpProcessor);
+ if (result.hasException()) {
+ setLocalDescriptionFailed(result.releaseException());
+ return;
+ }
+ auto newDescription = result.releaseReturnValue();
+
+ const RtpTransceiverVector& transceivers = m_peerConnection.getTransceivers();
+ const MediaDescriptionVector& mediaDescriptions = newDescription->configuration()->mediaDescriptions();
+ MediaEndpointSessionDescription* localDescription = internalLocalDescription();
+ unsigned previousNumberOfMediaDescriptions = localDescription ? localDescription->configuration()->mediaDescriptions().size() : 0;
+ bool hasNewMediaDescriptions = mediaDescriptions.size() > previousNumberOfMediaDescriptions;
+ bool isInitiator = newDescription->type() == RTCSessionDescription::SdpType::Offer;
+
+ if (hasNewMediaDescriptions) {
+ MediaEndpoint::UpdateResult result = m_mediaEndpoint->updateReceiveConfiguration(newDescription->configuration(), isInitiator);
+
+ if (result == MediaEndpoint::UpdateResult::SuccessWithIceRestart) {
+ if (m_peerConnection.internalIceGatheringState() != IceGatheringState::Gathering)
+ m_peerConnection.updateIceGatheringState(IceGatheringState::Gathering);
+
+ if (m_peerConnection.internalIceConnectionState() != IceConnectionState::Completed)
+ m_peerConnection.updateIceConnectionState(IceConnectionState::Connected);
+
+ LOG_ERROR("ICE restart is not implemented");
+ notImplemented();
+
+ } else if (result == MediaEndpoint::UpdateResult::Failed) {
+ setLocalDescriptionFailed(Exception { OperationError, "Unable to apply session description" });
+ return;
+ }
+
+ // Associate media descriptions with transceivers (set provisional mid to 'final' mid).
+ for (auto& mediaDescription : mediaDescriptions) {
+ RTCRtpTransceiver* transceiver = matchTransceiver(transceivers, [&mediaDescription] (RTCRtpTransceiver& current) {
+ return current.provisionalMid() == mediaDescription.mid;
+ });
+ if (transceiver)
+ transceiver->setMid(transceiver->provisionalMid());
+ }
+ }
+
+ if (internalRemoteDescription()) {
+ MediaEndpointSessionConfiguration* remoteConfiguration = internalRemoteDescription()->configuration();
+ RealtimeMediaSourceMap sendSourceMap = createSourceMap(remoteConfiguration->mediaDescriptions(), mediaDescriptions.size(), transceivers);
+
+ if (m_mediaEndpoint->updateSendConfiguration(remoteConfiguration, sendSourceMap, isInitiator) == MediaEndpoint::UpdateResult::Failed) {
+ setLocalDescriptionFailed(Exception { OperationError, "Unable to apply session description" });
+ return;
+ }
+ }
+
+ if (!hasUnassociatedTransceivers(transceivers))
+ clearNegotiationNeededState();
+
+ SignalingState newSignalingState;
+
+ // Update state and local descriptions according to setLocal/RemoteDescription processing model
+ switch (newDescription->type()) {
+ case RTCSessionDescription::SdpType::Offer:
+ m_pendingLocalDescription = WTFMove(newDescription);
+ newSignalingState = SignalingState::HaveLocalOffer;
+ break;
+
+ case RTCSessionDescription::SdpType::Answer:
+ m_currentLocalDescription = WTFMove(newDescription);
+ m_currentRemoteDescription = m_pendingRemoteDescription;
+ m_pendingLocalDescription = nullptr;
+ m_pendingRemoteDescription = nullptr;
+ newSignalingState = SignalingState::Stable;
+ break;
+
+ case RTCSessionDescription::SdpType::Rollback:
+ m_pendingLocalDescription = nullptr;
+ newSignalingState = SignalingState::Stable;
+ break;
+
+ case RTCSessionDescription::SdpType::Pranswer:
+ m_pendingLocalDescription = WTFMove(newDescription);
+ newSignalingState = SignalingState::HaveLocalPrAnswer;
+ break;
+ }
+
+ updateSignalingState(newSignalingState);
+
+ if (m_peerConnection.internalIceGatheringState() == IceGatheringState::New && mediaDescriptions.size())
+ m_peerConnection.updateIceGatheringState(IceGatheringState::Gathering);
+
+ markAsNeedingNegotiation();
+ setLocalDescriptionSucceeded();
+}
+
+RefPtr<RTCSessionDescription> MediaEndpointPeerConnection::localDescription() const
+{
+ return createRTCSessionDescription(internalLocalDescription());
+}
+
+RefPtr<RTCSessionDescription> MediaEndpointPeerConnection::currentLocalDescription() const
+{
+ return createRTCSessionDescription(m_currentLocalDescription.get());
+}
+
+RefPtr<RTCSessionDescription> MediaEndpointPeerConnection::pendingLocalDescription() const
+{
+ return createRTCSessionDescription(m_pendingLocalDescription.get());
+}
+
+void MediaEndpointPeerConnection::doSetRemoteDescription(RTCSessionDescription& description)
+{
+ runTask([this, protectedDescription = RefPtr<RTCSessionDescription>(&description)]() mutable {
+ setRemoteDescriptionTask(WTFMove(protectedDescription));
+ });
+}
+
+void MediaEndpointPeerConnection::setRemoteDescriptionTask(RefPtr<RTCSessionDescription>&& description)
+{
+ auto result = MediaEndpointSessionDescription::create(WTFMove(description), *m_sdpProcessor);
+ if (result.hasException()) {
+ setRemoteDescriptionFailed(result.releaseException());
+ return;
+ }
+ auto newDescription = result.releaseReturnValue();
+
+ auto& mediaDescriptions = newDescription->configuration()->mediaDescriptions();
+ for (auto& mediaDescription : mediaDescriptions) {
+ if (mediaDescription.type != "audio" && mediaDescription.type != "video")
+ continue;
+
+ mediaDescription.payloads = m_mediaEndpoint->filterPayloads(mediaDescription.payloads, mediaDescription.type == "audio" ? m_defaultAudioPayloads : m_defaultVideoPayloads);
+ }
+
+ bool isInitiator = newDescription->type() == RTCSessionDescription::SdpType::Answer;
+ const RtpTransceiverVector& transceivers = m_peerConnection.getTransceivers();
+
+ RealtimeMediaSourceMap sendSourceMap;
+ if (internalLocalDescription())
+ sendSourceMap = createSourceMap(mediaDescriptions, internalLocalDescription()->configuration()->mediaDescriptions().size(), transceivers);
+
+ if (m_mediaEndpoint->updateSendConfiguration(newDescription->configuration(), sendSourceMap, isInitiator) == MediaEndpoint::UpdateResult::Failed) {
+ setRemoteDescriptionFailed(Exception { OperationError, "Unable to apply session description" });
+ return;
+ }
+
+ // One legacy MediaStreamEvent will be fired for every new MediaStream created as this remote description is set.
+ Vector<RefPtr<MediaStreamEvent>> legacyMediaStreamEvents;
+
+ for (auto& mediaDescription : mediaDescriptions) {
+ RTCRtpTransceiver* transceiver = matchTransceiverByMid(transceivers, mediaDescription.mid);
+ if (!transceiver) {
+ bool receiveOnlyFlag = false;
+
+ if (mediaDescription.mode == "sendrecv" || mediaDescription.mode == "recvonly") {
+ // Try to match an existing transceiver.
+ transceiver = matchTransceiver(transceivers, [&mediaDescription] (RTCRtpTransceiver& current) {
+ return !current.stopped() && current.mid().isNull() && current.sender().trackKind() == mediaDescription.type;
+ });
+
+ if (transceiver) {
+ // This transceiver was created locally with a provisional mid. Its real mid will now be set by the remote
+ // description so we need to update the mid of the transceiver's muted source to preserve the association.
+ transceiver->setMid(mediaDescription.mid);
+ m_mediaEndpoint->replaceMutedRemoteSourceMid(transceiver->provisionalMid(), mediaDescription.mid);
+ } else
+ receiveOnlyFlag = true;
+ }
+
+ if (!transceiver) {
+ auto sender = RTCRtpSender::create(mediaDescription.type, Vector<String>(), m_peerConnection.senderClient());
+ auto receiver = createReceiver(mediaDescription.mid, mediaDescription.type, mediaDescription.mediaStreamTrackId);
+
+ auto newTransceiver = RTCRtpTransceiver::create(WTFMove(sender), WTFMove(receiver));
+ newTransceiver->setMid(mediaDescription.mid);
+ if (receiveOnlyFlag)
+ newTransceiver->disableSendingDirection();
+
+ transceiver = newTransceiver.ptr();
+ m_peerConnection.addTransceiver(WTFMove(newTransceiver));
+ }
+ }
+
+ if (mediaDescription.mode == "sendrecv" || mediaDescription.mode == "sendonly") {
+ auto& receiver = transceiver->receiver();
+ if (receiver.isDispatched())
+ continue;
+ receiver.setDispatched(true);
+
+ Vector<String> mediaStreamIds;
+ if (!mediaDescription.mediaStreamId.isEmpty())
+ mediaStreamIds.append(mediaDescription.mediaStreamId);
+
+ // A remote track can be associated with 0..* MediaStreams. We create a new stream for
+ // a track in case of an unrecognized stream id, or just add the track if the stream
+ // already exists.
+ HashMap<String, RefPtr<MediaStream>> trackEventMediaStreams;
+ for (auto& id : mediaStreamIds) {
+ if (m_remoteStreamMap.contains(id)) {
+ RefPtr<MediaStream> stream = m_remoteStreamMap.get(id);
+ stream->addTrack(*receiver.track());
+ trackEventMediaStreams.add(id, WTFMove(stream));
+ } else {
+ auto newStream = MediaStream::create(*m_peerConnection.scriptExecutionContext(), MediaStreamTrackVector({ receiver.track() }));
+ m_remoteStreamMap.add(id, newStream.copyRef());
+ legacyMediaStreamEvents.append(MediaStreamEvent::create(eventNames().addstreamEvent, false, false, newStream.copyRef()));
+ trackEventMediaStreams.add(id, WTFMove(newStream));
+ }
+ }
+
+ Vector<RefPtr<MediaStream>> streams;
+ copyValuesToVector(trackEventMediaStreams, streams);
+
+ m_peerConnection.fireEvent(RTCTrackEvent::create(eventNames().trackEvent, false, false,
+ &receiver, receiver.track(), WTFMove(streams), transceiver));
+ }
+ }
+
+ // Fire legacy addstream events.
+ for (auto& event : legacyMediaStreamEvents)
+ m_peerConnection.fireEvent(*event);
+
+ SignalingState newSignalingState;
+
+ // Update state and local descriptions according to setLocal/RemoteDescription processing model
+ switch (newDescription->type()) {
+ case RTCSessionDescription::SdpType::Offer:
+ m_pendingRemoteDescription = WTFMove(newDescription);
+ newSignalingState = SignalingState::HaveRemoteOffer;
+ break;
+
+ case RTCSessionDescription::SdpType::Answer:
+ m_currentRemoteDescription = WTFMove(newDescription);
+ m_currentLocalDescription = m_pendingLocalDescription;
+ m_pendingRemoteDescription = nullptr;
+ m_pendingLocalDescription = nullptr;
+ newSignalingState = SignalingState::Stable;
+ break;
+
+ case RTCSessionDescription::SdpType::Rollback:
+ m_pendingRemoteDescription = nullptr;
+ newSignalingState = SignalingState::Stable;
+ break;
+
+ case RTCSessionDescription::SdpType::Pranswer:
+ m_pendingRemoteDescription = WTFMove(newDescription);
+ newSignalingState = SignalingState::HaveRemotePrAnswer;
+ break;
+ }
+
+ updateSignalingState(newSignalingState);
+ setRemoteDescriptionSucceeded();
+}
+
+RefPtr<RTCSessionDescription> MediaEndpointPeerConnection::remoteDescription() const
+{
+ return createRTCSessionDescription(internalRemoteDescription());
+}
+
+RefPtr<RTCSessionDescription> MediaEndpointPeerConnection::currentRemoteDescription() const
+{
+ return createRTCSessionDescription(m_currentRemoteDescription.get());
+}
+
+RefPtr<RTCSessionDescription> MediaEndpointPeerConnection::pendingRemoteDescription() const
+{
+ return createRTCSessionDescription(m_pendingRemoteDescription.get());
+}
+
+void MediaEndpointPeerConnection::setConfiguration(MediaEndpointConfiguration&& configuration)
+{
+ m_mediaEndpoint->setConfiguration(WTFMove(configuration));
+}
+
+void MediaEndpointPeerConnection::doAddIceCandidate(RTCIceCandidate& rtcCandidate)
+{
+ runTask([this, protectedCandidate = RefPtr<RTCIceCandidate>(&rtcCandidate)]() mutable {
+ addIceCandidateTask(*protectedCandidate);
+ });
+}
+
+void MediaEndpointPeerConnection::addIceCandidateTask(RTCIceCandidate& rtcCandidate)
+{
+ if (!internalRemoteDescription()) {
+ addIceCandidateFailed(Exception { INVALID_STATE_ERR, "No remote description set" });
+ return;
+ }
+
+ auto& remoteMediaDescriptions = internalRemoteDescription()->configuration()->mediaDescriptions();
+ PeerMediaDescription* targetMediaDescription = nullptr;
+
+ // When identifying the target media description, sdpMid takes precedence over sdpMLineIndex
+ // if both are present.
+ if (!rtcCandidate.sdpMid().isNull()) {
+ const String& mid = rtcCandidate.sdpMid();
+ for (auto& description : remoteMediaDescriptions) {
+ if (description.mid == mid) {
+ targetMediaDescription = &description;
+ break;
+ }
+ }
+
+ if (!targetMediaDescription) {
+ addIceCandidateFailed(Exception { OperationError, "sdpMid did not match any media description" });
+ return;
+ }
+ } else if (rtcCandidate.sdpMLineIndex()) {
+ unsigned short sdpMLineIndex = rtcCandidate.sdpMLineIndex().value();
+ if (sdpMLineIndex >= remoteMediaDescriptions.size()) {
+ addIceCandidateFailed(Exception { OperationError, "sdpMLineIndex is out of range" });
+ return;
+ }
+ targetMediaDescription = &remoteMediaDescriptions[sdpMLineIndex];
+ } else {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ auto result = m_sdpProcessor->parseCandidateLine(rtcCandidate.candidate());
+ if (result.parsingStatus() != SDPProcessor::Result::Success) {
+ if (result.parsingStatus() == SDPProcessor::Result::ParseError)
+ addIceCandidateFailed(Exception { OperationError, "Invalid candidate content" });
+ else
+ LOG_ERROR("SDPProcessor internal error");
+ return;
+ }
+
+ ASSERT(targetMediaDescription);
+ m_mediaEndpoint->addRemoteCandidate(result.candidate(), targetMediaDescription->mid, targetMediaDescription->iceUfrag, targetMediaDescription->icePassword);
+
+ targetMediaDescription->addIceCandidate(WTFMove(result.candidate()));
+
+ addIceCandidateSucceeded();
+}
+
+void MediaEndpointPeerConnection::getStats(MediaStreamTrack* track, Ref<DeferredPromise>&& promise)
+{
+ m_mediaEndpoint->getStats(track, WTFMove(promise));
+}
+
+Vector<RefPtr<MediaStream>> MediaEndpointPeerConnection::getRemoteStreams() const
+{
+ Vector<RefPtr<MediaStream>> remoteStreams;
+ copyValuesToVector(m_remoteStreamMap, remoteStreams);
+ return remoteStreams;
+}
+
+Ref<RTCRtpReceiver> MediaEndpointPeerConnection::createReceiver(const String& transceiverMid, const String& trackKind, const String& trackId)
+{
+ RealtimeMediaSource::Type sourceType = trackKind == "audio" ? RealtimeMediaSource::Type::Audio : RealtimeMediaSource::Type::Video;
+
+ // Create a muted remote source that will be unmuted once media starts arriving.
+ auto remoteSource = m_mediaEndpoint->createMutedRemoteSource(transceiverMid, sourceType);
+ auto remoteTrackPrivate = MediaStreamTrackPrivate::create(WTFMove(remoteSource), String(trackId));
+ auto remoteTrack = MediaStreamTrack::create(*m_peerConnection.scriptExecutionContext(), WTFMove(remoteTrackPrivate));
+
+ return RTCRtpReceiver::create(WTFMove(remoteTrack));
+}
+
+std::unique_ptr<RTCDataChannelHandler> MediaEndpointPeerConnection::createDataChannelHandler(const String& label, const RTCDataChannelInit& options)
+{
+ return m_mediaEndpoint->createDataChannelHandler(label, options);
+}
+
+void MediaEndpointPeerConnection::replaceTrack(RTCRtpSender& sender, RefPtr<MediaStreamTrack>&& withTrack, DOMPromise<void>&& promise)
+{
+ RTCRtpTransceiver* transceiver = matchTransceiver(m_peerConnection.getTransceivers(), [&sender] (RTCRtpTransceiver& current) {
+ return &current.sender() == &sender;
+ });
+ ASSERT(transceiver);
+
+ const String& mid = transceiver->mid();
+ if (mid.isNull()) {
+ // Transceiver is not associated with a media description yet.
+ sender.setTrack(WTFMove(withTrack));
+ promise.resolve();
+ return;
+ }
+
+ runTask([this, protectedSender = RefPtr<RTCRtpSender>(&sender), mid, protectedTrack = WTFMove(withTrack), protectedPromise = WTFMove(promise)]() mutable {
+ replaceTrackTask(*protectedSender, mid, WTFMove(protectedTrack), protectedPromise);
+ });
+}
+
+void MediaEndpointPeerConnection::replaceTrackTask(RTCRtpSender& sender, const String& mid, RefPtr<MediaStreamTrack>&& withTrack, DOMPromise<void>& promise)
+{
+ if (m_peerConnection.internalSignalingState() == SignalingState::Closed)
+ return;
+
+ m_mediaEndpoint->replaceSendSource(withTrack->source(), mid);
+
+ sender.setTrack(WTFMove(withTrack));
+ promise.resolve();
+}
+
+void MediaEndpointPeerConnection::doStop()
+{
+ m_mediaEndpoint->stop();
+}
+
+void MediaEndpointPeerConnection::emulatePlatformEvent(const String& action)
+{
+ m_mediaEndpoint->emulatePlatformEvent(action);
+}
+
+MediaEndpointSessionDescription* MediaEndpointPeerConnection::internalLocalDescription() const
+{
+ return m_pendingLocalDescription ? m_pendingLocalDescription.get() : m_currentLocalDescription.get();
+}
+
+MediaEndpointSessionDescription* MediaEndpointPeerConnection::internalRemoteDescription() const
+{
+ return m_pendingRemoteDescription ? m_pendingRemoteDescription.get() : m_currentRemoteDescription.get();
+}
+
+RefPtr<RTCSessionDescription> MediaEndpointPeerConnection::createRTCSessionDescription(MediaEndpointSessionDescription* description) const
+{
+ return description ? description->toRTCSessionDescription(*m_sdpProcessor) : nullptr;
+}
+
+void MediaEndpointPeerConnection::gotDtlsFingerprint(const String& fingerprint, const String& fingerprintFunction)
+{
+ ASSERT(isMainThread());
+
+ m_dtlsFingerprint = fingerprint;
+ m_dtlsFingerprintFunction = fingerprintFunction;
+
+ startRunningTasks();
+}
+
+void MediaEndpointPeerConnection::gotIceCandidate(const String& mid, IceCandidate&& candidate)
+{
+ ASSERT(isMainThread());
+
+ auto& mediaDescriptions = internalLocalDescription()->configuration()->mediaDescriptions();
+ size_t mediaDescriptionIndex = notFound;
+
+ for (size_t i = 0; i < mediaDescriptions.size(); ++i) {
+ if (mediaDescriptions[i].mid == mid) {
+ mediaDescriptionIndex = i;
+ break;
+ }
+ }
+ ASSERT(mediaDescriptionIndex != notFound);
+
+ String candidateLine;
+ auto result = m_sdpProcessor->generateCandidateLine(candidate, candidateLine);
+ if (result != SDPProcessor::Result::Success) {
+ LOG_ERROR("SDPProcessor internal error");
+ return;
+ }
+
+ mediaDescriptions[mediaDescriptionIndex].addIceCandidate(WTFMove(candidate));
+
+ fireICECandidateEvent(RTCIceCandidate::create(candidateLine, mid, mediaDescriptionIndex));
+}
+
+void MediaEndpointPeerConnection::doneGatheringCandidates(const String& mid)
+{
+ ASSERT(isMainThread());
+
+ RtpTransceiverVector transceivers = RtpTransceiverVector(m_peerConnection.getTransceivers());
+ RTCRtpTransceiver* notifyingTransceiver = matchTransceiverByMid(transceivers, mid);
+ ASSERT(notifyingTransceiver);
+
+ notifyingTransceiver->iceTransport().setGatheringState(RTCIceTransport::GatheringState::Complete);
+
+ // Don't notify the script if there are transceivers still gathering.
+ RTCRtpTransceiver* stillGatheringTransceiver = matchTransceiver(transceivers, [] (RTCRtpTransceiver& current) {
+ return !current.stopped() && !current.mid().isNull()
+ && current.iceTransport().gatheringState() != RTCIceTransport::GatheringState::Complete;
+ });
+ if (!stillGatheringTransceiver)
+ PeerConnectionBackend::doneGatheringCandidates();
+}
+
+static RTCIceTransport::TransportState deriveAggregatedIceConnectionState(const Vector<RTCIceTransport::TransportState>& states)
+{
+ unsigned newCount = 0;
+ unsigned checkingCount = 0;
+ unsigned connectedCount = 0;
+ unsigned completedCount = 0;
+ unsigned failedCount = 0;
+ unsigned disconnectedCount = 0;
+ unsigned closedCount = 0;
+
+ for (auto& state : states) {
+ switch (state) {
+ case RTCIceTransport::TransportState::New: ++newCount; break;
+ case RTCIceTransport::TransportState::Checking: ++checkingCount; break;
+ case RTCIceTransport::TransportState::Connected: ++connectedCount; break;
+ case RTCIceTransport::TransportState::Completed: ++completedCount; break;
+ case RTCIceTransport::TransportState::Failed: ++failedCount; break;
+ case RTCIceTransport::TransportState::Disconnected: ++disconnectedCount; break;
+ case RTCIceTransport::TransportState::Closed: ++closedCount; break;
+ }
+ }
+
+ // The aggregated RTCIceConnectionState is derived from the RTCIceTransportState of all RTCIceTransports.
+ if ((newCount > 0 && !checkingCount && !failedCount && !disconnectedCount) || (closedCount == states.size()))
+ return RTCIceTransport::TransportState::New;
+
+ if (checkingCount > 0 && !failedCount && !disconnectedCount)
+ return RTCIceTransport::TransportState::Checking;
+
+ if ((connectedCount + completedCount + closedCount) == states.size() && connectedCount > 0)
+ return RTCIceTransport::TransportState::Connected;
+
+ if ((completedCount + closedCount) == states.size() && completedCount > 0)
+ return RTCIceTransport::TransportState::Completed;
+
+ if (failedCount > 0)
+ return RTCIceTransport::TransportState::Failed;
+
+ if (disconnectedCount > 0) // Any failed caught above.
+ return RTCIceTransport::TransportState::Disconnected;
+
+ ASSERT_NOT_REACHED();
+ return RTCIceTransport::TransportState::New;
+}
+
+void MediaEndpointPeerConnection::iceTransportStateChanged(const String& mid, MediaEndpoint::IceTransportState mediaEndpointIceTransportState)
+{
+ ASSERT(isMainThread());
+
+ RTCRtpTransceiver* transceiver = matchTransceiverByMid(m_peerConnection.getTransceivers(), mid);
+ ASSERT(transceiver);
+
+ RTCIceTransport::TransportState transportState = static_cast<RTCIceTransport::TransportState>(mediaEndpointIceTransportState);
+ transceiver->iceTransport().setTransportState(transportState);
+
+ // Determine if the script needs to be notified.
+ Vector<RTCIceTransport::TransportState> transportStates;
+ for (auto& transceiver : m_peerConnection.getTransceivers())
+ transportStates.append(transceiver->iceTransport().transportState());
+
+ RTCIceTransport::TransportState derivedState = deriveAggregatedIceConnectionState(transportStates);
+ m_peerConnection.updateIceConnectionState(static_cast<IceConnectionState>(derivedState));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h
new file mode 100644
index 000000000..01b37843d
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2015, 2016 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "MediaEndpoint.h"
+#include "PeerConnectionBackend.h"
+#include "RTCSessionDescription.h"
+#include <wtf/Function.h>
+
+namespace WebCore {
+
+class MediaEndpointSessionDescription;
+class SDPProcessor;
+
+class MediaEndpointPeerConnection final : public PeerConnectionBackend, public MediaEndpointClient {
+public:
+ WEBCORE_EXPORT explicit MediaEndpointPeerConnection(RTCPeerConnection&);
+
+private:
+ RefPtr<RTCSessionDescription> localDescription() const final;
+ RefPtr<RTCSessionDescription> currentLocalDescription() const final;
+ RefPtr<RTCSessionDescription> pendingLocalDescription() const final;
+
+ RefPtr<RTCSessionDescription> remoteDescription() const final;
+ RefPtr<RTCSessionDescription> currentRemoteDescription() const final;
+ RefPtr<RTCSessionDescription> pendingRemoteDescription() const final;
+
+ void setConfiguration(MediaEndpointConfiguration&&) final;
+
+ void getStats(MediaStreamTrack*, Ref<DeferredPromise>&&) final;
+
+ Vector<RefPtr<MediaStream>> getRemoteStreams() const final;
+
+ Ref<RTCRtpReceiver> createReceiver(const String& transceiverMid, const String& trackKind, const String& trackId) final;
+ void replaceTrack(RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromise<void>&&) final;
+
+ void emulatePlatformEvent(const String& action) final;
+
+ void runTask(Function<void ()>&&);
+ void startRunningTasks();
+
+ void doCreateOffer(RTCOfferOptions&&) final;
+ void doCreateAnswer(RTCAnswerOptions&&) final;
+ void doSetLocalDescription(RTCSessionDescription&) final;
+ void doSetRemoteDescription(RTCSessionDescription&) final;
+ void doAddIceCandidate(RTCIceCandidate&) final;
+ void doStop() final;
+
+ void createOfferTask(const RTCOfferOptions&);
+ void createAnswerTask(const RTCAnswerOptions&);
+
+ void setLocalDescriptionTask(RefPtr<RTCSessionDescription>&&);
+ void setRemoteDescriptionTask(RefPtr<RTCSessionDescription>&&);
+
+ void addIceCandidateTask(RTCIceCandidate&);
+
+ void replaceTrackTask(RTCRtpSender&, const String& mid, RefPtr<MediaStreamTrack>&&, DOMPromise<void>&);
+
+ bool localDescriptionTypeValidForState(RTCSessionDescription::SdpType) const;
+ bool remoteDescriptionTypeValidForState(RTCSessionDescription::SdpType) const;
+
+ MediaEndpointSessionDescription* internalLocalDescription() const;
+ MediaEndpointSessionDescription* internalRemoteDescription() const;
+ RefPtr<RTCSessionDescription> createRTCSessionDescription(MediaEndpointSessionDescription*) const;
+
+ // MediaEndpointClient
+ void gotDtlsFingerprint(const String& fingerprint, const String& fingerprintFunction) final;
+ void gotIceCandidate(const String& mid, IceCandidate&&) final;
+ void doneGatheringCandidates(const String& mid) final;
+ void iceTransportStateChanged(const String& mid, MediaEndpoint::IceTransportState) final;
+
+ std::unique_ptr<RTCDataChannelHandler> createDataChannelHandler(const String&, const RTCDataChannelInit&) final;
+
+ std::unique_ptr<MediaEndpoint> m_mediaEndpoint;
+
+ Function<void ()> m_initialDeferredTask;
+
+ std::unique_ptr<SDPProcessor> m_sdpProcessor;
+
+ Vector<MediaPayload> m_defaultAudioPayloads;
+ Vector<MediaPayload> m_defaultVideoPayloads;
+
+ String m_cname;
+ String m_iceUfrag;
+ String m_icePassword;
+ String m_dtlsFingerprint;
+ String m_dtlsFingerprintFunction;
+ unsigned m_sdpOfferSessionVersion { 0 };
+ unsigned m_sdpAnswerSessionVersion { 0 };
+
+ RefPtr<MediaEndpointSessionDescription> m_currentLocalDescription;
+ RefPtr<MediaEndpointSessionDescription> m_pendingLocalDescription;
+
+ RefPtr<MediaEndpointSessionDescription> m_currentRemoteDescription;
+ RefPtr<MediaEndpointSessionDescription> m_pendingRemoteDescription;
+
+ HashMap<String, RefPtr<MediaStream>> m_remoteStreamMap;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointSessionDescription.cpp b/Source/WebCore/Modules/mediastream/MediaEndpointSessionDescription.cpp
new file mode 100644
index 000000000..ac5b2f0d8
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaEndpointSessionDescription.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2015, 2016 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MediaEndpointSessionDescription.h"
+
+#if ENABLE(WEB_RTC)
+
+#include "ExceptionCode.h"
+#include "SDPProcessor.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+#define STRING_FUNCTION(name) \
+ static const String& name##String() \
+ { \
+ static NeverDestroyed<const String> name { ASCIILiteral(#name) }; \
+ return name; \
+ }
+
+STRING_FUNCTION(offer)
+STRING_FUNCTION(pranswer)
+STRING_FUNCTION(answer)
+STRING_FUNCTION(rollback)
+
+Ref<MediaEndpointSessionDescription> MediaEndpointSessionDescription::create(RTCSessionDescription::SdpType type, RefPtr<MediaEndpointSessionConfiguration>&& configuration)
+{
+ return adoptRef(*new MediaEndpointSessionDescription(type, WTFMove(configuration), nullptr));
+}
+
+ExceptionOr<Ref<MediaEndpointSessionDescription>> MediaEndpointSessionDescription::create(RefPtr<RTCSessionDescription>&& rtcDescription, const SDPProcessor& sdpProcessor)
+{
+ RefPtr<MediaEndpointSessionConfiguration> configuration;
+ auto result = sdpProcessor.parse(rtcDescription->sdp(), configuration);
+ if (result != SDPProcessor::Result::Success) {
+ if (result == SDPProcessor::Result::ParseError)
+ return Exception { INVALID_ACCESS_ERR, ASCIILiteral("SDP content is invalid") };
+ LOG_ERROR("SDPProcessor internal error");
+ return Exception { ABORT_ERR, ASCIILiteral("Internal error") };
+ }
+ return adoptRef(*new MediaEndpointSessionDescription(rtcDescription->type(), WTFMove(configuration), WTFMove(rtcDescription)));
+}
+
+RefPtr<RTCSessionDescription> MediaEndpointSessionDescription::toRTCSessionDescription(const SDPProcessor& sdpProcessor) const
+{
+ String sdpString;
+ SDPProcessor::Result result = sdpProcessor.generate(*m_configuration, sdpString);
+ if (result != SDPProcessor::Result::Success) {
+ LOG_ERROR("SDPProcessor internal error");
+ return nullptr;
+ }
+
+ // If this object was created from an RTCSessionDescription, toRTCSessionDescription will return
+ // that same instance but with an updated sdp. It is used for RTCPeerConnection's description
+ // atributes (e.g. localDescription and pendingLocalDescription).
+ if (m_rtcDescription) {
+ m_rtcDescription->setSdp(sdpString);
+ return m_rtcDescription;
+ }
+
+ return RTCSessionDescription::create(m_type, sdpString);
+}
+
+const String& MediaEndpointSessionDescription::typeString() const
+{
+ switch (m_type) {
+ case RTCSessionDescription::SdpType::Offer:
+ return offerString();
+ case RTCSessionDescription::SdpType::Pranswer:
+ return pranswerString();
+ case RTCSessionDescription::SdpType::Answer:
+ return answerString();
+ case RTCSessionDescription::SdpType::Rollback:
+ return rollbackString();
+ }
+
+ ASSERT_NOT_REACHED();
+ return emptyString();
+}
+
+bool MediaEndpointSessionDescription::isLaterThan(MediaEndpointSessionDescription* other) const
+{
+ return !other || configuration()->sessionVersion() > other->configuration()->sessionVersion();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointSessionDescription.h b/Source/WebCore/Modules/mediastream/MediaEndpointSessionDescription.h
new file mode 100644
index 000000000..60316ce58
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaEndpointSessionDescription.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015, 2016 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "ExceptionOr.h"
+#include "RTCSessionDescription.h"
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class MediaEndpointSessionConfiguration;
+class SDPProcessor;
+class DOMError;
+
+class MediaEndpointSessionDescription : public RefCounted<MediaEndpointSessionDescription> {
+public:
+ static Ref<MediaEndpointSessionDescription> create(RTCSessionDescription::SdpType, RefPtr<MediaEndpointSessionConfiguration>&&);
+ static ExceptionOr<Ref<MediaEndpointSessionDescription>> create(RefPtr<RTCSessionDescription>&&, const SDPProcessor&);
+ virtual ~MediaEndpointSessionDescription() { } // FIXME: Why is this virtual? There are no other virtual functions in this class.
+
+ RefPtr<RTCSessionDescription> toRTCSessionDescription(const SDPProcessor&) const;
+
+ RTCSessionDescription::SdpType type() const { return m_type; }
+ const String& typeString() const;
+ MediaEndpointSessionConfiguration* configuration() const { return m_configuration.get(); }
+
+ bool isLaterThan(MediaEndpointSessionDescription* other) const;
+
+private:
+ MediaEndpointSessionDescription(RTCSessionDescription::SdpType type, RefPtr<MediaEndpointSessionConfiguration>&& configuration, RefPtr<RTCSessionDescription>&& rtcDescription)
+ : m_type(type)
+ , m_configuration(configuration)
+ , m_rtcDescription(WTFMove(rtcDescription))
+ { }
+
+ RTCSessionDescription::SdpType m_type;
+ RefPtr<MediaEndpointSessionConfiguration> m_configuration;
+
+ RefPtr<RTCSessionDescription> m_rtcDescription;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/MediaSourceStates.cpp b/Source/WebCore/Modules/mediastream/MediaSourceStates.cpp
deleted file mode 100644
index 6f7eff6e4..000000000
--- a/Source/WebCore/Modules/mediastream/MediaSourceStates.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaSourceStates.h"
-
-#include <wtf/NeverDestroyed.h>
-
-namespace WebCore {
-
-RefPtr<MediaSourceStates> MediaSourceStates::create(const MediaStreamSourceStates& states)
-{
- return adoptRef(new MediaSourceStates(states));
-}
-
-MediaSourceStates::MediaSourceStates(const MediaStreamSourceStates& states)
- : m_sourceStates(states)
-{
-}
-
-const AtomicString& MediaSourceStates::sourceType() const
-{
- return MediaStreamSourceStates::sourceType(m_sourceStates.sourceType());
-}
-
-const AtomicString& MediaSourceStates::facingMode() const
-{
- return MediaStreamSourceStates::facingMode(m_sourceStates.facingMode());
-}
-
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/MediaSourceStates.h b/Source/WebCore/Modules/mediastream/MediaSourceStates.h
deleted file mode 100644
index b0a4554e2..000000000
--- a/Source/WebCore/Modules/mediastream/MediaSourceStates.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaSourceStates_h
-#define MediaSourceStates_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamSourceCapabilities.h"
-#include "ScriptWrappable.h"
-#include <wtf/Forward.h>
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class MediaSourceStates : public RefCounted<MediaSourceStates>, public ScriptWrappable {
-public:
- static RefPtr<MediaSourceStates> create(const MediaStreamSourceStates&);
-
- const AtomicString& sourceType() const;
- const AtomicString& sourceId() const { return m_sourceStates.sourceId(); }
- unsigned long width() const { return m_sourceStates.width(); }
- unsigned long height() const { return m_sourceStates.height(); }
- float frameRate() const { return m_sourceStates.frameRate(); }
- float aspectRatio() const { return m_sourceStates.aspectRatio(); }
- const AtomicString& facingMode() const;
- unsigned long volume() const { return m_sourceStates.volume(); }
-
- bool hasVideoSource() const { return m_sourceStates.sourceType() == MediaStreamSourceStates::Camera; }
-
-private:
- explicit MediaSourceStates(const MediaStreamSourceStates&);
-
- MediaStreamSourceStates m_sourceStates;
-};
-
-} // namespace WebCore
-
-#endif // MediaSourceStates_h
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/MediaSourceStates.idl b/Source/WebCore/Modules/mediastream/MediaSourceStates.idl
deleted file mode 100644
index 6ce9f7ef1..000000000
--- a/Source/WebCore/Modules/mediastream/MediaSourceStates.idl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-enum SourceTypeEnum { "none", "camera", "microphone" };
-enum VideoFacingModeEnum { "user", "environment", "left", "right" };
-
-[
- Conditional=MEDIA_STREAM,
- ImplementationLacksVTable,
- NoInterfaceObject,
-] interface MediaSourceStates {
- readonly attribute SourceTypeEnum sourceType;
- readonly attribute DOMString sourceId;
-
- [CustomGetter] readonly attribute unsigned long? width;
- [CustomGetter] readonly attribute unsigned long? height;
- [CustomGetter] readonly attribute float? frameRate;
- [CustomGetter] readonly attribute float? aspectRatio;
- [CustomGetter] readonly attribute VideoFacingModeEnum? facingMode;
- [CustomGetter] readonly attribute unsigned long? volume;
-};
-
diff --git a/Source/WebCore/Modules/mediastream/MediaStream.cpp b/Source/WebCore/Modules/mediastream/MediaStream.cpp
index 22ec3d4cc..dcacf8f82 100644
--- a/Source/WebCore/Modules/mediastream/MediaStream.cpp
+++ b/Source/WebCore/Modules/mediastream/MediaStream.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2011, 2012 Ericsson AB. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2015 Ericsson AB. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
*
* Redistribution and use in source and binary forms, with or without
@@ -30,356 +30,366 @@
#if ENABLE(MEDIA_STREAM)
-#include "AudioStreamTrack.h"
+#include "Document.h"
#include "Event.h"
-#include "ExceptionCode.h"
-#include "MediaStreamCenter.h"
+#include "EventNames.h"
+#include "Logging.h"
#include "MediaStreamRegistry.h"
-#include "MediaStreamSource.h"
#include "MediaStreamTrackEvent.h"
-#include "VideoStreamTrack.h"
-#include <wtf/NeverDestroyed.h>
+#include "Page.h"
+#include "RealtimeMediaSource.h"
+#include "URL.h"
namespace WebCore {
-PassRefPtr<MediaStream> MediaStream::create(ScriptExecutionContext& context)
+Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context)
{
- return MediaStream::create(context, MediaStreamPrivate::create(Vector<RefPtr<MediaStreamSource>>(), Vector<RefPtr<MediaStreamSource>>()));
+ return MediaStream::create(context, MediaStreamPrivate::create(Vector<RefPtr<MediaStreamTrackPrivate>>()));
}
-PassRefPtr<MediaStream> MediaStream::create(ScriptExecutionContext& context, PassRefPtr<MediaStream> stream)
+Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, MediaStream& stream)
{
- ASSERT(stream);
-
- Vector<RefPtr<MediaStreamTrackPrivate>> audioTracks;
- Vector<RefPtr<MediaStreamTrackPrivate>> videoTracks;
-
- for (size_t i = 0; i < stream->m_audioTracks.size(); ++i)
- audioTracks.append(&stream->m_audioTracks[i]->privateTrack());
-
- for (size_t i = 0; i < stream->m_videoTracks.size(); ++i)
- videoTracks.append(&stream->m_videoTracks[i]->privateTrack());
-
- return MediaStream::create(context, MediaStreamPrivate::create(audioTracks, videoTracks));
+ return adoptRef(*new MediaStream(context, stream.getTracks()));
}
-PassRefPtr<MediaStream> MediaStream::create(ScriptExecutionContext& context, const Vector<RefPtr<MediaStreamTrack>>& tracks)
+Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, const MediaStreamTrackVector& tracks)
{
- Vector<RefPtr<MediaStreamTrackPrivate>> audioTracks;
- Vector<RefPtr<MediaStreamTrackPrivate>> videoTracks;
-
- for (size_t i = 0; i < tracks.size(); ++i) {
- if (tracks[i]->kind() == "audio")
- audioTracks.append(&tracks[i]->privateTrack());
- else
- videoTracks.append(&tracks[i]->privateTrack());
- }
+ return adoptRef(*new MediaStream(context, tracks));
+}
- return MediaStream::create(context, MediaStreamPrivate::create(audioTracks, videoTracks));
+Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, RefPtr<MediaStreamPrivate>&& streamPrivate)
+{
+ return adoptRef(*new MediaStream(context, WTFMove(streamPrivate)));
}
-PassRefPtr<MediaStream> MediaStream::create(ScriptExecutionContext& context, PassRefPtr<MediaStreamPrivate> privateStream)
+MediaStream::MediaStream(ScriptExecutionContext& context, const MediaStreamTrackVector& tracks)
+ : ContextDestructionObserver(&context)
+ , m_activityEventTimer(*this, &MediaStream::activityEventTimerFired)
{
- return adoptRef(new MediaStream(context, privateStream));
+ // This constructor preserves MediaStreamTrack instances and must be used by calls originating
+ // from the JavaScript MediaStream constructor.
+ MediaStreamTrackPrivateVector trackPrivates;
+ trackPrivates.reserveCapacity(tracks.size());
+
+ for (auto& track : tracks) {
+ track->addObserver(*this);
+ m_trackSet.add(track->id(), track);
+ trackPrivates.append(&track->privateTrack());
+ }
+
+ m_private = MediaStreamPrivate::create(trackPrivates);
+ setIsActive(m_private->active());
+ m_private->addObserver(*this);
+ MediaStreamRegistry::shared().registerStream(*this);
+ document()->addAudioProducer(this);
}
-MediaStream::MediaStream(ScriptExecutionContext& context, PassRefPtr<MediaStreamPrivate> privateStream)
+MediaStream::MediaStream(ScriptExecutionContext& context, RefPtr<MediaStreamPrivate>&& streamPrivate)
: ContextDestructionObserver(&context)
- , m_private(privateStream)
- , m_scheduledEventTimer(this, &MediaStream::scheduledEventTimerFired)
+ , m_private(streamPrivate)
+ , m_activityEventTimer(*this, &MediaStream::activityEventTimerFired)
{
ASSERT(m_private);
- m_private->setClient(this);
-
- RefPtr<MediaStreamTrack> track;
- size_t numberOfAudioTracks = m_private->numberOfAudioTracks();
- m_audioTracks.reserveCapacity(numberOfAudioTracks);
- for (size_t i = 0; i < numberOfAudioTracks; i++) {
- track = AudioStreamTrack::create(context, *m_private->audioTracks(i));
- track->addObserver(this);
- m_audioTracks.append(track.release());
+ setIsActive(m_private->active());
+ m_private->addObserver(*this);
+ MediaStreamRegistry::shared().registerStream(*this);
+
+ for (auto& trackPrivate : m_private->tracks()) {
+ auto track = MediaStreamTrack::create(context, *trackPrivate);
+ track->addObserver(*this);
+ m_trackSet.add(track->id(), WTFMove(track));
}
+ document()->addAudioProducer(this);
+}
- size_t numberOfVideoTracks = m_private->numberOfVideoTracks();
- m_videoTracks.reserveCapacity(numberOfVideoTracks);
- for (size_t i = 0; i < numberOfVideoTracks; i++) {
- track = VideoStreamTrack::create(context, *m_private->videoTracks(i));
- track->addObserver(this);
- m_videoTracks.append(track.release());
+MediaStream::~MediaStream()
+{
+ // Set isActive to false immediately so an callbacks triggered by shutting down, e.g.
+ // mediaState(), are short circuited.
+ m_isActive = false;
+ MediaStreamRegistry::shared().unregisterStream(*this);
+ m_private->removeObserver(*this);
+ for (auto& track : m_trackSet.values())
+ track->removeObserver(*this);
+ if (Document* document = this->document()) {
+ document->removeAudioProducer(this);
+ if (m_isWaitingUntilMediaCanStart)
+ document->removeMediaCanStartListener(this);
}
}
-MediaStream::~MediaStream()
+RefPtr<MediaStream> MediaStream::clone()
{
- m_private->setClient(0);
+ MediaStreamTrackVector clonedTracks;
+ clonedTracks.reserveCapacity(m_trackSet.size());
+
+ for (auto& track : m_trackSet.values())
+ clonedTracks.append(track->clone());
+
+ return MediaStream::create(*scriptExecutionContext(), clonedTracks);
}
-bool MediaStream::ended() const
+void MediaStream::addTrack(MediaStreamTrack& track)
{
- return m_private->ended();
+ if (!internalAddTrack(track, StreamModifier::DomAPI))
+ return;
+
+ for (auto& observer : m_observers)
+ observer->didAddOrRemoveTrack();
}
-void MediaStream::setEnded()
+void MediaStream::removeTrack(MediaStreamTrack& track)
{
- if (ended())
+ if (!internalRemoveTrack(track.id(), StreamModifier::DomAPI))
return;
- m_private->setEnded();
+
+ for (auto& observer : m_observers)
+ observer->didAddOrRemoveTrack();
}
-PassRefPtr<MediaStream> MediaStream::clone()
+MediaStreamTrack* MediaStream::getTrackById(String id)
{
- Vector<RefPtr<MediaStreamTrack>> trackSet;
+ auto it = m_trackSet.find(id);
+ if (it != m_trackSet.end())
+ return it->value.get();
- cloneMediaStreamTrackVector(trackSet, getAudioTracks());
- cloneMediaStreamTrackVector(trackSet, getVideoTracks());
- return MediaStream::create(*scriptExecutionContext(), trackSet);
+ return nullptr;
}
-void MediaStream::cloneMediaStreamTrackVector(Vector<RefPtr<MediaStreamTrack>>& destination, const Vector<RefPtr<MediaStreamTrack>>& source)
+MediaStreamTrackVector MediaStream::getAudioTracks() const
{
- for (auto it = source.begin(), end = source.end(); it != end; ++it)
- destination.append((*it)->clone());
+ return trackVectorForType(RealtimeMediaSource::Audio);
}
-void MediaStream::addTrack(PassRefPtr<MediaStreamTrack> prpTrack, ExceptionCode& ec)
+MediaStreamTrackVector MediaStream::getVideoTracks() const
{
- if (ended()) {
- ec = INVALID_STATE_ERR;
- return;
- }
+ return trackVectorForType(RealtimeMediaSource::Video);
+}
- if (!prpTrack) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
+MediaStreamTrackVector MediaStream::getTracks() const
+{
+ MediaStreamTrackVector tracks;
+ tracks.reserveCapacity(m_trackSet.size());
+ copyValuesToVector(m_trackSet, tracks);
- if (addTrack(prpTrack)) {
- for (auto observer = m_observers.begin(), end = m_observers.end(); observer != end; ++observer)
- (*observer)->didAddOrRemoveTrack();
- }
+ return tracks;
}
-bool MediaStream::addTrack(PassRefPtr<MediaStreamTrack> prpTrack)
+void MediaStream::contextDestroyed()
{
- // This is a common part used by addTrack called by JavaScript
- // and addRemoteTrack and only addRemoteTrack must fire addtrack event
- RefPtr<MediaStreamTrack> track = prpTrack;
- if (getTrackById(track->id()))
- return false;
-
- Vector<RefPtr<MediaStreamTrack>>* tracks = trackVectorForType(track->source()->type());
+ ContextDestructionObserver::contextDestroyed();
+}
- tracks->append(track);
- track->addObserver(this);
- m_private->addTrack(&track->privateTrack());
- return true;
+void MediaStream::trackDidEnd()
+{
+ m_private->updateActiveState(MediaStreamPrivate::NotifyClientOption::Notify);
}
-void MediaStream::removeTrack(PassRefPtr<MediaStreamTrack> prpTrack, ExceptionCode& ec)
+void MediaStream::activeStatusChanged()
{
- if (ended()) {
- ec = INVALID_STATE_ERR;
- return;
- }
+ // Schedule the active state change and event dispatch since this callback may be called
+ // synchronously from the DOM API (e.g. as a result of addTrack()).
+ scheduleActiveStateChange();
+}
- if (!prpTrack) {
- ec = TYPE_MISMATCH_ERR;
+void MediaStream::didAddTrack(MediaStreamTrackPrivate& trackPrivate)
+{
+ ScriptExecutionContext* context = scriptExecutionContext();
+ if (!context)
return;
- }
- if (removeTrack(prpTrack)) {
- for (auto observer = m_observers.begin(), end = m_observers.end(); observer != end; ++observer)
- (*observer)->didAddOrRemoveTrack();
- }
+ if (!getTrackById(trackPrivate.id()))
+ internalAddTrack(MediaStreamTrack::create(*context, trackPrivate), StreamModifier::Platform);
}
-bool MediaStream::removeTrack(PassRefPtr<MediaStreamTrack> prpTrack)
+void MediaStream::didRemoveTrack(MediaStreamTrackPrivate& trackPrivate)
{
- // This is a common part used by removeTrack called by JavaScript
- // and removeRemoteTrack and only removeRemoteTrack must fire removetrack event
- RefPtr<MediaStreamTrack> track = prpTrack;
- Vector<RefPtr<MediaStreamTrack>>* tracks = trackVectorForType(track->source()->type());
+ internalRemoveTrack(trackPrivate.id(), StreamModifier::Platform);
+}
- size_t pos = tracks->find(track);
- if (pos == notFound)
+bool MediaStream::internalAddTrack(Ref<MediaStreamTrack>&& trackToAdd, StreamModifier streamModifier)
+{
+ auto result = m_trackSet.add(trackToAdd->id(), WTFMove(trackToAdd));
+ if (!result.isNewEntry)
return false;
- tracks->remove(pos);
- m_private->removeTrack(&track->privateTrack());
- // There can be other tracks using the same source in the same MediaStream,
- // like when MediaStreamTrack::clone() is called, for instance.
- // Spec says that a source can be shared, so we must assure that there is no
- // other track using it.
- if (!haveTrackWithSource(track->source()))
- m_private->removeSource(track->source());
+ ASSERT(result.iterator->value);
+ auto& track = *result.iterator->value;
+ track.addObserver(*this);
- track->removeObserver(this);
- if (!m_audioTracks.size() && !m_videoTracks.size())
- setEnded();
+ if (streamModifier == StreamModifier::DomAPI)
+ m_private->addTrack(&track.privateTrack(), MediaStreamPrivate::NotifyClientOption::DontNotify);
+ else
+ dispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEvent, false, false, &track));
return true;
}
-bool MediaStream::haveTrackWithSource(PassRefPtr<MediaStreamSource> source)
+bool MediaStream::internalRemoveTrack(const String& trackId, StreamModifier streamModifier)
{
- if (source->type() == MediaStreamSource::Audio) {
- for (auto it = m_audioTracks.begin(), end = m_audioTracks.end(); it != end; ++it) {
- if ((*it)->source() == source.get())
- return true;
- }
+ auto track = m_trackSet.take(trackId);
+ if (!track)
return false;
- }
- for (auto it = m_videoTracks.begin(), end = m_videoTracks.end(); it != end; ++it) {
- if ((*it)->source() == source.get())
- return true;
- }
+ track->removeObserver(*this);
+
+ if (streamModifier == StreamModifier::DomAPI)
+ m_private->removeTrack(track->privateTrack(), MediaStreamPrivate::NotifyClientOption::DontNotify);
+ else
+ dispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, WTFMove(track)));
- return false;
+ return true;
}
-MediaStreamTrack* MediaStream::getTrackById(String id)
+void MediaStream::setIsActive(bool active)
{
- for (auto it = m_audioTracks.begin(), end = m_audioTracks.end(); it != end; ++it) {
- if ((*it)->id() == id)
- return (*it).get();
- }
-
- for (auto it = m_videoTracks.begin(), end = m_videoTracks.end(); it != end; ++it) {
- if ((*it)->id() == id)
- return (*it).get();
- }
+ if (m_isActive == active)
+ return;
- return nullptr;
+ m_isActive = active;
+ statusDidChange();
}
-void MediaStream::trackDidEnd()
+void MediaStream::mediaCanStart(Document& document)
{
- for (auto it = m_audioTracks.begin(), end = m_audioTracks.end(); it != end; ++it) {
- if (!(*it)->ended())
- return;
- }
- for (auto it = m_videoTracks.begin(), end = m_videoTracks.end(); it != end; ++it) {
- if (!(*it)->ended())
- return;
+ ASSERT_UNUSED(document, &document == this->document());
+ ASSERT(m_isWaitingUntilMediaCanStart);
+ if (m_isWaitingUntilMediaCanStart) {
+ m_isWaitingUntilMediaCanStart = false;
+ startProducingData();
}
-
- setEnded();
}
-void MediaStream::streamDidEnd()
+void MediaStream::startProducingData()
{
- if (ended())
+ Document* document = this->document();
+ if (!document || !document->page())
return;
- scheduleDispatchEvent(Event::create(eventNames().endedEvent, false, false));
-}
+ // If we can't start a load right away, start it later.
+ if (!document->page()->canStartMedia()) {
+ LOG(Media, "MediaStream::startProducingData(%p) - not allowed to start in background, waiting", this);
+ if (m_isWaitingUntilMediaCanStart)
+ return;
-void MediaStream::contextDestroyed()
-{
- ContextDestructionObserver::contextDestroyed();
+ m_isWaitingUntilMediaCanStart = true;
+ document->addMediaCanStartListener(this);
+ return;
+ }
+
+ m_private->startProducingData();
}
-void MediaStream::addRemoteSource(MediaStreamSource* source)
+void MediaStream::stopProducingData()
{
- ASSERT(source);
- addRemoteTrack(MediaStreamTrackPrivate::create(source).get());
+ m_private->stopProducingData();
}
-void MediaStream::removeRemoteSource(MediaStreamSource* source)
+void MediaStream::pageMutedStateDidChange()
{
- ASSERT(source);
- if (ended())
+ if (!m_isActive)
return;
- Vector<RefPtr<MediaStreamTrack>>* tracks = trackVectorForType(source->type());
-
- for (int i = tracks->size() - 1; i >= 0; --i) {
- if ((*tracks)[i]->source() != source)
- continue;
+ Document* document = this->document();
+ if (!document)
+ return;
- RefPtr<MediaStreamTrack> track = (*tracks)[i];
- track->removeObserver(this);
- tracks->remove(i);
- m_private->removeTrack(&track->privateTrack());
- scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track.release()));
- }
+ bool pageMuted = document->page()->isMediaCaptureMuted();
+ if (m_externallyMuted == pageMuted)
+ return;
- m_private->removeSource(source);
+ m_externallyMuted = pageMuted;
+ if (pageMuted)
+ stopProducingData();
+ else
+ startProducingData();
}
-void MediaStream::addRemoteTrack(MediaStreamTrackPrivate* privateTrack)
+MediaProducer::MediaStateFlags MediaStream::mediaState() const
{
- ASSERT(privateTrack);
- if (ended())
- return;
+ MediaStateFlags state = IsNotPlaying;
- RefPtr<MediaStreamTrack> track;
- switch (privateTrack->type()) {
- case MediaStreamSource::Audio:
- track = AudioStreamTrack::create(*scriptExecutionContext(), *privateTrack);
- break;
- case MediaStreamSource::Video:
- track = VideoStreamTrack::create(*scriptExecutionContext(), *privateTrack);
- break;
- case MediaStreamSource::None:
- ASSERT_NOT_REACHED();
- break;
+ if (!m_isActive)
+ return state;
+
+ if (m_private->hasAudio()) {
+ state |= HasAudioOrVideo;
+ if (m_private->hasLocalAudioSource() && m_private->isProducingData())
+ state |= HasActiveAudioCaptureDevice;
}
- if (!track)
- return;
+ if (m_private->hasVideo()) {
+ state |= HasAudioOrVideo;
+ if (m_private->hasLocalVideoSource() && m_private->isProducingData())
+ state |= HasActiveVideoCaptureDevice;
+ }
- if (addTrack(track))
- scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEvent, false, false, track));
+ return state;
}
-void MediaStream::removeRemoteTrack(MediaStreamTrackPrivate* privateTrack)
+void MediaStream::statusDidChange()
{
- ASSERT(privateTrack);
- if (ended())
- return;
+ if (Document* document = this->document()) {
+ if (m_isActive)
+ document->setHasActiveMediaStreamTrack();
+ document->updateIsPlayingMedia();
+ }
+}
- RefPtr<MediaStreamTrack> track = getTrackById(privateTrack->id());
- if (removeTrack(track))
- scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track.release()));
+void MediaStream::characteristicsChanged()
+{
+ bool muted = m_private->muted();
+ if (m_isMuted != muted) {
+ m_isMuted = muted;
+ statusDidChange();
+ }
}
-void MediaStream::scheduleDispatchEvent(PassRefPtr<Event> event)
+void MediaStream::scheduleActiveStateChange()
{
- m_scheduledEvents.append(event);
+ bool active = false;
+ for (auto& track : m_trackSet.values()) {
+ if (!track->ended()) {
+ active = true;
+ break;
+ }
+ }
+
+ if (m_isActive == active)
+ return;
+
+ setIsActive(active);
+
+ const AtomicString& eventName = m_isActive ? eventNames().inactiveEvent : eventNames().activeEvent;
+ m_scheduledActivityEvents.append(Event::create(eventName, false, false));
- if (!m_scheduledEventTimer.isActive())
- m_scheduledEventTimer.startOneShot(0);
+ if (!m_activityEventTimer.isActive())
+ m_activityEventTimer.startOneShot(0);
}
-void MediaStream::scheduledEventTimerFired(Timer<MediaStream>*)
+void MediaStream::activityEventTimerFired()
{
- Vector<RefPtr<Event>> events;
- events.swap(m_scheduledEvents);
+ Vector<Ref<Event>> events;
+ events.swap(m_scheduledActivityEvents);
- for (auto it = events.begin(), end = events.end(); it != end; ++it)
- dispatchEvent((*it).release());
-
- events.clear();
+ for (auto& event : events)
+ dispatchEvent(event);
}
URLRegistry& MediaStream::registry() const
{
- return MediaStreamRegistry::registry();
+ return MediaStreamRegistry::shared();
}
-Vector<RefPtr<MediaStreamTrack>>* MediaStream::trackVectorForType(MediaStreamSource::Type type)
+MediaStreamTrackVector MediaStream::trackVectorForType(RealtimeMediaSource::Type filterType) const
{
- switch (type) {
- case MediaStreamSource::Audio:
- return &m_audioTracks;
- case MediaStreamSource::Video:
- return &m_videoTracks;
- case MediaStreamSource::None:
- ASSERT_NOT_REACHED();
+ MediaStreamTrackVector tracks;
+ for (auto& track : m_trackSet.values()) {
+ if (track->source().type() == filterType)
+ tracks.append(track);
}
- return nullptr;
+
+ return tracks;
}
void MediaStream::addObserver(MediaStream::Observer* observer)
@@ -395,6 +405,11 @@ void MediaStream::removeObserver(MediaStream::Observer* observer)
m_observers.remove(pos);
}
+Document* MediaStream::document() const
+{
+ return downcast<Document>(scriptExecutionContext());
+}
+
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/MediaStream.h b/Source/WebCore/Modules/mediastream/MediaStream.h
index 1791c2490..816d706a3 100644
--- a/Source/WebCore/Modules/mediastream/MediaStream.h
+++ b/Source/WebCore/Modules/mediastream/MediaStream.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
*
* Redistribution and use in source and binary forms, with or without
@@ -25,116 +25,140 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaStream_h
-#define MediaStream_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
#include "ContextDestructionObserver.h"
#include "EventTarget.h"
#include "ExceptionBase.h"
+#include "MediaCanStartListener.h"
+#include "MediaProducer.h"
#include "MediaStreamPrivate.h"
#include "MediaStreamTrack.h"
#include "ScriptWrappable.h"
#include "Timer.h"
#include "URLRegistry.h"
+#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
namespace WebCore {
-class MediaStreamCenter;
-
-class MediaStream final : public RefCounted<MediaStream>, public URLRegistrable, public ScriptWrappable, public MediaStreamPrivateClient, public EventTargetWithInlineData, public ContextDestructionObserver {
+class Document;
+
+class MediaStream final
+ : public URLRegistrable
+ , public EventTargetWithInlineData
+ , public ContextDestructionObserver
+ , public MediaStreamTrack::Observer
+ , public MediaStreamPrivate::Observer
+ , private MediaProducer
+ , private MediaCanStartListener
+ , public RefCounted<MediaStream> {
public:
class Observer {
public:
+ virtual ~Observer() { }
virtual void didAddOrRemoveTrack() = 0;
};
- static PassRefPtr<MediaStream> create(ScriptExecutionContext&);
- static PassRefPtr<MediaStream> create(ScriptExecutionContext&, PassRefPtr<MediaStream>);
- static PassRefPtr<MediaStream> create(ScriptExecutionContext&, const Vector<RefPtr<MediaStreamTrack>>&);
- static PassRefPtr<MediaStream> create(ScriptExecutionContext&, PassRefPtr<MediaStreamPrivate>);
+ static Ref<MediaStream> create(ScriptExecutionContext&);
+ static Ref<MediaStream> create(ScriptExecutionContext&, MediaStream&);
+ static Ref<MediaStream> create(ScriptExecutionContext&, const MediaStreamTrackVector&);
+ static Ref<MediaStream> create(ScriptExecutionContext&, RefPtr<MediaStreamPrivate>&&);
virtual ~MediaStream();
String id() const { return m_private->id(); }
- void addTrack(PassRefPtr<MediaStreamTrack>, ExceptionCode&);
- void removeTrack(PassRefPtr<MediaStreamTrack>, ExceptionCode&);
+ void addTrack(MediaStreamTrack&);
+ void removeTrack(MediaStreamTrack&);
MediaStreamTrack* getTrackById(String);
- Vector<RefPtr<MediaStreamTrack>> getAudioTracks() const { return m_audioTracks; }
- Vector<RefPtr<MediaStreamTrack>> getVideoTracks() const { return m_videoTracks; }
+ MediaStreamTrackVector getAudioTracks() const;
+ MediaStreamTrackVector getVideoTracks() const;
+ MediaStreamTrackVector getTracks() const;
- bool ended() const;
- void setEnded();
- PassRefPtr<MediaStream> clone();
+ RefPtr<MediaStream> clone();
- DEFINE_ATTRIBUTE_EVENT_LISTENER(ended);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack);
+ bool active() const { return m_isActive; }
+ bool muted() const { return m_isMuted; }
MediaStreamPrivate* privateStream() const { return m_private.get(); }
+ void startProducingData();
+ void stopProducingData();
+
// EventTarget
- virtual EventTargetInterface eventTargetInterface() const final { return MediaStreamEventTargetInterfaceType; }
- virtual ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
+ EventTargetInterface eventTargetInterface() const final { return MediaStreamEventTargetInterfaceType; }
+ ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
using RefCounted<MediaStream>::ref;
using RefCounted<MediaStream>::deref;
// URLRegistrable
- virtual URLRegistry& registry() const override;
+ URLRegistry& registry() const override;
void addObserver(Observer*);
void removeObserver(Observer*);
protected:
- MediaStream(ScriptExecutionContext&, PassRefPtr<MediaStreamPrivate>);
+ MediaStream(ScriptExecutionContext&, const MediaStreamTrackVector&);
+ MediaStream(ScriptExecutionContext&, RefPtr<MediaStreamPrivate>&&);
// ContextDestructionObserver
- virtual void contextDestroyed() override final;
+ void contextDestroyed() final;
private:
+ enum class StreamModifier { DomAPI, Platform };
+
// EventTarget
- virtual void refEventTarget() override final { ref(); }
- virtual void derefEventTarget() override final { deref(); }
+ void refEventTarget() final { ref(); }
+ void derefEventTarget() final { deref(); }
+
+ // MediaStreamTrack::Observer
+ void trackDidEnd() final;
+
+ // MediaStreamPrivate::Observer
+ void activeStatusChanged() final;
+ void didAddTrack(MediaStreamTrackPrivate&) final;
+ void didRemoveTrack(MediaStreamTrackPrivate&) final;
+ void characteristicsChanged() final;
- // MediaStreamPrivateClient
- virtual void trackDidEnd() override final;
- virtual void streamDidEnd() override final;
- virtual void addRemoteSource(MediaStreamSource*) override final;
- virtual void removeRemoteSource(MediaStreamSource*) override final;
- virtual void addRemoteTrack(MediaStreamTrackPrivate*) override final;
- virtual void removeRemoteTrack(MediaStreamTrackPrivate*) override final;
+ // MediaProducer
+ void pageMutedStateDidChange() final;
+ MediaProducer::MediaStateFlags mediaState() const final;
- bool removeTrack(PassRefPtr<MediaStreamTrack>);
- bool addTrack(PassRefPtr<MediaStreamTrack>);
+ // MediaCanStartListener
+ void mediaCanStart(Document&) final;
- bool haveTrackWithSource(PassRefPtr<MediaStreamSource>);
+ bool internalAddTrack(Ref<MediaStreamTrack>&&, StreamModifier);
+ bool internalRemoveTrack(const String&, StreamModifier);
- void scheduleDispatchEvent(PassRefPtr<Event>);
- void scheduledEventTimerFired(Timer<MediaStream>*);
+ void scheduleActiveStateChange();
+ void activityEventTimerFired();
+ void setIsActive(bool);
+ void statusDidChange();
- void cloneMediaStreamTrackVector(Vector<RefPtr<MediaStreamTrack>>&, const Vector<RefPtr<MediaStreamTrack>>&);
+ Document* document() const;
- Vector<RefPtr<MediaStreamTrack>>* trackVectorForType(MediaStreamSource::Type);
+ MediaStreamTrackVector trackVectorForType(RealtimeMediaSource::Type) const;
RefPtr<MediaStreamPrivate> m_private;
- Vector<RefPtr<MediaStreamTrack>> m_audioTracks;
- Vector<RefPtr<MediaStreamTrack>> m_videoTracks;
- Timer<MediaStream> m_scheduledEventTimer;
- Vector<RefPtr<Event>> m_scheduledEvents;
+ HashMap<String, RefPtr<MediaStreamTrack>> m_trackSet;
+
+ Timer m_activityEventTimer;
+ Vector<Ref<Event>> m_scheduledActivityEvents;
Vector<Observer*> m_observers;
-};
-typedef Vector<RefPtr<MediaStream>> MediaStreamVector;
+ bool m_isActive { false };
+ bool m_isMuted { true };
+ bool m_externallyMuted { false };
+ bool m_isWaitingUntilMediaCanStart { false };
+};
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStream_h
diff --git a/Source/WebCore/Modules/mediastream/MediaStream.idl b/Source/WebCore/Modules/mediastream/MediaStream.idl
index 8dd4c9419..7fa377b89 100644
--- a/Source/WebCore/Modules/mediastream/MediaStream.idl
+++ b/Source/WebCore/Modules/mediastream/MediaStream.idl
@@ -24,37 +24,31 @@
[
Conditional=MEDIA_STREAM,
- EventTarget,
Constructor,
Constructor(MediaStream stream),
- Constructor(MediaStreamTrack[] tracks),
+ Constructor(sequence<MediaStreamTrack> tracks),
ConstructorCallWith=ScriptExecutionContext,
- InterfaceName=webkitMediaStream,
-] interface MediaStream {
+ PrivateIdentifier,
+ PublicIdentifier
+] interface MediaStream : EventTarget {
readonly attribute DOMString id;
sequence<MediaStreamTrack> getAudioTracks();
sequence<MediaStreamTrack> getVideoTracks();
-
- [RaisesException] void addTrack(MediaStreamTrack track);
- [RaisesException] void removeTrack(MediaStreamTrack track);
+ [PrivateIdentifier, PublicIdentifier] sequence<MediaStreamTrack> getTracks();
MediaStreamTrack getTrackById(DOMString trackId);
- MediaStream clone();
- readonly attribute boolean ended;
+ void addTrack(MediaStreamTrack track);
+ void removeTrack(MediaStreamTrack track);
+
+ MediaStream clone();
- attribute EventListener onended;
- attribute EventListener onaddtrack;
- attribute EventListener onremovetrack;
+ readonly attribute boolean active;
- // EventTarget interface
- void addEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- void removeEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event event);
+ attribute EventHandler onactive;
+ attribute EventHandler oninactive;
+ attribute EventHandler onaddtrack;
+ attribute EventHandler onremovetrack;
};
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamCapabilities.cpp b/Source/WebCore/Modules/mediastream/MediaStreamCapabilities.cpp
deleted file mode 100644
index ad7cead3f..000000000
--- a/Source/WebCore/Modules/mediastream/MediaStreamCapabilities.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamCapabilities.h"
-
-#include "AllAudioCapabilities.h"
-#include "AllVideoCapabilities.h"
-#include "CapabilityRange.h"
-#include "MediaSourceStates.h"
-#include "MediaStreamSourceCapabilities.h"
-
-namespace WebCore {
-
-RefPtr<MediaStreamCapabilities> MediaStreamCapabilities::create(PassRefPtr<MediaStreamSourceCapabilities> capabilities)
-{
- if (capabilities->hasVideoSource())
- return AllVideoCapabilities::create(capabilities);
-
- return AllAudioCapabilities::create(capabilities);
-}
-
-MediaStreamCapabilities::MediaStreamCapabilities(PassRefPtr<MediaStreamSourceCapabilities> capabilities)
- : m_SourceCapabilities(capabilities)
-{
-}
-
-Vector<String> MediaStreamCapabilities::sourceType() const
-{
- ASSERT(m_SourceCapabilities->hasVideoSource());
-
- size_t count = m_SourceCapabilities->sourceTypes().size();
- if (!count)
- return Vector<String>();
-
- const Vector<MediaStreamSourceStates::SourceType>& sourceTypes = m_SourceCapabilities->sourceTypes();
- Vector<String> capabilities;
- capabilities.reserveCapacity(count);
-
- for (size_t i = 0; i < count; ++i)
- capabilities.append(MediaStreamSourceStates::sourceType(sourceTypes[i]));
-
- return capabilities;
-}
-
-Vector<String> MediaStreamCapabilities::sourceId() const
-{
- size_t count = m_SourceCapabilities->sourceId().size();
- if (!count)
- return Vector<String>();
-
- const Vector<AtomicString>& sourceIds = m_SourceCapabilities->sourceId();
- Vector<String> capabilities;
- capabilities.reserveCapacity(count);
-
- for (size_t i = 0; i < count; ++i)
- capabilities.append(sourceIds[i]);
-
- return capabilities;
-}
-
-Vector<String> MediaStreamCapabilities::facingMode() const
-{
- ASSERT(m_SourceCapabilities->hasVideoSource());
-
- size_t count = m_SourceCapabilities->facingModes().size();
- if (!count)
- return Vector<String>();
-
- const Vector<MediaStreamSourceStates::VideoFacingMode>& facingModes = m_SourceCapabilities->facingModes();
- Vector<String> capabilities;
- capabilities.reserveCapacity(count);
-
- for (size_t i = 0; i < count; ++i)
- capabilities.append(MediaStreamSourceStates::facingMode(facingModes[i]));
-
- return capabilities;
-}
-
-RefPtr<CapabilityRange> MediaStreamCapabilities::width() const
-{
- ASSERT(m_SourceCapabilities->hasVideoSource());
-
- return CapabilityRange::create(m_SourceCapabilities->width());
-}
-
-RefPtr<CapabilityRange> MediaStreamCapabilities::height() const
-{
- ASSERT(m_SourceCapabilities->hasVideoSource());
-
- return CapabilityRange::create(m_SourceCapabilities->height());
-}
-
-RefPtr<CapabilityRange> MediaStreamCapabilities::frameRate() const
-{
- ASSERT(m_SourceCapabilities->hasVideoSource());
-
- return CapabilityRange::create(m_SourceCapabilities->frameRate());
-}
-
-RefPtr<CapabilityRange> MediaStreamCapabilities::aspectRatio() const
-{
- ASSERT(m_SourceCapabilities->hasVideoSource());
-
- return CapabilityRange::create(m_SourceCapabilities->aspectRatio());
-}
-
-RefPtr<CapabilityRange> MediaStreamCapabilities::volume() const
-{
- ASSERT(!m_SourceCapabilities->hasVideoSource());
-
- return CapabilityRange::create(m_SourceCapabilities->volume());
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamCapabilities.h b/Source/WebCore/Modules/mediastream/MediaStreamCapabilities.h
deleted file mode 100644
index 5ad3412ea..000000000
--- a/Source/WebCore/Modules/mediastream/MediaStreamCapabilities.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaStreamCapabilities_h
-#define MediaStreamCapabilities_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamCapabilities.h"
-#include "MediaStreamSourceCapabilities.h"
-#include "ScriptWrappable.h"
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class CapabilityRange;
-class MediaStreamSourceCapabilities;
-
-class MediaStreamCapabilities : public RefCounted<MediaStreamCapabilities>, public ScriptWrappable {
-public:
- static RefPtr<MediaStreamCapabilities> create(PassRefPtr<MediaStreamSourceCapabilities>);
- virtual ~MediaStreamCapabilities() { }
-
- virtual Vector<String> sourceType() const;
- virtual Vector<String> sourceId() const;
- virtual RefPtr<CapabilityRange> width() const;
- virtual RefPtr<CapabilityRange> height() const;
- virtual RefPtr<CapabilityRange> frameRate() const;
- virtual RefPtr<CapabilityRange> aspectRatio() const;
- virtual Vector<String> facingMode() const;
- virtual RefPtr<CapabilityRange> volume() const;
-
- bool hasVideoSource() { return m_SourceCapabilities->hasVideoSource(); }
-
-protected:
- explicit MediaStreamCapabilities(PassRefPtr<MediaStreamSourceCapabilities>);
-
- RefPtr<MediaStreamSourceCapabilities> m_SourceCapabilities;
-};
-
-} // namespace WebCore
-
-#endif // MediaStreamCapabilities_h
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamCapabilities.idl b/Source/WebCore/Modules/mediastream/MediaStreamCapabilities.idl
deleted file mode 100644
index dd71ccbf6..000000000
--- a/Source/WebCore/Modules/mediastream/MediaStreamCapabilities.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Conditional=MEDIA_STREAM,
- NoInterfaceObject,
- SkipVTableValidation,
- CustomToJSObject,
-] interface MediaStreamCapabilities {
-};
-
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamEvent.cpp b/Source/WebCore/Modules/mediastream/MediaStreamEvent.cpp
index 92f6bb14f..09584b2ba 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamEvent.cpp
+++ b/Source/WebCore/Modules/mediastream/MediaStreamEvent.cpp
@@ -25,45 +25,30 @@
#include "config.h"
#include "MediaStreamEvent.h"
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
-#include "EventNames.h"
#include "MediaStream.h"
namespace WebCore {
-MediaStreamEventInit::MediaStreamEventInit()
- : stream(0)
+Ref<MediaStreamEvent> MediaStreamEvent::create(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<MediaStream>&& stream)
{
+ return adoptRef(*new MediaStreamEvent(type, canBubble, cancelable, WTFMove(stream)));
}
-PassRefPtr<MediaStreamEvent> MediaStreamEvent::create()
+Ref<MediaStreamEvent> MediaStreamEvent::create(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
{
- return adoptRef(new MediaStreamEvent);
+ return adoptRef(*new MediaStreamEvent(type, initializer, isTrusted));
}
-PassRefPtr<MediaStreamEvent> MediaStreamEvent::create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<MediaStream> stream)
-{
- return adoptRef(new MediaStreamEvent(type, canBubble, cancelable, stream));
-}
-
-PassRefPtr<MediaStreamEvent> MediaStreamEvent::create(const AtomicString& type, const MediaStreamEventInit& initializer)
-{
- return adoptRef(new MediaStreamEvent(type, initializer));
-}
-
-MediaStreamEvent::MediaStreamEvent()
-{
-}
-
-MediaStreamEvent::MediaStreamEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<MediaStream> stream)
+MediaStreamEvent::MediaStreamEvent(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<MediaStream>&& stream)
: Event(type, canBubble, cancelable)
- , m_stream(stream)
+ , m_stream(WTFMove(stream))
{
}
-MediaStreamEvent::MediaStreamEvent(const AtomicString& type, const MediaStreamEventInit& initializer)
- : Event(type, initializer)
+MediaStreamEvent::MediaStreamEvent(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
+ : Event(type, initializer, isTrusted)
, m_stream(initializer.stream)
{
}
@@ -84,5 +69,5 @@ EventInterface MediaStreamEvent::eventInterface() const
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamEvent.h b/Source/WebCore/Modules/mediastream/MediaStreamEvent.h
index bad394e0a..f67c52952 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamEvent.h
+++ b/Source/WebCore/Modules/mediastream/MediaStreamEvent.h
@@ -22,10 +22,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaStreamEvent_h
-#define MediaStreamEvent_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include "Event.h"
#include "MediaStream.h"
@@ -33,34 +32,28 @@
namespace WebCore {
-struct MediaStreamEventInit : public EventInit {
- MediaStreamEventInit();
-
- RefPtr<MediaStream> stream;
-};
-
class MediaStreamEvent : public Event {
public:
virtual ~MediaStreamEvent();
- static PassRefPtr<MediaStreamEvent> create();
- static PassRefPtr<MediaStreamEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<MediaStream>);
- static PassRefPtr<MediaStreamEvent> create(const AtomicString& type, const MediaStreamEventInit& initializer);
+ static Ref<MediaStreamEvent> create(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<MediaStream>&&);
+
+ struct Init : EventInit {
+ RefPtr<MediaStream> stream;
+ };
+ static Ref<MediaStreamEvent> create(const AtomicString& type, const Init& initializer, IsTrusted = IsTrusted::No);
MediaStream* stream() const;
virtual EventInterface eventInterface() const;
private:
- MediaStreamEvent();
- MediaStreamEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<MediaStream>);
- MediaStreamEvent(const AtomicString& type, const MediaStreamEventInit&);
+ MediaStreamEvent(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<MediaStream>&&);
+ MediaStreamEvent(const AtomicString& type, const Init&, IsTrusted);
RefPtr<MediaStream> m_stream;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStreamEvent_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamEvent.idl b/Source/WebCore/Modules/mediastream/MediaStreamEvent.idl
index b44729ca3..e4ffceb15 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamEvent.idl
+++ b/Source/WebCore/Modules/mediastream/MediaStreamEvent.idl
@@ -23,9 +23,13 @@
*/
[
- Conditional=MEDIA_STREAM,
- ConstructorTemplate=Event
+ Conditional=WEB_RTC,
+ Constructor(DOMString type, optional MediaStreamEventInit eventInitDict),
+ EnabledAtRuntime=MediaStream,
] interface MediaStreamEvent : Event {
- [InitializedByEventConstructor] readonly attribute MediaStream stream;
+ readonly attribute MediaStream? stream;
};
+dictionary MediaStreamEventInit : EventInit {
+ MediaStream? stream = null;
+};
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamRegistry.cpp b/Source/WebCore/Modules/mediastream/MediaStreamRegistry.cpp
index 9a2eeb18e..843498657 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamRegistry.cpp
+++ b/Source/WebCore/Modules/mediastream/MediaStreamRegistry.cpp
@@ -28,25 +28,26 @@
#if ENABLE(MEDIA_STREAM)
-#include "URL.h"
#include "MediaStream.h"
+#include "URL.h"
#include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
namespace WebCore {
-MediaStreamRegistry& MediaStreamRegistry::registry()
+MediaStreamRegistry& MediaStreamRegistry::shared()
{
// Since WebWorkers cannot obtain MediaSource objects, we should be on the main thread.
ASSERT(isMainThread());
- DEFINE_STATIC_LOCAL(MediaStreamRegistry, instance, ());
+ static NeverDestroyed<MediaStreamRegistry> instance;
return instance;
}
-void MediaStreamRegistry::registerURL(SecurityOrigin*, const URL& url, URLRegistrable* stream)
+void MediaStreamRegistry::registerURL(SecurityOrigin*, const URL& url, URLRegistrable& stream)
{
- ASSERT(&stream->registry() == this);
+ ASSERT(&stream.registry() == this);
ASSERT(isMainThread());
- m_mediaStreams.set(url.string(), static_cast<MediaStream*>(stream));
+ m_mediaStreams.set(url.string(), static_cast<MediaStream*>(&stream));
}
void MediaStreamRegistry::unregisterURL(const URL& url)
@@ -61,6 +62,45 @@ URLRegistrable* MediaStreamRegistry::lookup(const String& url) const
return m_mediaStreams.get(url);
}
+MediaStreamRegistry::MediaStreamRegistry()
+{
+}
+
+MediaStream* MediaStreamRegistry::lookUp(const URL& url) const
+{
+ return static_cast<MediaStream*>(lookup(url.string()));
+}
+
+static Vector<MediaStream*>& mediaStreams()
+{
+ static NeverDestroyed<Vector<MediaStream*>> streams;
+ return streams;
+}
+
+void MediaStreamRegistry::registerStream(MediaStream& stream)
+{
+ mediaStreams().append(&stream);
+}
+
+void MediaStreamRegistry::unregisterStream(MediaStream& stream)
+{
+ Vector<MediaStream*>& allStreams = mediaStreams();
+ size_t pos = allStreams.find(&stream);
+ if (pos != notFound)
+ allStreams.remove(pos);
+}
+
+MediaStream* MediaStreamRegistry::lookUp(const MediaStreamPrivate& privateStream) const
+{
+ Vector<MediaStream*>& allStreams = mediaStreams();
+ for (auto& stream : allStreams) {
+ if (stream->privateStream() == &privateStream)
+ return stream;
+ }
+
+ return nullptr;
+}
+
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamRegistry.h b/Source/WebCore/Modules/mediastream/MediaStreamRegistry.h
index cfea9f59e..7e23a1e2e 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamRegistry.h
+++ b/Source/WebCore/Modules/mediastream/MediaStreamRegistry.h
@@ -23,38 +23,44 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaStreamRegistry_h
-#define MediaStreamRegistry_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
#include "URLRegistry.h"
#include <wtf/HashMap.h>
-#include <wtf/PassRefPtr.h>
#include <wtf/text/StringHash.h>
namespace WebCore {
-class URL;
class MediaStream;
+class MediaStreamPrivate;
+class URL;
class MediaStreamRegistry final : public URLRegistry {
public:
+ friend class NeverDestroyed<MediaStreamRegistry>;
+
// Returns a single instance of MediaStreamRegistry.
- static MediaStreamRegistry& registry();
+ static MediaStreamRegistry& shared();
// Registers a blob URL referring to the specified stream data.
- virtual void registerURL(SecurityOrigin*, const URL&, URLRegistrable*) override;
- virtual void unregisterURL(const URL&) override;
+ void registerURL(SecurityOrigin*, const URL&, URLRegistrable&) override;
+ void unregisterURL(const URL&) override;
- virtual URLRegistrable* lookup(const String&) const override;
+ URLRegistrable* lookup(const String&) const override;
+
+ void registerStream(MediaStream&);
+ void unregisterStream(MediaStream&);
+
+ MediaStream* lookUp(const URL&) const;
+ MediaStream* lookUp(const MediaStreamPrivate&) const;
private:
+ MediaStreamRegistry();
HashMap<String, RefPtr<MediaStream>> m_mediaStreams;
};
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStreamRegistry_h
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp
index 476dec103..96cc6298b 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp
+++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
*
* Redistribution and use in source and binary forms, with or without
@@ -30,292 +30,345 @@
#if ENABLE(MEDIA_STREAM)
-#include "AllAudioCapabilities.h"
-#include "AllVideoCapabilities.h"
-#include "AudioStreamTrack.h"
-#include "Dictionary.h"
#include "Event.h"
-#include "ExceptionCode.h"
-#include "ExceptionCodePlaceholder.h"
+#include "EventNames.h"
+#include "JSOverconstrainedError.h"
#include "MediaConstraintsImpl.h"
-#include "MediaSourceStates.h"
#include "MediaStream.h"
-#include "MediaStreamCenter.h"
#include "MediaStreamPrivate.h"
-#include "MediaStreamTrackSourcesCallback.h"
-#include "MediaStreamTrackSourcesRequest.h"
-#include "MediaTrackConstraints.h"
#include "NotImplemented.h"
-#include "VideoStreamTrack.h"
-#include <wtf/Functional.h>
+#include "OverconstrainedError.h"
+#include "ScriptExecutionContext.h"
#include <wtf/NeverDestroyed.h>
namespace WebCore {
-MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack, const Dictionary* constraints)
- : RefCounted()
- , ActiveDOMObject(&context)
- , m_privateTrack(privateTrack)
- , m_eventDispatchScheduled(false)
- , m_stoppingTrack(false)
+Ref<MediaStreamTrack> MediaStreamTrack::create(ScriptExecutionContext& context, Ref<MediaStreamTrackPrivate>&& privateTrack)
{
- suspendIfNeeded();
-
- m_privateTrack->setClient(this);
-
- if (constraints)
- applyConstraints(*constraints);
+ return adoptRef(*new MediaStreamTrack(context, WTFMove(privateTrack)));
}
-MediaStreamTrack::MediaStreamTrack(MediaStreamTrack& other)
- : RefCounted()
- , ActiveDOMObject(other.scriptExecutionContext())
- , m_privateTrack(*other.privateTrack().clone())
- , m_eventDispatchScheduled(false)
- , m_stoppingTrack(false)
+MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, Ref<MediaStreamTrackPrivate>&& privateTrack)
+ : ActiveDOMObject(&context)
+ , m_private(WTFMove(privateTrack))
+ , m_weakPtrFactory(this)
{
suspendIfNeeded();
- m_privateTrack->setClient(this);
+ m_private->addObserver(*this);
}
MediaStreamTrack::~MediaStreamTrack()
{
- m_privateTrack->setClient(nullptr);
+ m_private->removeObserver(*this);
}
-void MediaStreamTrack::setSource(PassRefPtr<MediaStreamSource> newSource)
+const AtomicString& MediaStreamTrack::kind() const
{
- m_privateTrack->setSource(newSource);
+ static NeverDestroyed<AtomicString> audioKind("audio", AtomicString::ConstructFromLiteral);
+ static NeverDestroyed<AtomicString> videoKind("video", AtomicString::ConstructFromLiteral);
+
+ if (m_private->type() == RealtimeMediaSource::Audio)
+ return audioKind;
+ return videoKind;
}
const String& MediaStreamTrack::id() const
{
- return m_privateTrack->id();
+ return m_private->id();
}
const String& MediaStreamTrack::label() const
{
- return m_privateTrack->label();
+ return m_private->label();
}
bool MediaStreamTrack::enabled() const
{
- return m_privateTrack->enabled();
+ return m_private->enabled();
}
void MediaStreamTrack::setEnabled(bool enabled)
{
- m_privateTrack->setEnabled(enabled);
-}
-
-bool MediaStreamTrack::stopped() const
-{
- return m_privateTrack->stopped();
+ m_private->setEnabled(enabled);
}
bool MediaStreamTrack::muted() const
{
- return m_privateTrack->muted();
+ return m_private->muted();
}
bool MediaStreamTrack::readonly() const
{
- return m_privateTrack->readonly();
+ return m_private->readonly();
}
bool MediaStreamTrack::remote() const
{
- return m_privateTrack->remote();
+ return m_private->remote();
}
-const AtomicString& MediaStreamTrack::readyState() const
+auto MediaStreamTrack::readyState() const -> State
{
- static NeverDestroyed<AtomicString> ended("ended", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> live("live", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> newState("new", AtomicString::ConstructFromLiteral);
-
- switch (m_privateTrack->readyState()) {
- case MediaStreamSource::Live:
- return live;
- case MediaStreamSource::New:
- return newState;
- case MediaStreamSource::Ended:
- return ended;
- }
-
- ASSERT_NOT_REACHED();
- return emptyAtom;
+ return ended() ? State::Ended : State::Live;
}
-void MediaStreamTrack::getSources(ScriptExecutionContext* context, PassRefPtr<MediaStreamTrackSourcesCallback> callback, ExceptionCode& ec)
+bool MediaStreamTrack::ended() const
{
- RefPtr<MediaStreamTrackSourcesRequest> request = MediaStreamTrackSourcesRequest::create(context, callback);
- if (!MediaStreamCenter::shared().getMediaStreamTrackSources(request.release()))
- ec = NOT_SUPPORTED_ERR;
+ return m_ended || m_private->ended();
}
-RefPtr<MediaTrackConstraints> MediaStreamTrack::constraints() const
+Ref<MediaStreamTrack> MediaStreamTrack::clone()
{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=122428
- notImplemented();
- return 0;
+ return MediaStreamTrack::create(*scriptExecutionContext(), m_private->clone());
}
-RefPtr<MediaSourceStates> MediaStreamTrack::states() const
+void MediaStreamTrack::stopProducingData()
{
- return MediaSourceStates::create(m_privateTrack->states());
-}
+ // NOTE: this method is called when the "stop" method is called from JS, using
+ // the "ImplementedAs" IDL attribute. This is done because ActiveDOMObject requires
+ // a "stop" method.
-RefPtr<MediaStreamCapabilities> MediaStreamTrack::capabilities() const
-{
- // The source may be shared by multiple tracks, so its states is not necessarily
- // in sync with the track state. A track that is new or has ended always has a source
- // type of "none".
- RefPtr<MediaStreamSourceCapabilities> sourceCapabilities = m_privateTrack->capabilities();
- MediaStreamSource::ReadyState readyState = m_privateTrack->readyState();
- if (readyState == MediaStreamSource::New || readyState == MediaStreamSource::Ended)
- sourceCapabilities->setSourceType(MediaStreamSourceStates::None);
-
- return MediaStreamCapabilities::create(sourceCapabilities.release());
+ // http://w3c.github.io/mediacapture-main/#widl-MediaStreamTrack-stop-void
+ // 4.3.3.2 Methods
+ // When a MediaStreamTrack object's stop() method is invoked, the User Agent must run following steps:
+ // 1. Let track be the current MediaStreamTrack object.
+ // 2. If track is sourced by a non-local source, then abort these steps.
+ if (remote() || ended())
+ return;
+
+ // 3. Notify track's source that track is ended so that the source may be stopped, unless other
+ // MediaStreamTrack objects depend on it.
+ // 4. Set track's readyState attribute to ended.
+
+ // Set m_ended to true before telling the private to stop so we do not fire an 'ended' event.
+ m_ended = true;
+
+ m_private->endTrack();
+}
+
+MediaStreamTrack::TrackSettings MediaStreamTrack::getSettings() const
+{
+ auto& settings = m_private->settings();
+ TrackSettings result;
+ if (settings.supportsWidth())
+ result.width = settings.width();
+ if (settings.supportsHeight())
+ result.height = settings.height();
+ if (settings.supportsAspectRatio() && settings.aspectRatio()) // FIXME: Why the check for zero here?
+ result.aspectRatio = settings.aspectRatio();
+ if (settings.supportsFrameRate())
+ result.frameRate = settings.frameRate();
+ if (settings.supportsFacingMode())
+ result.facingMode = RealtimeMediaSourceSettings::facingMode(settings.facingMode());
+ if (settings.supportsVolume())
+ result.volume = settings.volume();
+ if (settings.supportsSampleRate())
+ result.sampleRate = settings.sampleRate();
+ if (settings.supportsSampleSize())
+ result.sampleSize = settings.sampleSize();
+ if (settings.supportsEchoCancellation())
+ result.echoCancellation = settings.echoCancellation();
+ if (settings.supportsDeviceId())
+ result.deviceId = settings.deviceId();
+ if (settings.supportsGroupId())
+ result.groupId = settings.groupId();
+ return result;
+}
+
+static DoubleRange capabilityDoubleRange(const CapabilityValueOrRange& value)
+{
+ DoubleRange range;
+ switch (value.type()) {
+ case CapabilityValueOrRange::Double:
+ range.min = value.value().asDouble;
+ range.max = range.min;
+ break;
+ case CapabilityValueOrRange::DoubleRange:
+ range.min = value.rangeMin().asDouble;
+ range.max = value.rangeMax().asDouble;
+ break;
+ case CapabilityValueOrRange::Undefined:
+ case CapabilityValueOrRange::ULong:
+ case CapabilityValueOrRange::ULongRange:
+ ASSERT_NOT_REACHED();
+ }
+ return range;
+}
+
+static LongRange capabilityIntRange(const CapabilityValueOrRange& value)
+{
+ LongRange range;
+ switch (value.type()) {
+ case CapabilityValueOrRange::ULong:
+ range.min = value.value().asInt;
+ range.max = range.min;
+ break;
+ case CapabilityValueOrRange::ULongRange:
+ range.min = value.rangeMin().asInt;
+ range.max = value.rangeMax().asInt;
+ break;
+ case CapabilityValueOrRange::Undefined:
+ case CapabilityValueOrRange::Double:
+ case CapabilityValueOrRange::DoubleRange:
+ ASSERT_NOT_REACHED();
+ }
+ return range;
}
-void MediaStreamTrack::applyConstraints(const Dictionary& constraints)
+static Vector<String> capabilityStringVector(const Vector<RealtimeMediaSourceSettings::VideoFacingMode>& modes)
{
- m_constraints->initialize(constraints);
- m_privateTrack->applyConstraints(m_constraints);
+ Vector<String> result;
+ result.reserveCapacity(modes.size());
+ for (auto& mode : modes)
+ result.uncheckedAppend(RealtimeMediaSourceSettings::facingMode(mode));
+ return result;
}
-void MediaStreamTrack::applyConstraints(PassRefPtr<MediaConstraints>)
+static Vector<bool> capabilityBooleanVector(RealtimeMediaSourceCapabilities::EchoCancellation cancellation)
{
- // FIXME: apply the new constraints to the track
- // https://bugs.webkit.org/show_bug.cgi?id=122428
+ Vector<bool> result;
+ result.reserveCapacity(2);
+ result.uncheckedAppend(true);
+ result.uncheckedAppend(cancellation == RealtimeMediaSourceCapabilities::EchoCancellation::ReadWrite);
+ return result;
}
-RefPtr<MediaStreamTrack> MediaStreamTrack::clone()
+MediaStreamTrack::TrackCapabilities MediaStreamTrack::getCapabilities() const
{
- if (m_privateTrack->type() == MediaStreamSource::Audio)
- return AudioStreamTrack::create(*this);
-
- return VideoStreamTrack::create(*this);
+ auto capabilities = m_private->capabilities();
+ TrackCapabilities result;
+ if (capabilities->supportsWidth())
+ result.width = capabilityIntRange(capabilities->width());
+ if (capabilities->supportsHeight())
+ result.height = capabilityIntRange(capabilities->height());
+ if (capabilities->supportsAspectRatio())
+ result.aspectRatio = capabilityDoubleRange(capabilities->aspectRatio());
+ if (capabilities->supportsFrameRate())
+ result.frameRate = capabilityDoubleRange(capabilities->frameRate());
+ if (capabilities->supportsFacingMode())
+ result.facingMode = capabilityStringVector(capabilities->facingMode());
+ if (capabilities->supportsVolume())
+ result.volume = capabilityDoubleRange(capabilities->volume());
+ if (capabilities->supportsSampleRate())
+ result.sampleRate = capabilityIntRange(capabilities->sampleRate());
+ if (capabilities->supportsSampleSize())
+ result.sampleSize = capabilityIntRange(capabilities->sampleSize());
+ if (capabilities->supportsEchoCancellation())
+ result.echoCancellation = capabilityBooleanVector(capabilities->echoCancellation());
+ if (capabilities->supportsDeviceId())
+ result.deviceId = capabilities->deviceId();
+ if (capabilities->supportsGroupId())
+ result.groupId = capabilities->groupId();
+ return result;
}
-void MediaStreamTrack::stopProducingData()
+static Ref<MediaConstraintsImpl> createMediaConstraintsImpl(const std::optional<MediaTrackConstraints>& constraints)
{
- // NOTE: this method is called when the "stop" method is called from JS, using
- // the "ImplementedAs" IDL attribute. This is done because ActiveDOMObject requires
- // a "stop" method.
-
- // The stop method should "Permanently stop the generation of data for track's source", but it
- // should not post an 'ended' event.
- m_stoppingTrack = true;
- m_privateTrack->stop(MediaStreamTrackPrivate::StopTrackAndStopSource);
- m_stoppingTrack = false;
+ if (!constraints)
+ return MediaConstraintsImpl::create({ }, { }, true);
+ return createMediaConstraintsImpl(constraints.value());
}
-bool MediaStreamTrack::ended() const
+void MediaStreamTrack::applyConstraints(const std::optional<MediaTrackConstraints>& constraints, DOMPromise<void>&& promise)
{
- return m_privateTrack->ended();
+ m_promise = WTFMove(promise);
+
+ auto weakThis = createWeakPtr();
+ auto failureHandler = [weakThis] (const String& failedConstraint, const String& message) {
+ if (!weakThis || !weakThis->m_promise)
+ return;
+ weakThis->m_promise->rejectType<IDLInterface<OverconstrainedError>>(OverconstrainedError::create(failedConstraint, message).get());
+ };
+ auto successHandler = [weakThis, constraints] () {
+ if (!weakThis || !weakThis->m_promise)
+ return;
+ weakThis->m_promise->resolve();
+ weakThis->m_constraints = constraints.value_or(MediaTrackConstraints { });
+ };
+ m_private->applyConstraints(createMediaConstraintsImpl(constraints), successHandler, failureHandler);
}
-void MediaStreamTrack::addObserver(MediaStreamTrack::Observer* observer)
+void MediaStreamTrack::addObserver(Observer& observer)
{
- m_observers.append(observer);
+ m_observers.append(&observer);
}
-void MediaStreamTrack::removeObserver(MediaStreamTrack::Observer* observer)
+void MediaStreamTrack::removeObserver(Observer& observer)
{
- size_t pos = m_observers.find(observer);
- if (pos != notFound)
- m_observers.remove(pos);
+ m_observers.removeFirst(&observer);
}
-void MediaStreamTrack::trackReadyStateChanged()
+void MediaStreamTrack::trackEnded(MediaStreamTrackPrivate&)
{
- if (stopped())
+ // http://w3c.github.io/mediacapture-main/#life-cycle
+ // When a MediaStreamTrack track ends for any reason other than the stop() method being invoked, the User Agent must queue a task that runs the following steps:
+ // 1. If the track's readyState attribute has the value ended already, then abort these steps.
+ if (m_ended)
return;
- MediaStreamSource::ReadyState readyState = m_privateTrack->readyState();
- if (readyState == MediaStreamSource::Live)
- scheduleEventDispatch(Event::create(eventNames().startedEvent, false, false));
- else if (readyState == MediaStreamSource::Ended && !m_stoppingTrack)
- scheduleEventDispatch(Event::create(eventNames().endedEvent, false, false));
+ // 2. Set track's readyState attribute to ended.
+ m_ended = true;
+
+ if (scriptExecutionContext()->activeDOMObjectsAreSuspended() || scriptExecutionContext()->activeDOMObjectsAreStopped())
+ return;
+
+ // 3. Notify track's source that track is ended so that the source may be stopped, unless other MediaStreamTrack objects depend on it.
+ // 4. Fire a simple event named ended at the object.
+ dispatchEvent(Event::create(eventNames().endedEvent, false, false));
+
+ for (auto& observer : m_observers)
+ observer->trackDidEnd();
configureTrackRendering();
}
-void MediaStreamTrack::trackMutedChanged()
+void MediaStreamTrack::trackMutedChanged(MediaStreamTrackPrivate&)
{
- if (stopped())
+ if (scriptExecutionContext()->activeDOMObjectsAreSuspended() || scriptExecutionContext()->activeDOMObjectsAreStopped())
return;
- if (muted())
- scheduleEventDispatch(Event::create(eventNames().muteEvent, false, false));
- else
- scheduleEventDispatch(Event::create(eventNames().unmuteEvent, false, false));
+ AtomicString eventType = muted() ? eventNames().muteEvent : eventNames().unmuteEvent;
+ dispatchEvent(Event::create(eventType, false, false));
configureTrackRendering();
}
-void MediaStreamTrack::trackEnabledChanged()
+void MediaStreamTrack::trackSettingsChanged(MediaStreamTrackPrivate&)
{
- if (stopped())
- return;
+ configureTrackRendering();
+}
- setEnabled(m_privateTrack->enabled());
+void MediaStreamTrack::trackEnabledChanged(MediaStreamTrackPrivate&)
+{
configureTrackRendering();
}
void MediaStreamTrack::configureTrackRendering()
{
- if (stopped())
- return;
-
// 4.3.1
// ... media from the source only flows when a MediaStreamTrack object is both unmuted and enabled
}
-void MediaStreamTrack::trackDidEnd()
+void MediaStreamTrack::stop()
{
- m_privateTrack->setReadyState(MediaStreamSource::Ended);
-
- for (Vector<Observer*>::iterator i = m_observers.begin(); i != m_observers.end(); ++i)
- (*i)->trackDidEnd();
+ stopProducingData();
}
-void MediaStreamTrack::stop()
+const char* MediaStreamTrack::activeDOMObjectName() const
{
- m_privateTrack->stop(MediaStreamTrackPrivate::StopTrackOnly);
+ return "MediaStreamTrack";
}
-void MediaStreamTrack::scheduleEventDispatch(PassRefPtr<Event> event)
+bool MediaStreamTrack::canSuspendForDocumentSuspension() const
{
- {
- MutexLocker locker(m_mutex);
- m_scheduledEvents.append(event);
- if (m_eventDispatchScheduled)
- return;
- m_eventDispatchScheduled = true;
- }
-
- callOnMainThread(bind(&MediaStreamTrack::dispatchQueuedEvents, this));
+ // FIXME: We should try and do better here.
+ return false;
}
-void MediaStreamTrack::dispatchQueuedEvents()
+AudioSourceProvider* MediaStreamTrack::audioSourceProvider()
{
- Vector<RefPtr<Event>> events;
- {
- MutexLocker locker(m_mutex);
- m_eventDispatchScheduled = false;
- events.swap(m_scheduledEvents);
- }
- if (!scriptExecutionContext())
- return;
-
- for (auto it = events.begin(); it != events.end(); ++it)
- dispatchEvent((*it).release());
-
- events.clear();
+ return m_private->audioSourceProvider();
}
} // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h
index 64ea32d3f..118728758 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h
+++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
*
* Redistribution and use in source and binary forms, with or without
@@ -25,31 +25,25 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaStreamTrack_h
-#define MediaStreamTrack_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
#include "ActiveDOMObject.h"
+#include "DoubleRange.h"
#include "EventTarget.h"
-#include "MediaStreamSource.h"
+#include "JSDOMPromise.h"
+#include "LongRange.h"
#include "MediaStreamTrackPrivate.h"
-#include "ScriptWrappable.h"
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
+#include "MediaTrackConstraints.h"
namespace WebCore {
-class Dictionary;
-class MediaConstraintsImpl;
-class MediaSourceStates;
-class MediaStreamTrackSourcesCallback;
-class MediaStreamCapabilities;
-class MediaTrackConstraints;
+class AudioSourceProvider;
-class MediaStreamTrack : public RefCounted<MediaStreamTrack>, public ScriptWrappable, public ActiveDOMObject, public EventTargetWithInlineData, public MediaStreamTrackPrivateClient {
+struct MediaTrackConstraints;
+
+class MediaStreamTrack final : public RefCounted<MediaStreamTrack>, public ActiveDOMObject, public EventTargetWithInlineData, private MediaStreamTrackPrivate::Observer {
public:
class Observer {
public:
@@ -57,9 +51,10 @@ public:
virtual void trackDidEnd() = 0;
};
+ static Ref<MediaStreamTrack> create(ScriptExecutionContext&, Ref<MediaStreamTrackPrivate>&&);
virtual ~MediaStreamTrack();
- virtual const AtomicString& kind() const = 0;
+ const AtomicString& kind() const;
const String& id() const;
const String& label() const;
@@ -69,82 +64,96 @@ public:
bool muted() const;
bool readonly() const;
bool remote() const;
- bool stopped() const;
-
- const AtomicString& readyState() const;
- static void getSources(ScriptExecutionContext*, PassRefPtr<MediaStreamTrackSourcesCallback>, ExceptionCode&);
+ enum class State { New, Live, Ended };
+ State readyState() const;
- RefPtr<MediaTrackConstraints> constraints() const;
- RefPtr<MediaSourceStates> states() const;
- RefPtr<MediaStreamCapabilities> capabilities() const;
- void applyConstraints(const Dictionary&);
- void applyConstraints(PassRefPtr<MediaConstraints>);
+ bool ended() const;
- RefPtr<MediaStreamTrack> clone();
+ Ref<MediaStreamTrack> clone();
void stopProducingData();
- DEFINE_ATTRIBUTE_EVENT_LISTENER(mute);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(unmute);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(started);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(ended);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(overconstrained);
-
- MediaStreamSource* source() const { return m_privateTrack->source(); }
- MediaStreamTrackPrivate& privateTrack() { return m_privateTrack.get(); }
-
- bool ended() const;
+ struct TrackSettings {
+ std::optional<int> width;
+ std::optional<int> height;
+ std::optional<double> aspectRatio;
+ std::optional<double> frameRate;
+ String facingMode;
+ std::optional<double> volume;
+ std::optional<int> sampleRate;
+ std::optional<int> sampleSize;
+ std::optional<bool> echoCancellation;
+ String deviceId;
+ String groupId;
+ };
+ TrackSettings getSettings() const;
+
+ struct TrackCapabilities {
+ std::optional<LongRange> width;
+ std::optional<LongRange> height;
+ std::optional<DoubleRange> aspectRatio;
+ std::optional<DoubleRange> frameRate;
+ std::optional<Vector<String>> facingMode;
+ std::optional<DoubleRange> volume;
+ std::optional<LongRange> sampleRate;
+ std::optional<LongRange> sampleSize;
+ std::optional<Vector<bool>> echoCancellation;
+ String deviceId;
+ String groupId;
+ };
+ TrackCapabilities getCapabilities() const;
- void addObserver(Observer*);
- void removeObserver(Observer*);
+ const MediaTrackConstraints& getConstraints() const { return m_constraints; }
+ void applyConstraints(const std::optional<MediaTrackConstraints>&, DOMPromise<void>&&);
- // EventTarget
- virtual EventTargetInterface eventTargetInterface() const override final { return MediaStreamTrackEventTargetInterfaceType; }
- virtual ScriptExecutionContext* scriptExecutionContext() const override final { return ActiveDOMObject::scriptExecutionContext(); }
+ RealtimeMediaSource& source() { return m_private->source(); }
+ MediaStreamTrackPrivate& privateTrack() { return m_private.get(); }
- using RefCounted<MediaStreamTrack>::ref;
- using RefCounted<MediaStreamTrack>::deref;
+ AudioSourceProvider* audioSourceProvider();
-protected:
- explicit MediaStreamTrack(MediaStreamTrack&);
- MediaStreamTrack(ScriptExecutionContext&, MediaStreamTrackPrivate&, const Dictionary*);
+ void addObserver(Observer&);
+ void removeObserver(Observer&);
- void setSource(PassRefPtr<MediaStreamSource>);
+ using RefCounted::ref;
+ using RefCounted::deref;
private:
+ MediaStreamTrack(ScriptExecutionContext&, Ref<MediaStreamTrackPrivate>&&);
+ explicit MediaStreamTrack(MediaStreamTrack&);
void configureTrackRendering();
- void trackDidEnd();
- void scheduleEventDispatch(PassRefPtr<Event>);
- void dispatchQueuedEvents();
- // ActiveDOMObject
- virtual void stop() override final;
+ // ActiveDOMObject API.
+ void stop() final;
+ const char* activeDOMObjectName() const final;
+ bool canSuspendForDocumentSuspension() const final;
// EventTarget
- virtual void refEventTarget() override final { ref(); }
- virtual void derefEventTarget() override final { deref(); }
+ void refEventTarget() final { ref(); }
+ void derefEventTarget() final { deref(); }
+ EventTargetInterface eventTargetInterface() const final { return MediaStreamTrackEventTargetInterfaceType; }
+ ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
- // MediaStreamTrackPrivateClient
- void trackReadyStateChanged();
- void trackMutedChanged();
- void trackEnabledChanged();
+ // MediaStreamTrackPrivate::Observer
+ void trackEnded(MediaStreamTrackPrivate&) override;
+ void trackMutedChanged(MediaStreamTrackPrivate&) override;
+ void trackSettingsChanged(MediaStreamTrackPrivate&) override;
+ void trackEnabledChanged(MediaStreamTrackPrivate&) override;
- Vector<RefPtr<Event>> m_scheduledEvents;
-
- RefPtr<MediaConstraintsImpl> m_constraints;
- Mutex m_mutex;
+ WeakPtr<MediaStreamTrack> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
Vector<Observer*> m_observers;
+ Ref<MediaStreamTrackPrivate> m_private;
- Ref<MediaStreamTrackPrivate> m_privateTrack;
- bool m_eventDispatchScheduled;
+ MediaTrackConstraints m_constraints;
+ std::optional<DOMPromise<void>> m_promise;
+ WeakPtrFactory<MediaStreamTrack> m_weakPtrFactory;
- bool m_stoppingTrack;
+ bool m_ended { false };
};
+typedef Vector<RefPtr<MediaStreamTrack>> MediaStreamTrackVector;
+
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStreamTrack_h
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl b/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl
index 68d5fb91c..ac033019a 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl
+++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,45 +26,69 @@
enum MediaStreamTrackState { "new", "live", "ended" };
[
- Conditional=MEDIA_STREAM,
- EventTarget,
ActiveDOMObject,
+ Conditional=MEDIA_STREAM,
+ PrivateIdentifier,
+ PublicIdentifier,
SkipVTableValidation,
-] interface MediaStreamTrack {
+] interface MediaStreamTrack : EventTarget {
readonly attribute DOMString kind;
readonly attribute DOMString id;
readonly attribute DOMString label;
- attribute boolean enabled;
+ attribute boolean enabled;
readonly attribute boolean muted;
- attribute EventListener onmute;
- attribute EventListener onunmute;
+ attribute EventHandler onmute;
+ attribute EventHandler onunmute;
readonly attribute boolean _readonly;
readonly attribute boolean remote;
readonly attribute MediaStreamTrackState readyState;
- attribute EventListener onstarted;
- attribute EventListener onended;
-
- [CallWith=ScriptExecutionContext, RaisesException] static void getSources(MediaStreamTrackSourcesCallback callback);
-
- MediaTrackConstraints constraints();
+ attribute EventHandler onended;
- MediaSourceStates states();
-
- MediaStreamCapabilities capabilities(); // returns either AllVideoCapabilities or AllAudioCapabilities
-
- void applyConstraints(Dictionary constraints);
-
- attribute EventListener onoverconstrained;
MediaStreamTrack clone();
[ImplementedAs=stopProducingData] void stop();
- // EventTarget interface
- void addEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- void removeEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event event);
+ MediaTrackConstraints getConstraints();
+ MediaTrackSettings getSettings();
+ MediaTrackCapabilities getCapabilities();
+ Promise<void> applyConstraints(optional MediaTrackConstraints constraints);
+
+ attribute EventHandler onoverconstrained;
};
+[
+ Conditional=MEDIA_STREAM,
+ JSGenerateToJSObject,
+] dictionary MediaTrackCapabilities {
+ LongRange width;
+ LongRange height;
+ DoubleRange aspectRatio;
+ DoubleRange frameRate;
+ sequence<DOMString> facingMode;
+ DoubleRange volume;
+ LongRange sampleRate;
+ LongRange sampleSize;
+ sequence<boolean> echoCancellation;
+ // FIXME: add latency
+ // FIXME: add channelCount
+ DOMString deviceId;
+ DOMString groupId;
+};
+
+[
+ Conditional=MEDIA_STREAM,
+ JSGenerateToJSObject,
+] dictionary MediaTrackSettings {
+ long width;
+ long height;
+ double aspectRatio;
+ double frameRate;
+ DOMString facingMode;
+ double volume;
+ long sampleRate;
+ long sampleSize;
+ boolean echoCancellation;
+ // FIXME: add latency
+ // FIXME: add channelCount
+ DOMString deviceId;
+ DOMString groupId;
+};
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.cpp
index 6d884fc5a..de46e0bc2 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.cpp
+++ b/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.cpp
@@ -27,43 +27,28 @@
#include "MediaStreamTrackEvent.h"
-#include "EventNames.h"
#include "MediaStreamTrack.h"
namespace WebCore {
-MediaStreamTrackEventInit::MediaStreamTrackEventInit()
- : track(0)
+Ref<MediaStreamTrackEvent> MediaStreamTrackEvent::create(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<MediaStreamTrack>&& track)
{
+ return adoptRef(*new MediaStreamTrackEvent(type, canBubble, cancelable, WTFMove(track)));
}
-PassRefPtr<MediaStreamTrackEvent> MediaStreamTrackEvent::create()
+Ref<MediaStreamTrackEvent> MediaStreamTrackEvent::create(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
{
- return adoptRef(new MediaStreamTrackEvent);
+ return adoptRef(*new MediaStreamTrackEvent(type, initializer, isTrusted));
}
-PassRefPtr<MediaStreamTrackEvent> MediaStreamTrackEvent::create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<MediaStreamTrack> track)
-{
- return adoptRef(new MediaStreamTrackEvent(type, canBubble, cancelable, track));
-}
-
-PassRefPtr<MediaStreamTrackEvent> MediaStreamTrackEvent::create(const AtomicString& type, const MediaStreamTrackEventInit& initializer)
-{
- return adoptRef(new MediaStreamTrackEvent(type, initializer));
-}
-
-MediaStreamTrackEvent::MediaStreamTrackEvent()
-{
-}
-
-MediaStreamTrackEvent::MediaStreamTrackEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<MediaStreamTrack> track)
+MediaStreamTrackEvent::MediaStreamTrackEvent(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<MediaStreamTrack>&& track)
: Event(type, canBubble, cancelable)
- , m_track(track)
+ , m_track(WTFMove(track))
{
}
-MediaStreamTrackEvent::MediaStreamTrackEvent(const AtomicString& type, const MediaStreamTrackEventInit& initializer)
- : Event(type, initializer)
+MediaStreamTrackEvent::MediaStreamTrackEvent(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
+ : Event(type, initializer, isTrusted)
, m_track(initializer.track)
{
}
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.h b/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.h
index b0818abb4..4101f49f8 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.h
+++ b/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.h
@@ -22,8 +22,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaStreamTrackEvent_h
-#define MediaStreamTrackEvent_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
@@ -34,29 +33,25 @@ namespace WebCore {
class MediaStreamTrack;
-struct MediaStreamTrackEventInit : public EventInit {
- MediaStreamTrackEventInit();
-
- RefPtr<MediaStreamTrack> track;
-};
-
class MediaStreamTrackEvent : public Event {
public:
virtual ~MediaStreamTrackEvent();
- static PassRefPtr<MediaStreamTrackEvent> create();
- static PassRefPtr<MediaStreamTrackEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<MediaStreamTrack>);
- static PassRefPtr<MediaStreamTrackEvent> create(const AtomicString& type, const MediaStreamTrackEventInit& initializer);
+ static Ref<MediaStreamTrackEvent> create(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<MediaStreamTrack>&&);
+
+ struct Init : EventInit {
+ RefPtr<MediaStreamTrack> track;
+ };
+ static Ref<MediaStreamTrackEvent> create(const AtomicString& type, const Init&, IsTrusted = IsTrusted::No);
MediaStreamTrack* track() const;
// Event
- virtual EventInterface eventInterface() const override;
+ EventInterface eventInterface() const override;
private:
- MediaStreamTrackEvent();
- MediaStreamTrackEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<MediaStreamTrack>);
- MediaStreamTrackEvent(const AtomicString& type, const MediaStreamTrackEventInit&);
+ MediaStreamTrackEvent(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<MediaStreamTrack>&&);
+ MediaStreamTrackEvent(const AtomicString& type, const Init&, IsTrusted);
RefPtr<MediaStreamTrack> m_track;
};
@@ -64,5 +59,3 @@ private:
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStreamTrackEvent_h
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.idl b/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.idl
index 10d5f333f..26d9cca68 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.idl
+++ b/Source/WebCore/Modules/mediastream/MediaStreamTrackEvent.idl
@@ -24,8 +24,11 @@
[
Conditional=MEDIA_STREAM,
- ConstructorTemplate=Event
+ Constructor(DOMString type, MediaStreamTrackEventInit eventInitDict),
] interface MediaStreamTrackEvent : Event {
- [InitializedByEventConstructor] readonly attribute MediaStreamTrack track;
+ readonly attribute MediaStreamTrack track;
};
+dictionary MediaStreamTrackEventInit : EventInit {
+ required MediaStreamTrack track;
+};
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesCallback.idl b/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesCallback.idl
deleted file mode 100644
index 4c0593fcf..000000000
--- a/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesCallback.idl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Conditional=MEDIA_STREAM,
- NoInterfaceObject,
-] callback interface MediaStreamTrackSourcesCallback {
- boolean handleEvent(sequence<SourceInfo> sources);
-};
-
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.cpp
deleted file mode 100644
index 18b929a9e..000000000
--- a/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "MediaStreamTrackSourcesRequest.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamTrackSourcesCallback.h"
-#include "ScriptExecutionContext.h"
-#include "SecurityOrigin.h"
-#include "SourceInfo.h"
-#include <wtf/Functional.h>
-#include <wtf/MainThread.h>
-
-namespace WebCore {
-
-PassRefPtr<MediaStreamTrackSourcesRequest> MediaStreamTrackSourcesRequest::create(ScriptExecutionContext* context, PassRefPtr<MediaStreamTrackSourcesCallback> callback)
-{
- return adoptRef(new MediaStreamTrackSourcesRequest(context, callback));
-}
-
-MediaStreamTrackSourcesRequest::MediaStreamTrackSourcesRequest(ScriptExecutionContext* context, PassRefPtr<MediaStreamTrackSourcesCallback> callback)
- : m_callback(callback)
-{
- m_origin = context->securityOrigin()->toString();
-}
-
-void MediaStreamTrackSourcesRequest::didCompleteRequest(const Vector<RefPtr<TrackSourceInfo>>& requestSourceInfos)
-{
- ASSERT(m_callback);
-
- for (size_t i = 0; i < requestSourceInfos.size(); ++i)
- m_sourceInfos.append(SourceInfo::create(requestSourceInfos[i]));
-
- callOnMainThread(bind(&MediaStreamTrackSourcesRequest::callCompletionHandler, this));
-}
-
-void MediaStreamTrackSourcesRequest::callCompletionHandler()
-{
- ASSERT(m_callback);
-
- m_callback->handleEvent(m_sourceInfos);
- m_callback = nullptr;
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.h b/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.h
deleted file mode 100644
index 96599b436..000000000
--- a/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesRequest.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaStreamTrackSourcesRequest_h
-#define MediaStreamTrackSourcesRequest_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamTrackSourcesRequestClient.h"
-#include "SourceInfo.h"
-#include "Timer.h"
-#include <wtf/RefPtr.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class MediaStreamTrackSourcesCallback;
-class ScriptExecutionContext;
-
-class MediaStreamTrackSourcesRequest : public MediaStreamTrackSourcesRequestClient {
-public:
- static PassRefPtr<MediaStreamTrackSourcesRequest> create(ScriptExecutionContext*, PassRefPtr<MediaStreamTrackSourcesCallback>);
- virtual ~MediaStreamTrackSourcesRequest() { }
-
-private:
- MediaStreamTrackSourcesRequest(ScriptExecutionContext*, PassRefPtr<MediaStreamTrackSourcesCallback>);
-
- // MediaStreamTrackSourcesRequestClient
- virtual const String& requestOrigin() const override { return m_origin; }
- virtual void didCompleteRequest(const Vector<RefPtr<TrackSourceInfo>>&) override;
-
- void callCompletionHandler();
-
- String m_origin;
- RefPtr<MediaStreamTrackSourcesCallback> m_callback;
- Vector<RefPtr<SourceInfo>> m_sourceInfos;
-};
-
-} // namespace WebCore
-
-#endif // MediaStreamTrackSourcesRequest_h
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.cpp b/Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.cpp
deleted file mode 100644
index a5aec90a5..000000000
--- a/Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaTrackConstraintSet.h"
-
-using namespace JSC;
-
-namespace WebCore {
-
-RefPtr<MediaTrackConstraintSet> MediaTrackConstraintSet::create(const Dictionary& constraints)
-{
- return adoptRef(new MediaTrackConstraintSet(constraints));
-}
-
-MediaTrackConstraintSet::MediaTrackConstraintSet(const Dictionary& constraints)
- : m_constraints(constraints)
-{
-}
-
-MediaTrackConstraintSet::~MediaTrackConstraintSet()
-{
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.h b/Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.h
deleted file mode 100644
index b6978ae30..000000000
--- a/Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef MediaTrackConstraintSet_h
-#define MediaTrackConstraintSet_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "Dictionary.h"
-#include "ScriptWrappable.h"
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class MediaTrackConstraintSet : public RefCounted<MediaTrackConstraintSet>, public ScriptWrappable {
-public:
- static RefPtr<MediaTrackConstraintSet> create(const Dictionary&);
-
- virtual ~MediaTrackConstraintSet();
-
- const Dictionary& constraints() const { return m_constraints; }
-
-private:
- explicit MediaTrackConstraintSet(const Dictionary&);
-
- const Dictionary& m_constraints;
-};
-
-} // namespace WebCore
-
-#endif // MediaTrackConstraintSet_h
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.idl b/Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.idl
deleted file mode 100644
index 82754c8c6..000000000
--- a/Source/WebCore/Modules/mediastream/MediaTrackConstraintSet.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Conditional=MEDIA_STREAM,
- NoInterfaceObject,
-] interface MediaTrackConstraintSet {
- // FIXME: Not implemented.
- // https://bugs.webkit.org/show_bug.cgi?id=121954
-};
-
diff --git a/Source/WebCore/Modules/mediastream/MediaTrackConstraints.cpp b/Source/WebCore/Modules/mediastream/MediaTrackConstraints.cpp
index 77b105448..c4c4cf122 100644
--- a/Source/WebCore/Modules/mediastream/MediaTrackConstraints.cpp
+++ b/Source/WebCore/Modules/mediastream/MediaTrackConstraints.cpp
@@ -1,67 +1,200 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
+#include "MediaTrackConstraints.h"
#if ENABLE(MEDIA_STREAM)
-#include "MediaTrackConstraints.h"
+#include "MediaConstraintsImpl.h"
-#include "MediaTrackConstraint.h"
-#include "MediaTrackConstraintSet.h"
-#include "NotImplemented.h"
+namespace WebCore {
-using namespace JSC;
+enum class ConstraintSetType { Mandatory, Advanced };
-namespace WebCore {
+static void set(MediaTrackConstraintSetMap& map, ConstraintSetType setType, const char* typeAsString, MediaConstraintType type, const ConstrainLong& value)
+{
+ IntConstraint constraint(typeAsString, type);
+ WTF::switchOn(value,
+ [&] (int integer) {
+ if (setType == ConstraintSetType::Mandatory)
+ constraint.setIdeal(integer);
+ else
+ constraint.setExact(integer);
+ },
+ [&] (const ConstrainLongRange& range) {
+ if (range.min)
+ constraint.setMin(range.min.value());
+ if (range.max)
+ constraint.setMax(range.max.value());
+ if (range.exact)
+ constraint.setExact(range.exact.value());
+ if (range.ideal)
+ constraint.setIdeal(range.ideal.value());
+ }
+ );
+ map.set(type, WTFMove(constraint));
+}
+
+static void set(MediaTrackConstraintSetMap& map, ConstraintSetType setType, const char* typeAsString, MediaConstraintType type, const ConstrainDouble& value)
+{
+ DoubleConstraint constraint(typeAsString, type);
+ WTF::switchOn(value,
+ [&] (double number) {
+ if (setType == ConstraintSetType::Mandatory)
+ constraint.setIdeal(number);
+ else
+ constraint.setExact(number);
+ },
+ [&] (const ConstrainDoubleRange& range) {
+ if (range.min)
+ constraint.setMin(range.min.value());
+ if (range.max)
+ constraint.setMax(range.max.value());
+ if (range.exact)
+ constraint.setExact(range.exact.value());
+ if (range.ideal)
+ constraint.setIdeal(range.ideal.value());
+ }
+ );
+ map.set(type, WTFMove(constraint));
+}
-RefPtr<MediaTrackConstraints> MediaTrackConstraints::create(PassRefPtr<MediaConstraintsImpl> constraints)
+static void set(MediaTrackConstraintSetMap& map, ConstraintSetType setType, const char* typeAsString, MediaConstraintType type, const ConstrainBoolean& value)
{
- return adoptRef(new MediaTrackConstraints(constraints));
+ BooleanConstraint constraint(typeAsString, type);
+ WTF::switchOn(value,
+ [&] (bool boolean) {
+ if (setType == ConstraintSetType::Mandatory)
+ constraint.setIdeal(boolean);
+ else
+ constraint.setExact(boolean);
+ },
+ [&] (const ConstrainBooleanParameters& parameters) {
+ if (parameters.exact)
+ constraint.setExact(parameters.exact.value());
+ if (parameters.ideal)
+ constraint.setIdeal(parameters.ideal.value());
+ }
+ );
+ map.set(type, WTFMove(constraint));
}
-MediaTrackConstraints::MediaTrackConstraints(PassRefPtr<MediaConstraintsImpl> constraints)
- : m_constraints(constraints)
+static void set(MediaTrackConstraintSetMap& map, ConstraintSetType setType, const char* typeAsString, MediaConstraintType type, const ConstrainDOMString& value)
{
+ StringConstraint constraint(typeAsString, type);
+ WTF::switchOn(value,
+ [&] (const String& string) {
+ if (setType == ConstraintSetType::Mandatory)
+ constraint.appendIdeal(string);
+ else
+ constraint.appendExact(string);
+ },
+ [&] (const Vector<String>& vector) {
+ if (setType == ConstraintSetType::Mandatory) {
+ for (auto& string : vector)
+ constraint.appendIdeal(string);
+ } else {
+ for (auto& string : vector)
+ constraint.appendExact(string);
+ }
+ },
+ [&] (const ConstrainDOMStringParameters& parameters) {
+ if (parameters.exact) {
+ WTF::switchOn(parameters.exact.value(),
+ [&] (const String& string) {
+ constraint.appendExact(string);
+ },
+ [&] (const Vector<String>& vector) {
+ for (auto& string : vector)
+ constraint.appendExact(string);
+ }
+ );
+ }
+ if (parameters.ideal) {
+ WTF::switchOn(parameters.ideal.value(),
+ [&] (const String& string) {
+ constraint.appendIdeal(string);
+ },
+ [&] (const Vector<String>& vector) {
+ for (auto& string : vector)
+ constraint.appendIdeal(string);
+ }
+ );
+ }
+ }
+ );
+ map.set(type, WTFMove(constraint));
}
-Vector<PassRefPtr<MediaTrackConstraint>> MediaTrackConstraints::optional(bool) const
+template<typename T> static inline void set(MediaTrackConstraintSetMap& map, ConstraintSetType setType, const char* typeAsString, MediaConstraintType type, const std::optional<T>& value)
{
- // https://bugs.webkit.org/show_bug.cgi?id=121954
- notImplemented();
- return Vector<PassRefPtr<MediaTrackConstraint>>();
+ if (!value)
+ return;
+ set(map, setType, typeAsString, type, value.value());
}
-RefPtr<MediaTrackConstraintSet> MediaTrackConstraints::mandatory(bool) const
+static MediaTrackConstraintSetMap convertToInternalForm(ConstraintSetType setType, const MediaTrackConstraintSet& constraintSet)
{
- // https://bugs.webkit.org/show_bug.cgi?id=121954
- notImplemented();
- return nullptr;
+ MediaTrackConstraintSetMap result;
+ set(result, setType, "width", MediaConstraintType::Width, constraintSet.width);
+ set(result, setType, "height", MediaConstraintType::Height, constraintSet.height);
+ set(result, setType, "aspectRatio", MediaConstraintType::AspectRatio, constraintSet.aspectRatio);
+ set(result, setType, "frameRate", MediaConstraintType::FrameRate, constraintSet.frameRate);
+ set(result, setType, "facingMode", MediaConstraintType::FacingMode, constraintSet.facingMode);
+ set(result, setType, "volume", MediaConstraintType::Volume, constraintSet.volume);
+ set(result, setType, "sampleRate", MediaConstraintType::SampleRate, constraintSet.sampleRate);
+ set(result, setType, "sampleSize", MediaConstraintType::SampleSize, constraintSet.sampleSize);
+ set(result, setType, "echoCancellation", MediaConstraintType::EchoCancellation, constraintSet.echoCancellation);
+ // FIXME: add latency
+ // FIXME: add channelCount
+ set(result, setType, "deviceId", MediaConstraintType::DeviceId, constraintSet.deviceId);
+ set(result, setType, "groupId", MediaConstraintType::GroupId, constraintSet.groupId);
+ return result;
}
-} // namespace WebCore
+static Vector<MediaTrackConstraintSetMap> convertAdvancedToInternalForm(const Vector<MediaTrackConstraintSet>& vector)
+{
+ Vector<MediaTrackConstraintSetMap> result;
+ result.reserveInitialCapacity(vector.size());
+ for (auto& set : vector)
+ result.uncheckedAppend(convertToInternalForm(ConstraintSetType::Advanced, set));
+ return result;
+}
+
+static Vector<MediaTrackConstraintSetMap> convertAdvancedToInternalForm(const std::optional<Vector<MediaTrackConstraintSet>>& optionalVector)
+{
+ if (!optionalVector)
+ return { };
+ return convertAdvancedToInternalForm(optionalVector.value());
+}
+
+Ref<MediaConstraintsImpl> createMediaConstraintsImpl(const MediaTrackConstraints& constraints)
+{
+ return MediaConstraintsImpl::create(convertToInternalForm(ConstraintSetType::Mandatory, constraints), convertAdvancedToInternalForm(constraints.advanced), true);
+}
+
+}
#endif
diff --git a/Source/WebCore/Modules/mediastream/MediaTrackConstraints.h b/Source/WebCore/Modules/mediastream/MediaTrackConstraints.h
index 95a8ccaff..3bccdaea0 100644
--- a/Source/WebCore/Modules/mediastream/MediaTrackConstraints.h
+++ b/Source/WebCore/Modules/mediastream/MediaTrackConstraints.h
@@ -1,60 +1,86 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaTrackConstraints_h
-#define MediaTrackConstraints_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
-#include "MediaConstraintsImpl.h"
-#include "ScriptWrappable.h"
-#include <wtf/RefCounted.h>
+#include "DoubleRange.h"
+#include "LongRange.h"
+#include <wtf/Variant.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
-class MediaTrackConstraint;
-class MediaTrackConstraintSet;
+class MediaConstraintsImpl;
-class MediaTrackConstraints : public RefCounted<MediaTrackConstraints>, public ScriptWrappable {
-public:
- virtual ~MediaTrackConstraints() { }
+struct ConstrainBooleanParameters {
+ std::optional<bool> exact;
+ std::optional<bool> ideal;
+};
- static RefPtr<MediaTrackConstraints> create(PassRefPtr<MediaConstraintsImpl>);
+struct ConstrainDOMStringParameters {
+ std::optional<Variant<String, Vector<String>>> exact;
+ std::optional<Variant<String, Vector<String>>> ideal;
+};
+
+struct ConstrainDoubleRange : DoubleRange {
+ std::optional<double> exact;
+ std::optional<double> ideal;
+};
- Vector<PassRefPtr<MediaTrackConstraint>> optional(bool) const;
- RefPtr<MediaTrackConstraintSet> mandatory(bool) const;
+struct ConstrainLongRange : LongRange {
+ std::optional<int> exact;
+ std::optional<int> ideal;
+};
+
+using ConstrainBoolean = Variant<bool, ConstrainBooleanParameters>;
+using ConstrainDOMString = Variant<String, Vector<String>, ConstrainDOMStringParameters>;
+using ConstrainDouble = Variant<double, ConstrainDoubleRange>;
+using ConstrainLong = Variant<int, ConstrainLongRange>;
+
+struct MediaTrackConstraintSet {
+ std::optional<ConstrainLong> width;
+ std::optional<ConstrainLong> height;
+ std::optional<ConstrainDouble> aspectRatio;
+ std::optional<ConstrainDouble> frameRate;
+ std::optional<ConstrainDOMString> facingMode;
+ std::optional<ConstrainDouble> volume;
+ std::optional<ConstrainLong> sampleRate;
+ std::optional<ConstrainLong> sampleSize;
+ std::optional<ConstrainBoolean> echoCancellation;
+ std::optional<ConstrainDOMString> deviceId;
+ std::optional<ConstrainDOMString> groupId;
+};
-private:
- explicit MediaTrackConstraints(PassRefPtr<MediaConstraintsImpl>);
-
- RefPtr<MediaConstraintsImpl> m_constraints;
+struct MediaTrackConstraints : MediaTrackConstraintSet {
+ std::optional<Vector<MediaTrackConstraintSet>> advanced;
};
-} // namespace WebCore
+Ref<MediaConstraintsImpl> createMediaConstraintsImpl(const MediaTrackConstraints&);
-#endif // MediaTrackConstraints_h
+}
#endif
diff --git a/Source/WebCore/Modules/mediastream/MediaTrackConstraints.idl b/Source/WebCore/Modules/mediastream/MediaTrackConstraints.idl
index aab80d0aa..59b96bd37 100644
--- a/Source/WebCore/Modules/mediastream/MediaTrackConstraints.idl
+++ b/Source/WebCore/Modules/mediastream/MediaTrackConstraints.idl
@@ -1,33 +1,91 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
[
Conditional=MEDIA_STREAM,
- NoInterfaceObject,
-] interface MediaTrackConstraints {
- readonly attribute MediaTrackConstraintSet? mandatory;
- readonly attribute MediaTrackConstraint[]? optional;
+ JSGenerateToJSObject,
+] dictionary MediaTrackConstraints : MediaTrackConstraintSet {
+ sequence<MediaTrackConstraintSet> advanced;
};
+[
+ Conditional=MEDIA_STREAM,
+ JSGenerateToJSObject,
+ ImplementedAs=MediaTrackConstraintSet
+] dictionary MediaTrackConstraintSet {
+ ConstrainLong width;
+ ConstrainLong height;
+ ConstrainDouble aspectRatio;
+ ConstrainDouble frameRate;
+ ConstrainDOMString facingMode;
+ ConstrainDouble volume;
+ ConstrainLong sampleRate;
+ ConstrainLong sampleSize;
+ ConstrainBoolean echoCancellation;
+ // FIXME: add latency
+ // FIXME: add channelCount
+ ConstrainDOMString deviceId;
+ ConstrainDOMString groupId;
+};
+
+typedef (double or ConstrainDoubleRange) ConstrainDouble;
+typedef (long or ConstrainLongRange) ConstrainLong;
+typedef (boolean or ConstrainBooleanParameters) ConstrainBoolean;
+typedef (DOMString or sequence<DOMString> or ConstrainDOMStringParameters) ConstrainDOMString;
+
+[
+ Conditional=MEDIA_STREAM,
+ JSGenerateToJSObject,
+ ImplementedAs=ConstrainBooleanParameters
+] dictionary ConstrainBooleanParameters {
+ boolean exact;
+ boolean ideal;
+};
+
+[
+ Conditional=MEDIA_STREAM,
+ JSGenerateToJSObject,
+ ImplementedAs=ConstrainDOMStringParameters
+] dictionary ConstrainDOMStringParameters {
+ (DOMString or sequence<DOMString>) exact;
+ (DOMString or sequence<DOMString>) ideal;
+};
+
+[
+ Conditional=MEDIA_STREAM,
+ JSGenerateToJSObject,
+ ImplementedAs=ConstrainDoubleRange
+] dictionary ConstrainDoubleRange : DoubleRange {
+ double exact;
+ double ideal;
+};
+
+[
+ Conditional=MEDIA_STREAM,
+ JSGenerateToJSObject,
+ ImplementedAs=ConstrainLongRange
+] dictionary ConstrainLongRange : LongRange {
+ long exact;
+ long ideal;
+};
diff --git a/Source/WebCore/Modules/mediastream/MediaTrackSupportedConstraints.h b/Source/WebCore/Modules/mediastream/MediaTrackSupportedConstraints.h
new file mode 100644
index 000000000..f8626b899
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaTrackSupportedConstraints.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+namespace WebCore {
+
+struct MediaTrackSupportedConstraints {
+ bool width;
+ bool height;
+ bool aspectRatio;
+ bool frameRate;
+ bool facingMode;
+ bool volume;
+ bool sampleRate;
+ bool sampleSize;
+ bool echoCancellation;
+ bool deviceId;
+ bool groupId;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/MediaTrackSupportedConstraints.idl b/Source/WebCore/Modules/mediastream/MediaTrackSupportedConstraints.idl
new file mode 100644
index 000000000..586ec6990
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/MediaTrackSupportedConstraints.idl
@@ -0,0 +1,46 @@
+/*
+* Copyright (C) 2015 Apple Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* 3. Neither the name of Ericsson nor the names of its contributors
+* may be used to endorse or promote products derived from this
+* software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+[
+ Conditional=MEDIA_STREAM,
+ JSGenerateToJSObject,
+] dictionary MediaTrackSupportedConstraints {
+ boolean width = true;
+ boolean height = true;
+ boolean aspectRatio = true;
+ boolean frameRate = true;
+ boolean facingMode = true;
+ boolean volume = true;
+ boolean sampleRate = true;
+ boolean sampleSize = true;
+ boolean echoCancellation = true;
+ boolean deviceId = true;
+ boolean groupId = true;
+};
diff --git a/Source/WebCore/Modules/mediastream/RTCVoidRequestImpl.cpp b/Source/WebCore/Modules/mediastream/NavigatorMediaDevices.cpp
index 116115818..8a0f16ba6 100644
--- a/Source/WebCore/Modules/mediastream/RTCVoidRequestImpl.cpp
+++ b/Source/WebCore/Modules/mediastream/NavigatorMediaDevices.cpp
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -12,7 +11,7 @@
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
+ * 3. Neither the name of Ericsson nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@@ -30,61 +29,52 @@
*/
#include "config.h"
+#include "NavigatorMediaDevices.h"
#if ENABLE(MEDIA_STREAM)
-#include "RTCVoidRequestImpl.h"
-
-#include "DOMError.h"
-#include "RTCPeerConnection.h"
-#include "RTCPeerConnectionErrorCallback.h"
-#include "VoidCallback.h"
+#include "Document.h"
+#include "Frame.h"
+#include "MediaDevices.h"
+#include "Navigator.h"
namespace WebCore {
-PassRefPtr<RTCVoidRequestImpl> RTCVoidRequestImpl::create(ScriptExecutionContext* context, PassRefPtr<VoidCallback> successCallback, PassRefPtr<RTCPeerConnectionErrorCallback> errorCallback)
-{
- RefPtr<RTCVoidRequestImpl> request = adoptRef(new RTCVoidRequestImpl(context, successCallback, errorCallback));
- request->suspendIfNeeded();
- return request.release();
-}
-
-RTCVoidRequestImpl::RTCVoidRequestImpl(ScriptExecutionContext* context, PassRefPtr<VoidCallback> successCallback, PassRefPtr<RTCPeerConnectionErrorCallback> errorCallback)
- : ActiveDOMObject(context)
- , m_successCallback(successCallback)
- , m_errorCallback(errorCallback)
+NavigatorMediaDevices::NavigatorMediaDevices(Frame* frame)
+ : DOMWindowProperty(frame)
{
}
-RTCVoidRequestImpl::~RTCVoidRequestImpl()
+NavigatorMediaDevices::~NavigatorMediaDevices()
{
}
-void RTCVoidRequestImpl::requestSucceeded()
+NavigatorMediaDevices* NavigatorMediaDevices::from(Navigator* navigator)
{
- if (m_successCallback)
- m_successCallback->handleEvent();
-
- clear();
+ NavigatorMediaDevices* supplement = static_cast<NavigatorMediaDevices*>(Supplement<Navigator>::from(navigator, supplementName()));
+ if (!supplement) {
+ auto newSupplement = std::make_unique<NavigatorMediaDevices>(navigator->frame());
+ supplement = newSupplement.get();
+ provideTo(navigator, supplementName(), WTFMove(newSupplement));
+ }
+ return supplement;
}
-void RTCVoidRequestImpl::requestFailed(const String& error)
+MediaDevices* NavigatorMediaDevices::mediaDevices(Navigator& navigator)
{
- if (m_errorCallback.get())
- m_errorCallback->handleEvent(DOMError::create(error).get());
-
- clear();
+ return NavigatorMediaDevices::from(&navigator)->mediaDevices();
}
-void RTCVoidRequestImpl::stop()
+MediaDevices* NavigatorMediaDevices::mediaDevices() const
{
- clear();
+ if (!m_mediaDevices && frame())
+ m_mediaDevices = MediaDevices::create(*frame()->document());
+ return m_mediaDevices.get();
}
-void RTCVoidRequestImpl::clear()
+const char* NavigatorMediaDevices::supplementName()
{
- m_successCallback.clear();
- m_errorCallback.clear();
+ return "NavigatorMediaDevices";
}
} // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/RTCVoidRequestImpl.h b/Source/WebCore/Modules/mediastream/NavigatorMediaDevices.h
index 3c3f34d48..677ddbbdf 100644
--- a/Source/WebCore/Modules/mediastream/RTCVoidRequestImpl.h
+++ b/Source/WebCore/Modules/mediastream/NavigatorMediaDevices.h
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -12,7 +11,7 @@
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
+ * 3. Neither the name of Ericsson nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@@ -29,43 +28,34 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCVoidRequestImpl_h
-#define RTCVoidRequestImpl_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
-#include "ActiveDOMObject.h"
-#include "RTCVoidRequest.h"
+#include "DOMWindowProperty.h"
+#include "Supplementable.h"
namespace WebCore {
-class RTCPeerConnectionErrorCallback;
-class VoidCallback;
+class Frame;
+class MediaDevices;
+class Navigator;
-class RTCVoidRequestImpl : public RTCVoidRequest, public ActiveDOMObject {
+class NavigatorMediaDevices : public Supplement<Navigator>, public DOMWindowProperty {
public:
- static PassRefPtr<RTCVoidRequestImpl> create(ScriptExecutionContext*, PassRefPtr<VoidCallback>, PassRefPtr<RTCPeerConnectionErrorCallback>);
- virtual ~RTCVoidRequestImpl();
+ explicit NavigatorMediaDevices(Frame*);
+ virtual ~NavigatorMediaDevices();
+ static NavigatorMediaDevices* from(Navigator*);
- virtual void requestSucceeded();
- virtual void requestFailed(const String& error);
-
- // ActiveDOMObject
- virtual void stop() override;
+ static MediaDevices* mediaDevices(Navigator&);
+ MediaDevices* mediaDevices() const;
private:
- RTCVoidRequestImpl(ScriptExecutionContext*, PassRefPtr<VoidCallback>, PassRefPtr<RTCPeerConnectionErrorCallback>);
-
- void clear();
+ static const char* supplementName();
- RefPtr<VoidCallback> m_successCallback;
- RefPtr<RTCPeerConnectionErrorCallback> m_errorCallback;
+ mutable RefPtr<MediaDevices> m_mediaDevices;
};
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCVoidRequestImpl_h
-
-
diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescriptionCallback.idl b/Source/WebCore/Modules/mediastream/NavigatorMediaDevices.idl
index 30ce08568..9c8e7849c 100644
--- a/Source/WebCore/Modules/mediastream/RTCSessionDescriptionCallback.idl
+++ b/Source/WebCore/Modules/mediastream/NavigatorMediaDevices.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,7 +11,7 @@
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
+ * 3. Neither the name of Ericsson nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@@ -30,7 +30,7 @@
[
Conditional=MEDIA_STREAM,
-] callback interface RTCSessionDescriptionCallback {
- boolean handleEvent(RTCSessionDescription sdp);
+ EnabledAtRuntime=MediaStream,
+] partial interface Navigator {
+ readonly attribute MediaDevices mediaDevices;
};
-
diff --git a/Source/WebCore/Modules/mediastream/NavigatorMediaStream.cpp b/Source/WebCore/Modules/mediastream/NavigatorMediaStream.cpp
deleted file mode 100644
index c14bc10e1..000000000
--- a/Source/WebCore/Modules/mediastream/NavigatorMediaStream.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2000 Harri Porten (porten@kde.org)
- * Copyright (c) 2000 Daniel Molkentin (molkentin@kde.org)
- * Copyright (c) 2000 Stefan Schimanski (schimmi@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#include "NavigatorMediaStream.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "Dictionary.h"
-#include "Document.h"
-#include "ExceptionCode.h"
-#include "Frame.h"
-#include "Navigator.h"
-#include "NavigatorUserMediaErrorCallback.h"
-#include "NavigatorUserMediaSuccessCallback.h"
-#include "Page.h"
-#include "UserMediaController.h"
-#include "UserMediaRequest.h"
-
-namespace WebCore {
-
-NavigatorMediaStream::NavigatorMediaStream()
-{
-}
-
-NavigatorMediaStream::~NavigatorMediaStream()
-{
-}
-
-void NavigatorMediaStream::webkitGetUserMedia(Navigator* navigator, const Dictionary& options, PassRefPtr<NavigatorUserMediaSuccessCallback> successCallback, PassRefPtr<NavigatorUserMediaErrorCallback> errorCallback, ExceptionCode& ec)
-{
- if (!successCallback)
- return;
-
- UserMediaController* userMedia = UserMediaController::from(navigator->frame() ? navigator->frame()->page() : 0);
- if (!userMedia) {
- ec = NOT_SUPPORTED_ERR;
- return;
- }
-
- RefPtr<UserMediaRequest> request = UserMediaRequest::create(navigator->frame()->document(), userMedia, options, successCallback, errorCallback, ec);
- if (!request) {
- ec = NOT_SUPPORTED_ERR;
- return;
- }
-
- request->start();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/NavigatorMediaStream.h b/Source/WebCore/Modules/mediastream/NavigatorMediaStream.h
deleted file mode 100644
index 1bdf4de32..000000000
--- a/Source/WebCore/Modules/mediastream/NavigatorMediaStream.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-#ifndef NavigatorMediaStream_h
-#define NavigatorMediaStream_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include <wtf/PassRefPtr.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class Dictionary;
-class Navigator;
-class NavigatorUserMediaErrorCallback;
-class NavigatorUserMediaSuccessCallback;
-
-typedef int ExceptionCode;
-
-class NavigatorMediaStream {
-public:
- static void webkitGetUserMedia(Navigator*, const Dictionary&, PassRefPtr<NavigatorUserMediaSuccessCallback>, PassRefPtr<NavigatorUserMediaErrorCallback>, ExceptionCode&);
-
-private:
- NavigatorMediaStream();
- ~NavigatorMediaStream();
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // NavigatorMediaStream_h
diff --git a/Source/WebCore/Modules/mediastream/NavigatorMediaStream.idl b/Source/WebCore/Modules/mediastream/NavigatorMediaStream.idl
deleted file mode 100644
index 0cf230796..000000000
--- a/Source/WebCore/Modules/mediastream/NavigatorMediaStream.idl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-[
- Conditional=MEDIA_STREAM,
-] partial interface Navigator {
- [RaisesException] void webkitGetUserMedia(Dictionary options,
- NavigatorUserMediaSuccessCallback successCallback,
- optional NavigatorUserMediaErrorCallback errorCallback);
-};
-
diff --git a/Source/WebCore/Modules/mediastream/NavigatorUserMedia.idl b/Source/WebCore/Modules/mediastream/NavigatorUserMedia.idl
new file mode 100644
index 000000000..85e32d318
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/NavigatorUserMedia.idl
@@ -0,0 +1,36 @@
+/*
+* Copyright (C) 2017 Apple Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* 3. Neither the name of Ericsson nor the names of its contributors
+* may be used to endorse or promote products derived from this
+* software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+[
+ Conditional=MEDIA_STREAM,
+ EnabledAtRuntime=MediaStream,
+] partial interface Navigator {
+ [JSBuiltin] void getUserMedia(MediaStreamConstraints constraints, NavigatorUserMediaSuccessCallback successCallback, NavigatorUserMediaErrorCallback errorCallback);
+};
diff --git a/Source/WebCore/Modules/mediastream/NavigatorUserMedia.js b/Source/WebCore/Modules/mediastream/NavigatorUserMedia.js
new file mode 100644
index 000000000..d1417d78b
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/NavigatorUserMedia.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Canon Inc.
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// @conditional=ENABLE(MEDIA_STREAM)
+
+function getUserMedia(options, successCallback, errorCallback)
+{
+ "use strict";
+
+ // FIXME: We should raise a DOM unsupported exception if there is no navigator and properly detect whether method is not called on a Navigator object.
+ if (!(this.mediaDevices && this.mediaDevices.@getUserMedia))
+ throw @makeThisTypeError("Navigator", "getUserMedia");
+
+ if (arguments.length < 3)
+ @throwTypeError("Not enough arguments");
+
+ if (options !== @Object(options))
+ @throwTypeError("Argument 1 (options) to Navigator.getUserMedia must be an object");
+
+ if (typeof successCallback !== "function")
+ @throwTypeError("Argument 2 ('successCallback') to Navigator.getUserMedia must be a function");
+ if (typeof errorCallback !== "function")
+ @throwTypeError("Argument 3 ('errorCallback') to Navigator.getUserMedia must be a function");
+
+ this.mediaDevices.@getUserMedia(options).@then(successCallback, errorCallback);
+}
diff --git a/Source/WebCore/Modules/mediastream/NavigatorUserMediaError.cpp b/Source/WebCore/Modules/mediastream/NavigatorUserMediaError.cpp
deleted file mode 100644
index 5ff494582..000000000
--- a/Source/WebCore/Modules/mediastream/NavigatorUserMediaError.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "NavigatorUserMediaError.h"
-
-#include <wtf/NeverDestroyed.h>
-
-namespace WebCore {
-
-const AtomicString& NavigatorUserMediaError::permissionDeniedErrorName()
-{
- static NeverDestroyed<AtomicString> permissionDenied("PermissionDeniedError", AtomicString::ConstructFromLiteral);
- return permissionDenied;
-}
-
-const AtomicString& NavigatorUserMediaError::constraintNotSatisfiedErrorName()
-{
- static NeverDestroyed<AtomicString> constraintNotSatisfied("ConstraintNotSatisfiedError", AtomicString::ConstructFromLiteral);
- return constraintNotSatisfied;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
diff --git a/Source/WebCore/Modules/mediastream/NavigatorUserMediaErrorCallback.h b/Source/WebCore/Modules/mediastream/NavigatorUserMediaErrorCallback.h
deleted file mode 100644
index dd3c8b32b..000000000
--- a/Source/WebCore/Modules/mediastream/NavigatorUserMediaErrorCallback.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef NavigatorUserMediaErrorCallback_h
-#define NavigatorUserMediaErrorCallback_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "NavigatorUserMediaError.h"
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class NavigatorUserMediaErrorCallback : public RefCounted<NavigatorUserMediaErrorCallback> {
-public:
- virtual ~NavigatorUserMediaErrorCallback() { }
- virtual bool handleEvent(NavigatorUserMediaError*) = 0;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // NavigatorUserMediaErrorCallback_h
diff --git a/Source/WebCore/Modules/mediastream/NavigatorUserMediaSuccessCallback.h b/Source/WebCore/Modules/mediastream/NavigatorUserMediaSuccessCallback.h
deleted file mode 100644
index 9f456eadc..000000000
--- a/Source/WebCore/Modules/mediastream/NavigatorUserMediaSuccessCallback.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef NavigatorUserMediaSuccessCallback_h
-#define NavigatorUserMediaSuccessCallback_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class MediaStream;
-
-class NavigatorUserMediaSuccessCallback : public RefCounted<NavigatorUserMediaSuccessCallback> {
-public:
- virtual ~NavigatorUserMediaSuccessCallback() { }
- virtual bool handleEvent(MediaStream*) = 0;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // NavigatorUserMediaSuccessCallback_h
diff --git a/Source/WebCore/Modules/mediastream/OverconstrainedError.h b/Source/WebCore/Modules/mediastream/OverconstrainedError.h
new file mode 100644
index 000000000..126ccb617
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/OverconstrainedError.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <wtf/RefCounted.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class OverconstrainedError : public RefCounted<OverconstrainedError> {
+public:
+ static Ref<OverconstrainedError> create(const String& constraint, const String& message)
+ {
+ return adoptRef(*new OverconstrainedError(constraint, message));
+ }
+
+ String constraint() const { return m_constraint; }
+ String message() const { return m_message; }
+
+protected:
+ explicit OverconstrainedError(const String& constraint, const String& message)
+ : m_constraint(constraint)
+ , m_message(message)
+ {
+ }
+
+private:
+ String m_constraint;
+ String m_message;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/Modules/mediastream/NavigatorUserMediaError.idl b/Source/WebCore/Modules/mediastream/OverconstrainedError.idl
index de1030417..8c505c6a5 100644
--- a/Source/WebCore/Modules/mediastream/NavigatorUserMediaError.idl
+++ b/Source/WebCore/Modules/mediastream/OverconstrainedError.idl
@@ -1,33 +1,36 @@
/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
+ *
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
[
- NoInterfaceObject,
+ Constructor(optional DOMString constraint = "", optional DOMString message = ""),
+ ImplementationLacksVTable,
Conditional=MEDIA_STREAM,
- JSGenerateToJSObject,
-] interface NavigatorUserMediaError : DOMError {
- readonly attribute DOMString constraintName;
+] exception OverconstrainedError {
+ readonly attribute DOMString message;
+ readonly attribute DOMString constraint;
};
-
diff --git a/Source/WebCore/Modules/mediastream/OverconstrainedErrorEvent.h b/Source/WebCore/Modules/mediastream/OverconstrainedErrorEvent.h
new file mode 100644
index 000000000..9c4f39640
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/OverconstrainedErrorEvent.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "Event.h"
+#include "OverconstrainedError.h"
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+class OverconstrainedErrorEvent : public Event {
+public:
+ virtual ~OverconstrainedErrorEvent() { }
+
+ static Ref<OverconstrainedErrorEvent> create(const AtomicString& type, bool canBubble, bool cancelable, OverconstrainedError* error)
+ {
+ return adoptRef(*new OverconstrainedErrorEvent(type, canBubble, cancelable, error));
+ }
+
+ struct Init : EventInit {
+ RefPtr<OverconstrainedError> error;
+ };
+
+ static Ref<OverconstrainedErrorEvent> create(const AtomicString& type, const Init& initializer, IsTrusted isTrusted = IsTrusted::No)
+ {
+ return adoptRef(*new OverconstrainedErrorEvent(type, initializer, isTrusted));
+ }
+
+ OverconstrainedError* error() const { return m_error.get(); }
+ EventInterface eventInterface() const override { return OverconstrainedErrorEventInterfaceType; }
+
+private:
+ explicit OverconstrainedErrorEvent(const AtomicString& type, bool canBubble, bool cancelable, OverconstrainedError* error)
+ : Event(type, canBubble, cancelable)
+ , m_error(error)
+ {
+ }
+ OverconstrainedErrorEvent(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
+ : Event(type, initializer, isTrusted)
+ , m_error(initializer.error)
+ {
+ }
+
+ RefPtr<OverconstrainedError> m_error;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/OverconstrainedErrorEvent.idl b/Source/WebCore/Modules/mediastream/OverconstrainedErrorEvent.idl
new file mode 100644
index 000000000..ceddfa7f2
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/OverconstrainedErrorEvent.idl
@@ -0,0 +1,38 @@
+/*
+* Copyright (C) 2016 Apple Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* 3. Neither the name of Apple Inc. ("Apple") nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+[
+ Conditional=MEDIA_STREAM,
+ Constructor(DOMString type, optional OverconstrainedErrorEventInit eventInitDict),
+] interface OverconstrainedErrorEvent : Event {
+ readonly attribute OverconstrainedError? error;
+};
+
+dictionary OverconstrainedErrorEventInit : EventInit {
+ OverconstrainedError? error = null;
+};
diff --git a/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp b/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp
new file mode 100644
index 000000000..ba2d43fd2
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ * Copyright (C) 2016 Apple INC. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PeerConnectionBackend.h"
+
+#if ENABLE(WEB_RTC)
+
+#include "EventNames.h"
+#include "JSRTCSessionDescription.h"
+#include "RTCIceCandidate.h"
+#include "RTCIceCandidateEvent.h"
+#include "RTCPeerConnection.h"
+
+namespace WebCore {
+
+void PeerConnectionBackend::createOffer(RTCOfferOptions&& options, PeerConnection::SessionDescriptionPromise&& promise)
+{
+ ASSERT(!m_offerAnswerPromise);
+ ASSERT(m_peerConnection.internalSignalingState() != PeerConnectionStates::SignalingState::Closed);
+
+ m_offerAnswerPromise = WTFMove(promise);
+ doCreateOffer(WTFMove(options));
+}
+
+void PeerConnectionBackend::createOfferSucceeded(String&& sdp)
+{
+ ASSERT(isMainThread());
+
+ if (m_peerConnection.internalSignalingState() == PeerConnectionStates::SignalingState::Closed)
+ return;
+
+ ASSERT(m_offerAnswerPromise);
+ m_offerAnswerPromise->resolve(RTCSessionDescription::create(RTCSessionDescription::SdpType::Offer, WTFMove(sdp)));
+ m_offerAnswerPromise = std::nullopt;
+}
+
+void PeerConnectionBackend::createOfferFailed(Exception&& exception)
+{
+ ASSERT(isMainThread());
+
+ if (m_peerConnection.internalSignalingState() == PeerConnectionStates::SignalingState::Closed)
+ return;
+
+ ASSERT(m_offerAnswerPromise);
+ m_offerAnswerPromise->reject(WTFMove(exception));
+ m_offerAnswerPromise = std::nullopt;
+}
+
+void PeerConnectionBackend::createAnswer(RTCAnswerOptions&& options, PeerConnection::SessionDescriptionPromise&& promise)
+{
+ ASSERT(!m_offerAnswerPromise);
+ ASSERT(m_peerConnection.internalSignalingState() != PeerConnectionStates::SignalingState::Closed);
+
+ m_offerAnswerPromise = WTFMove(promise);
+ doCreateAnswer(WTFMove(options));
+}
+
+void PeerConnectionBackend::createAnswerSucceeded(String&& sdp)
+{
+ ASSERT(isMainThread());
+
+ if (m_peerConnection.internalSignalingState() == PeerConnectionStates::SignalingState::Closed)
+ return;
+
+ ASSERT(m_offerAnswerPromise);
+ m_offerAnswerPromise->resolve(RTCSessionDescription::create(RTCSessionDescription::SdpType::Answer, WTFMove(sdp)));
+ m_offerAnswerPromise = std::nullopt;
+}
+
+void PeerConnectionBackend::createAnswerFailed(Exception&& exception)
+{
+ ASSERT(isMainThread());
+
+ if (m_peerConnection.internalSignalingState() == PeerConnectionStates::SignalingState::Closed)
+ return;
+
+ ASSERT(m_offerAnswerPromise);
+ m_offerAnswerPromise->reject(WTFMove(exception));
+ m_offerAnswerPromise = std::nullopt;
+}
+
+static inline bool isLocalDescriptionTypeValidForState(RTCSessionDescription::SdpType type, PeerConnectionStates::SignalingState state)
+{
+ switch (state) {
+ case PeerConnectionStates::SignalingState::Stable:
+ return type == RTCSessionDescription::SdpType::Offer;
+ case PeerConnectionStates::SignalingState::HaveLocalOffer:
+ return type == RTCSessionDescription::SdpType::Offer;
+ case PeerConnectionStates::SignalingState::HaveRemoteOffer:
+ return type == RTCSessionDescription::SdpType::Answer || type == RTCSessionDescription::SdpType::Pranswer;
+ case PeerConnectionStates::SignalingState::HaveLocalPrAnswer:
+ return type == RTCSessionDescription::SdpType::Answer || type == RTCSessionDescription::SdpType::Pranswer;
+ default:
+ return false;
+ };
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+void PeerConnectionBackend::setLocalDescription(RTCSessionDescription& sessionDescription, DOMPromise<void>&& promise)
+{
+ ASSERT(m_peerConnection.internalSignalingState() != PeerConnectionStates::SignalingState::Closed);
+
+ if (!isLocalDescriptionTypeValidForState(sessionDescription.type(), m_peerConnection.internalSignalingState())) {
+ promise.reject(INVALID_STATE_ERR, "Description type incompatible with current signaling state");
+ return;
+ }
+
+ m_setDescriptionPromise = WTFMove(promise);
+ doSetLocalDescription(sessionDescription);
+}
+
+void PeerConnectionBackend::setLocalDescriptionSucceeded()
+{
+ ASSERT(isMainThread());
+
+ if (m_peerConnection.internalSignalingState() == PeerConnectionStates::SignalingState::Closed)
+ return;
+
+ ASSERT(m_setDescriptionPromise);
+
+ m_setDescriptionPromise->resolve();
+ m_setDescriptionPromise = std::nullopt;
+}
+
+void PeerConnectionBackend::setLocalDescriptionFailed(Exception&& exception)
+{
+ ASSERT(isMainThread());
+
+ if (m_peerConnection.internalSignalingState() == PeerConnectionStates::SignalingState::Closed)
+ return;
+
+ ASSERT(m_setDescriptionPromise);
+
+ m_setDescriptionPromise->reject(WTFMove(exception));
+ m_setDescriptionPromise = std::nullopt;
+}
+
+static inline bool isRemoteDescriptionTypeValidForState(RTCSessionDescription::SdpType type, PeerConnectionStates::SignalingState state)
+{
+ switch (state) {
+ case PeerConnectionStates::SignalingState::Stable:
+ return type == RTCSessionDescription::SdpType::Offer;
+ case PeerConnectionStates::SignalingState::HaveLocalOffer:
+ return type == RTCSessionDescription::SdpType::Answer || type == RTCSessionDescription::SdpType::Pranswer;
+ case PeerConnectionStates::SignalingState::HaveRemoteOffer:
+ return type == RTCSessionDescription::SdpType::Offer;
+ case PeerConnectionStates::SignalingState::HaveRemotePrAnswer:
+ return type == RTCSessionDescription::SdpType::Answer || type == RTCSessionDescription::SdpType::Pranswer;
+ default:
+ return false;
+ };
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+void PeerConnectionBackend::setRemoteDescription(RTCSessionDescription& sessionDescription, DOMPromise<void>&& promise)
+{
+ ASSERT(m_peerConnection.internalSignalingState() != PeerConnectionStates::SignalingState::Closed);
+
+ if (!isRemoteDescriptionTypeValidForState(sessionDescription.type(), m_peerConnection.internalSignalingState())) {
+ promise.reject(INVALID_STATE_ERR, "Description type incompatible with current signaling state");
+ return;
+ }
+
+ m_setDescriptionPromise = WTFMove(promise);
+ doSetRemoteDescription(sessionDescription);
+}
+
+void PeerConnectionBackend::setRemoteDescriptionSucceeded()
+{
+ ASSERT(isMainThread());
+
+ if (m_peerConnection.internalSignalingState() == PeerConnectionStates::SignalingState::Closed)
+ return;
+
+ ASSERT(m_setDescriptionPromise);
+
+ m_setDescriptionPromise->resolve();
+ m_setDescriptionPromise = std::nullopt;
+}
+
+void PeerConnectionBackend::setRemoteDescriptionFailed(Exception&& exception)
+{
+ ASSERT(isMainThread());
+
+ if (m_peerConnection.internalSignalingState() == PeerConnectionStates::SignalingState::Closed)
+ return;
+
+ ASSERT(m_setDescriptionPromise);
+
+ m_setDescriptionPromise->reject(WTFMove(exception));
+ m_setDescriptionPromise = std::nullopt;
+}
+
+void PeerConnectionBackend::addIceCandidate(RTCIceCandidate& iceCandidate, DOMPromise<void>&& promise)
+{
+ ASSERT(m_peerConnection.internalSignalingState() != PeerConnectionStates::SignalingState::Closed);
+
+ if (iceCandidate.sdpMid().isNull() && !iceCandidate.sdpMLineIndex()) {
+ promise.reject(Exception { TypeError, ASCIILiteral("Trying to add a candidate that is missing both sdpMid and sdpMLineIndex") });
+ return;
+ }
+ m_addIceCandidatePromise = WTFMove(promise);
+ doAddIceCandidate(iceCandidate);
+}
+
+void PeerConnectionBackend::addIceCandidateSucceeded()
+{
+ ASSERT(isMainThread());
+
+ if (m_peerConnection.internalSignalingState() == PeerConnectionStates::SignalingState::Closed)
+ return;
+
+ // FIXME: Update remote description and set ICE connection state to checking if not already done so.
+ ASSERT(m_addIceCandidatePromise);
+
+ m_addIceCandidatePromise->resolve();
+ m_addIceCandidatePromise = std::nullopt;
+}
+
+void PeerConnectionBackend::addIceCandidateFailed(Exception&& exception)
+{
+ ASSERT(isMainThread());
+ if (m_peerConnection.internalSignalingState() == PeerConnectionStates::SignalingState::Closed)
+ return;
+
+ ASSERT(m_addIceCandidatePromise);
+
+ m_addIceCandidatePromise->reject(WTFMove(exception));
+ m_addIceCandidatePromise = std::nullopt;
+}
+
+void PeerConnectionBackend::fireICECandidateEvent(RefPtr<RTCIceCandidate>&& candidate)
+{
+ ASSERT(isMainThread());
+
+ m_peerConnection.fireEvent(RTCIceCandidateEvent::create(false, false, WTFMove(candidate)));
+}
+
+void PeerConnectionBackend::doneGatheringCandidates()
+{
+ ASSERT(isMainThread());
+
+ m_peerConnection.fireEvent(RTCIceCandidateEvent::create(false, false, nullptr));
+ m_peerConnection.updateIceGatheringState(PeerConnectionStates::IceGatheringState::Complete);
+}
+
+void PeerConnectionBackend::updateSignalingState(PeerConnectionStates::SignalingState newSignalingState)
+{
+ ASSERT(isMainThread());
+
+ if (newSignalingState != m_peerConnection.internalSignalingState()) {
+ m_peerConnection.setSignalingState(newSignalingState);
+ m_peerConnection.fireEvent(Event::create(eventNames().signalingstatechangeEvent, false, false));
+ }
+}
+
+void PeerConnectionBackend::stop()
+{
+ m_offerAnswerPromise = std::nullopt;
+ m_setDescriptionPromise = std::nullopt;
+ m_addIceCandidatePromise = std::nullopt;
+
+ doStop();
+}
+
+void PeerConnectionBackend::markAsNeedingNegotiation()
+{
+ if (m_negotiationNeeded)
+ return;
+
+ m_negotiationNeeded = true;
+
+ if (m_peerConnection.internalSignalingState() == PeerConnectionStates::SignalingState::Stable)
+ m_peerConnection.scheduleNegotiationNeededEvent();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h b/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h
new file mode 100644
index 000000000..5df7db454
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "JSDOMPromise.h"
+#include "PeerConnectionStates.h"
+
+namespace WebCore {
+
+class MediaStream;
+class MediaStreamTrack;
+class PeerConnectionBackend;
+class RTCDataChannelHandler;
+class RTCIceCandidate;
+class RTCPeerConnection;
+class RTCRtpReceiver;
+class RTCRtpSender;
+class RTCSessionDescription;
+class RTCStatsReport;
+
+struct MediaEndpointConfiguration;
+struct RTCAnswerOptions;
+struct RTCDataChannelInit;
+struct RTCOfferOptions;
+
+namespace PeerConnection {
+using SessionDescriptionPromise = DOMPromise<IDLInterface<RTCSessionDescription>>;
+using StatsPromise = DOMPromise<IDLInterface<RTCStatsReport>>;
+}
+
+using CreatePeerConnectionBackend = std::unique_ptr<PeerConnectionBackend> (*)(RTCPeerConnection&);
+
+// FIXME: What is the value of this abstract class? There is only one concrete class derived from it.
+class PeerConnectionBackend {
+public:
+ WEBCORE_EXPORT static CreatePeerConnectionBackend create;
+
+ PeerConnectionBackend(RTCPeerConnection& peerConnection) : m_peerConnection(peerConnection) { }
+ virtual ~PeerConnectionBackend() { }
+
+ void createOffer(RTCOfferOptions&&, PeerConnection::SessionDescriptionPromise&&);
+ void createAnswer(RTCAnswerOptions&&, PeerConnection::SessionDescriptionPromise&&);
+ void setLocalDescription(RTCSessionDescription&, DOMPromise<void>&&);
+ void setRemoteDescription(RTCSessionDescription&, DOMPromise<void>&&);
+ void addIceCandidate(RTCIceCandidate&, DOMPromise<void>&&);
+
+ virtual std::unique_ptr<RTCDataChannelHandler> createDataChannelHandler(const String&, const RTCDataChannelInit&) = 0;
+
+ void stop();
+
+ virtual RefPtr<RTCSessionDescription> localDescription() const = 0;
+ virtual RefPtr<RTCSessionDescription> currentLocalDescription() const = 0;
+ virtual RefPtr<RTCSessionDescription> pendingLocalDescription() const = 0;
+
+ virtual RefPtr<RTCSessionDescription> remoteDescription() const = 0;
+ virtual RefPtr<RTCSessionDescription> currentRemoteDescription() const = 0;
+ virtual RefPtr<RTCSessionDescription> pendingRemoteDescription() const = 0;
+
+ virtual void setConfiguration(MediaEndpointConfiguration&&) = 0;
+
+ virtual void getStats(MediaStreamTrack*, Ref<DeferredPromise>&&) = 0;
+
+ virtual Vector<RefPtr<MediaStream>> getRemoteStreams() const = 0;
+
+ virtual Ref<RTCRtpReceiver> createReceiver(const String& transceiverMid, const String& trackKind, const String& trackId) = 0;
+ virtual void replaceTrack(RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromise<void>&&) = 0;
+
+ void markAsNeedingNegotiation();
+ bool isNegotiationNeeded() const { return m_negotiationNeeded; };
+ void clearNegotiationNeededState() { m_negotiationNeeded = false; };
+
+ virtual void emulatePlatformEvent(const String& action) = 0;
+
+protected:
+ void fireICECandidateEvent(RefPtr<RTCIceCandidate>&&);
+ void doneGatheringCandidates();
+
+ void updateSignalingState(PeerConnectionStates::SignalingState);
+
+ void createOfferSucceeded(String&&);
+ void createOfferFailed(Exception&&);
+
+ void createAnswerSucceeded(String&&);
+ void createAnswerFailed(Exception&&);
+
+ void setLocalDescriptionSucceeded();
+ void setLocalDescriptionFailed(Exception&&);
+
+ void setRemoteDescriptionSucceeded();
+ void setRemoteDescriptionFailed(Exception&&);
+
+ void addIceCandidateSucceeded();
+ void addIceCandidateFailed(Exception&&);
+
+private:
+ virtual void doCreateOffer(RTCOfferOptions&&) = 0;
+ virtual void doCreateAnswer(RTCAnswerOptions&&) = 0;
+ virtual void doSetLocalDescription(RTCSessionDescription&) = 0;
+ virtual void doSetRemoteDescription(RTCSessionDescription&) = 0;
+ virtual void doAddIceCandidate(RTCIceCandidate&) = 0;
+ virtual void doStop() = 0;
+
+protected:
+ RTCPeerConnection& m_peerConnection;
+
+private:
+ std::optional<PeerConnection::SessionDescriptionPromise> m_offerAnswerPromise;
+ std::optional<DOMPromise<void>> m_setDescriptionPromise;
+ std::optional<DOMPromise<void>> m_addIceCandidatePromise;
+
+ bool m_negotiationNeeded { false };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescriptionCallback.h b/Source/WebCore/Modules/mediastream/RTCConfiguration.h
index 06ee071c4..2f06ea25a 100644
--- a/Source/WebCore/Modules/mediastream/RTCSessionDescriptionCallback.h
+++ b/Source/WebCore/Modules/mediastream/RTCConfiguration.h
@@ -28,25 +28,27 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCSessionDescriptionCallback_h
-#define RTCSessionDescriptionCallback_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
-#include <wtf/RefCounted.h>
+#include "PeerConnectionStates.h"
+#include "RTCIceServer.h"
namespace WebCore {
-class RTCSessionDescription;
+using RTCIceTransportPolicy = PeerConnectionStates::IceTransportPolicy;
+using RTCBundlePolicy = PeerConnectionStates::BundlePolicy;
-class RTCSessionDescriptionCallback : public RefCounted<RTCSessionDescriptionCallback> {
-public:
- virtual ~RTCSessionDescriptionCallback() { }
- virtual bool handleEvent(RTCSessionDescription*) = 0;
+struct RTCConfiguration {
+ using IceTransportPolicy = RTCIceTransportPolicy;
+ using BundlePolicy = RTCBundlePolicy;
+
+ std::optional<Vector<RTCIceServer>> iceServers;
+ IceTransportPolicy iceTransportPolicy;
+ BundlePolicy bundlePolicy;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCSessionDescriptionCallback_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/AllAudioCapabilities.idl b/Source/WebCore/Modules/mediastream/RTCConfiguration.idl
index dfb3a6e0c..3d2664dbc 100644
--- a/Source/WebCore/Modules/mediastream/AllAudioCapabilities.idl
+++ b/Source/WebCore/Modules/mediastream/RTCConfiguration.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,24 +10,27 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+enum RTCIceTransportPolicy { "relay", "all" };
+enum RTCBundlePolicy { "balanced", "max-compat", "max-bundle" };
+
[
- NoInterfaceObject,
- Conditional=MEDIA_STREAM,
+ Conditional=WEB_RTC,
JSGenerateToJSObject,
-] interface AllAudioCapabilities : MediaStreamCapabilities {
- readonly attribute DOMString[] sourceId;
- readonly attribute CapabilityRange volume;
+] dictionary RTCConfiguration {
+ sequence<RTCIceServer> iceServers;
+ RTCIceTransportPolicy iceTransportPolicy = "all";
+ RTCBundlePolicy bundlePolicy = "balanced";
};
diff --git a/Source/WebCore/Modules/mediastream/RTCDTMFSender.cpp b/Source/WebCore/Modules/mediastream/RTCDTMFSender.cpp
index 3167d9275..08eae7b70 100644
--- a/Source/WebCore/Modules/mediastream/RTCDTMFSender.cpp
+++ b/Source/WebCore/Modules/mediastream/RTCDTMFSender.cpp
@@ -24,50 +24,31 @@
*/
#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
#include "RTCDTMFSender.h"
-#include "ExceptionCode.h"
+#if ENABLE(WEB_RTC)
+
#include "MediaStreamTrack.h"
#include "RTCDTMFSenderHandler.h"
#include "RTCDTMFToneChangeEvent.h"
-#include "RTCPeerConnectionHandler.h"
#include "ScriptExecutionContext.h"
namespace WebCore {
-static const long minToneDurationMs = 70;
+static const long minToneDurationMs = 40;
static const long defaultToneDurationMs = 100;
static const long maxToneDurationMs = 6000;
-static const long minInterToneGapMs = 50;
-static const long defaultInterToneGapMs = 50;
-
-PassRefPtr<RTCDTMFSender> RTCDTMFSender::create(ScriptExecutionContext* context, RTCPeerConnectionHandler* peerConnectionHandler, PassRefPtr<MediaStreamTrack> prpTrack, ExceptionCode& ec)
-{
- RefPtr<MediaStreamTrack> track = prpTrack;
- std::unique_ptr<RTCDTMFSenderHandler> handler = peerConnectionHandler->createDTMFSender(track->source());
- if (!handler) {
- ec = NOT_SUPPORTED_ERR;
- return nullptr;
- }
-
- RefPtr<RTCDTMFSender> dtmfSender = adoptRef(new RTCDTMFSender(context, track, std::move(handler)));
- dtmfSender->suspendIfNeeded();
- return dtmfSender.release();
-}
+static const long minInterToneGapMs = 30;
+static const long defaultInterToneGapMs = 70;
-RTCDTMFSender::RTCDTMFSender(ScriptExecutionContext* context, PassRefPtr<MediaStreamTrack> track, std::unique_ptr<RTCDTMFSenderHandler> handler)
- : ActiveDOMObject(context)
- , m_track(track)
+RTCDTMFSender::RTCDTMFSender(ScriptExecutionContext& context, RefPtr<MediaStreamTrack>&& track)
+ : ActiveDOMObject(&context)
+ , m_track(WTFMove(track))
, m_duration(defaultToneDurationMs)
, m_interToneGap(defaultInterToneGapMs)
- , m_handler(std::move(handler))
, m_stopped(false)
- , m_scheduledEventTimer(this, &RTCDTMFSender::scheduledEventTimerFired)
+ , m_scheduledEventTimer(*this, &RTCDTMFSender::scheduledEventTimerFired)
{
- m_handler->setClient(this);
}
RTCDTMFSender::~RTCDTMFSender()
@@ -76,7 +57,7 @@ RTCDTMFSender::~RTCDTMFSender()
bool RTCDTMFSender::canInsertDTMF() const
{
- return m_handler->canInsertDTMF();
+ return false;
}
MediaStreamTrack* RTCDTMFSender::track() const
@@ -86,41 +67,24 @@ MediaStreamTrack* RTCDTMFSender::track() const
String RTCDTMFSender::toneBuffer() const
{
- return m_handler->currentToneBuffer();
+ return { };
}
-void RTCDTMFSender::insertDTMF(const String& tones, ExceptionCode& ec)
+ExceptionOr<void> RTCDTMFSender::insertDTMF(const String&, std::optional<int> duration, std::optional<int> interToneGap)
{
- insertDTMF(tones, defaultToneDurationMs, defaultInterToneGapMs, ec);
-}
+ if (!canInsertDTMF())
+ return Exception { NOT_SUPPORTED_ERR };
-void RTCDTMFSender::insertDTMF(const String& tones, long duration, ExceptionCode& ec)
-{
- insertDTMF(tones, duration, defaultInterToneGapMs, ec);
-}
+ if (duration && (duration.value() > maxToneDurationMs || duration.value() < minToneDurationMs))
+ return Exception { SYNTAX_ERR };
-void RTCDTMFSender::insertDTMF(const String& tones, long duration, long interToneGap, ExceptionCode& ec)
-{
- if (!canInsertDTMF()) {
- ec = NOT_SUPPORTED_ERR;
- return;
- }
+ if (interToneGap && interToneGap.value() < minInterToneGapMs)
+ return Exception { SYNTAX_ERR };
- if (duration > maxToneDurationMs || duration < minToneDurationMs) {
- ec = SYNTAX_ERR;
- return;
- }
-
- if (interToneGap < minInterToneGapMs) {
- ec = SYNTAX_ERR;
- return;
- }
+ m_duration = duration.value_or(defaultToneDurationMs);
+ m_interToneGap = interToneGap.value_or(defaultInterToneGapMs);
- m_duration = duration;
- m_interToneGap = interToneGap;
-
- if (!m_handler->insertDTMF(tones, m_duration, m_interToneGap))
- ec = SYNTAX_ERR;
+ return Exception { SYNTAX_ERR };
}
void RTCDTMFSender::didPlayTone(const String& tone)
@@ -131,30 +95,39 @@ void RTCDTMFSender::didPlayTone(const String& tone)
void RTCDTMFSender::stop()
{
m_stopped = true;
- m_handler->setClient(0);
}
-void RTCDTMFSender::scheduleDispatchEvent(PassRefPtr<Event> event)
+const char* RTCDTMFSender::activeDOMObjectName() const
+{
+ return "RTCDTMFSender";
+}
+
+bool RTCDTMFSender::canSuspendForDocumentSuspension() const
+{
+ // FIXME: We should try and do better here.
+ return false;
+}
+
+void RTCDTMFSender::scheduleDispatchEvent(Ref<Event>&& event)
{
- m_scheduledEvents.append(event);
+ m_scheduledEvents.append(WTFMove(event));
if (!m_scheduledEventTimer.isActive())
m_scheduledEventTimer.startOneShot(0);
}
-void RTCDTMFSender::scheduledEventTimerFired(Timer<RTCDTMFSender>*)
+void RTCDTMFSender::scheduledEventTimerFired()
{
if (m_stopped)
return;
- Vector<RefPtr<Event>> events;
+ Vector<Ref<Event>> events;
events.swap(m_scheduledEvents);
- Vector<RefPtr<Event>>::iterator it = events.begin();
- for (; it != events.end(); ++it)
- dispatchEvent((*it).release());
+ for (auto& event : events)
+ dispatchEvent(event);
}
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCDTMFSender.h b/Source/WebCore/Modules/mediastream/RTCDTMFSender.h
index 0e6b49d32..c67b3a164 100644
--- a/Source/WebCore/Modules/mediastream/RTCDTMFSender.h
+++ b/Source/WebCore/Modules/mediastream/RTCDTMFSender.h
@@ -23,78 +23,63 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCDTMFSender_h
-#define RTCDTMFSender_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include "ActiveDOMObject.h"
#include "EventTarget.h"
-#include "RTCDTMFSenderHandlerClient.h"
+#include "ExceptionOr.h"
#include "ScriptWrappable.h"
#include "Timer.h"
-#include <wtf/RefCounted.h>
namespace WebCore {
class MediaStreamTrack;
-class RTCPeerConnectionHandler;
-class RTCDTMFSenderHandler;
-class RTCDTMFSender final : public RefCounted<RTCDTMFSender>, public ScriptWrappable, public EventTargetWithInlineData, public RTCDTMFSenderHandlerClient, public ActiveDOMObject {
+class RTCDTMFSender final : public RefCounted<RTCDTMFSender>, public EventTargetWithInlineData, public ActiveDOMObject {
public:
- static PassRefPtr<RTCDTMFSender> create(ScriptExecutionContext*, RTCPeerConnectionHandler*, PassRefPtr<MediaStreamTrack>, ExceptionCode&);
- ~RTCDTMFSender();
+ virtual ~RTCDTMFSender();
bool canInsertDTMF() const;
MediaStreamTrack* track() const;
String toneBuffer() const;
- long duration() const { return m_duration; }
- long interToneGap() const { return m_interToneGap; }
+ int duration() const { return m_duration; }
+ int interToneGap() const { return m_interToneGap; }
- void insertDTMF(const String& tones, ExceptionCode&);
- void insertDTMF(const String& tones, long duration, ExceptionCode&);
- void insertDTMF(const String& tones, long duration, long interToneGap, ExceptionCode&);
+ ExceptionOr<void> insertDTMF(const String& tones, std::optional<int> duration, std::optional<int> interToneGap);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(tonechange);
+ using RefCounted::ref;
+ using RefCounted::deref;
- // EventTarget
- virtual EventTargetInterface eventTargetInterface() const override { return RTCDTMFSenderEventTargetInterfaceType; }
- virtual ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); }
-
- // ActiveDOMObject
- virtual void stop() override;
+private:
+ RTCDTMFSender(ScriptExecutionContext&, RefPtr<MediaStreamTrack>&&);
- using RefCounted<RTCDTMFSender>::ref;
- using RefCounted<RTCDTMFSender>::deref;
+ void stop() final;
+ const char* activeDOMObjectName() const final;
+ bool canSuspendForDocumentSuspension() const final;
-private:
- RTCDTMFSender(ScriptExecutionContext*, PassRefPtr<MediaStreamTrack>, std::unique_ptr<RTCDTMFSenderHandler>);
+ EventTargetInterface eventTargetInterface() const final { return RTCDTMFSenderEventTargetInterfaceType; }
+ ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
- void scheduleDispatchEvent(PassRefPtr<Event>);
- void scheduledEventTimerFired(Timer<RTCDTMFSender>*);
+ void refEventTarget() final { ref(); }
+ void derefEventTarget() final { deref(); }
- // EventTarget
- virtual void refEventTarget() override { ref(); }
- virtual void derefEventTarget() override { deref(); }
+ void didPlayTone(const String&);
- // RTCDTMFSenderHandlerClient
- virtual void didPlayTone(const String&) override;
+ void scheduleDispatchEvent(Ref<Event>&&);
+ void scheduledEventTimerFired();
RefPtr<MediaStreamTrack> m_track;
- long m_duration;
- long m_interToneGap;
-
- std::unique_ptr<RTCDTMFSenderHandler> m_handler;
+ int m_duration;
+ int m_interToneGap;
bool m_stopped;
- Timer<RTCDTMFSender> m_scheduledEventTimer;
- Vector<RefPtr<Event>> m_scheduledEvents;
+ Timer m_scheduledEventTimer;
+ Vector<Ref<Event>> m_scheduledEvents;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCDTMFSender_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCDTMFSender.idl b/Source/WebCore/Modules/mediastream/RTCDTMFSender.idl
index f4fb77158..fea23bda9 100644
--- a/Source/WebCore/Modules/mediastream/RTCDTMFSender.idl
+++ b/Source/WebCore/Modules/mediastream/RTCDTMFSender.idl
@@ -24,27 +24,17 @@
*/
[
- NoInterfaceObject,
- Conditional=MEDIA_STREAM,
ActiveDOMObject,
- EventTarget,
-] interface RTCDTMFSender {
+ Conditional=WEB_RTC,
+ NoInterfaceObject,
+] interface RTCDTMFSender : EventTarget {
readonly attribute boolean canInsertDTMF;
readonly attribute MediaStreamTrack track;
readonly attribute DOMString toneBuffer;
readonly attribute long duration;
readonly attribute long interToneGap;
- [RaisesException] void insertDTMF(DOMString tones, optional long duration, optional long interToneGap);
-
- attribute EventListener ontonechange;
+ [MayThrowException] void insertDTMF(DOMString tones, optional long duration, optional long interToneGap);
- // EventTarget interface
- void addEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- void removeEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event event);
+ attribute EventHandler ontonechange;
};
diff --git a/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.cpp b/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.cpp
index 526ef2c6b..d6ff9fda8 100644
--- a/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.cpp
+++ b/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.cpp
@@ -26,30 +26,20 @@
#include "config.h"
#include "RTCDTMFToneChangeEvent.h"
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include "EventNames.h"
namespace WebCore {
-PassRefPtr<RTCDTMFToneChangeEvent> RTCDTMFToneChangeEvent::create()
+Ref<RTCDTMFToneChangeEvent> RTCDTMFToneChangeEvent::create(const String& tone)
{
- return adoptRef(new RTCDTMFToneChangeEvent);
+ return adoptRef(*new RTCDTMFToneChangeEvent(tone));
}
-PassRefPtr<RTCDTMFToneChangeEvent> RTCDTMFToneChangeEvent::create(const String& tone)
-{
- return adoptRef(new RTCDTMFToneChangeEvent(tone));
-}
-
-PassRefPtr<RTCDTMFToneChangeEvent> RTCDTMFToneChangeEvent::create(const AtomicString& type, const RTCDTMFToneChangeEventInit& initializer)
-{
- ASSERT_UNUSED(type, type == eventNames().tonechangeEvent);
- return adoptRef(new RTCDTMFToneChangeEvent(initializer));
-}
-
-RTCDTMFToneChangeEvent::RTCDTMFToneChangeEvent()
+Ref<RTCDTMFToneChangeEvent> RTCDTMFToneChangeEvent::create(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
{
+ return adoptRef(*new RTCDTMFToneChangeEvent(type, initializer, isTrusted));
}
RTCDTMFToneChangeEvent::RTCDTMFToneChangeEvent(const String& tone)
@@ -58,8 +48,8 @@ RTCDTMFToneChangeEvent::RTCDTMFToneChangeEvent(const String& tone)
{
}
-RTCDTMFToneChangeEvent::RTCDTMFToneChangeEvent(const RTCDTMFToneChangeEventInit& initializer)
- : Event(eventNames().tonechangeEvent, initializer)
+RTCDTMFToneChangeEvent::RTCDTMFToneChangeEvent(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
+ : Event(type, initializer, isTrusted)
, m_tone(initializer.tone)
{
}
@@ -80,5 +70,5 @@ EventInterface RTCDTMFToneChangeEvent::eventInterface() const
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.h b/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.h
index 0693db694..112d529a5 100644
--- a/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.h
+++ b/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.h
@@ -23,42 +23,38 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCDTMFToneChangeEvent_h
-#define RTCDTMFToneChangeEvent_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include "Event.h"
#include <wtf/text/AtomicString.h>
namespace WebCore {
-struct RTCDTMFToneChangeEventInit : public EventInit {
- String tone;
-};
-
class RTCDTMFToneChangeEvent : public Event {
public:
virtual ~RTCDTMFToneChangeEvent();
- static PassRefPtr<RTCDTMFToneChangeEvent> create();
- static PassRefPtr<RTCDTMFToneChangeEvent> create(const String& tone);
- static PassRefPtr<RTCDTMFToneChangeEvent> create(const AtomicString& type, const RTCDTMFToneChangeEventInit& initializer);
+ static Ref<RTCDTMFToneChangeEvent> create(const String& tone);
+
+ struct Init : EventInit {
+ String tone;
+ };
+
+ static Ref<RTCDTMFToneChangeEvent> create(const AtomicString& type, const Init&, IsTrusted = IsTrusted::No);
const String& tone() const;
virtual EventInterface eventInterface() const;
private:
- RTCDTMFToneChangeEvent();
explicit RTCDTMFToneChangeEvent(const String& tone);
- explicit RTCDTMFToneChangeEvent(const RTCDTMFToneChangeEventInit&);
+ RTCDTMFToneChangeEvent(const AtomicString& type, const Init&, IsTrusted);
String m_tone;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCDTMFToneChangeEvent_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.idl b/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.idl
index 1edebd33e..722df3cf7 100644
--- a/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.idl
+++ b/Source/WebCore/Modules/mediastream/RTCDTMFToneChangeEvent.idl
@@ -24,9 +24,13 @@
*/
[
- NoInterfaceObject,
- Conditional=MEDIA_STREAM,
- ConstructorTemplate=Event
+ Conditional=WEB_RTC,
+ Constructor(DOMString type, optional RTCDTMFToneChangeEventInit eventInitDict),
+ EnabledAtRuntime=PeerConnection,
] interface RTCDTMFToneChangeEvent : Event {
- [InitializedByEventConstructor] readonly attribute DOMString tone;
+ readonly attribute DOMString tone;
+};
+
+dictionary RTCDTMFToneChangeEventInit : EventInit {
+ DOMString tone = "";
};
diff --git a/Source/WebCore/Modules/mediastream/RTCDataChannel.cpp b/Source/WebCore/Modules/mediastream/RTCDataChannel.cpp
index 4e876bb7e..76723e4ee 100644
--- a/Source/WebCore/Modules/mediastream/RTCDataChannel.cpp
+++ b/Source/WebCore/Modules/mediastream/RTCDataChannel.cpp
@@ -23,18 +23,16 @@
*/
#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
#include "RTCDataChannel.h"
+#if ENABLE(WEB_RTC)
+
#include "Blob.h"
-#include "Dictionary.h"
#include "Event.h"
+#include "EventNames.h"
#include "ExceptionCode.h"
#include "MessageEvent.h"
#include "RTCDataChannelHandler.h"
-#include "RTCPeerConnectionHandler.h"
#include "ScriptExecutionContext.h"
#include <runtime/ArrayBuffer.h>
#include <runtime/ArrayBufferView.h>
@@ -54,87 +52,30 @@ static const AtomicString& arraybufferKeyword()
return arraybuffer;
}
-PassRefPtr<RTCDataChannel> RTCDataChannel::create(ScriptExecutionContext* context, RTCPeerConnectionHandler* peerConnectionHandler, const String& label, const Dictionary& options, ExceptionCode& ec)
-{
- RTCDataChannelInit initData;
- options.get("ordered", initData.ordered);
- options.get("negotiated", initData.negotiated);
- options.get("id", initData.id);
- options.get("maxRetransmits", initData.maxRetransmits);
- options.get("maxRetransmitTime", initData.maxRetransmitTime);
- options.get("protocol", initData.protocol);
-
- std::unique_ptr<RTCDataChannelHandler> handler = peerConnectionHandler->createDataChannel(label, initData);
- if (!handler) {
- ec = NOT_SUPPORTED_ERR;
- return nullptr;
- }
- return adoptRef(new RTCDataChannel(context, std::move(handler)));
-}
-
-PassRefPtr<RTCDataChannel> RTCDataChannel::create(ScriptExecutionContext* context, std::unique_ptr<RTCDataChannelHandler> handler)
+Ref<RTCDataChannel> RTCDataChannel::create(ScriptExecutionContext& context, std::unique_ptr<RTCDataChannelHandler>&& handler, String&& label, RTCDataChannelInit&& options)
{
ASSERT(handler);
- return adoptRef(new RTCDataChannel(context, std::move(handler)));
-}
-
-RTCDataChannel::RTCDataChannel(ScriptExecutionContext* context, std::unique_ptr<RTCDataChannelHandler> handler)
- : m_scriptExecutionContext(context)
- , m_handler(std::move(handler))
- , m_stopped(false)
- , m_readyState(ReadyStateConnecting)
- , m_binaryType(BinaryTypeArrayBuffer)
- , m_scheduledEventTimer(this, &RTCDataChannel::scheduledEventTimerFired)
-{
- m_handler->setClient(this);
-}
-
-RTCDataChannel::~RTCDataChannel()
-{
-}
-
-String RTCDataChannel::label() const
-{
- return m_handler->label();
-}
-
-bool RTCDataChannel::ordered() const
-{
- return m_handler->ordered();
-}
-
-unsigned short RTCDataChannel::maxRetransmitTime() const
-{
- return m_handler->maxRetransmitTime();
-}
-
-unsigned short RTCDataChannel::maxRetransmits() const
-{
-return m_handler->maxRetransmits();
-}
-
-String RTCDataChannel::protocol() const
-{
- return m_handler->protocol();
-}
-
-bool RTCDataChannel::negotiated() const
-{
- return m_handler->negotiated();
+ auto channel = adoptRef(*new RTCDataChannel(context, WTFMove(handler), WTFMove(label), WTFMove(options)));
+ channel->m_handler->setClient(&channel.get());
+ return channel;
}
-unsigned short RTCDataChannel::id() const
+RTCDataChannel::RTCDataChannel(ScriptExecutionContext& context, std::unique_ptr<RTCDataChannelHandler>&& handler, String&& label, RTCDataChannelInit&& options)
+ : m_scriptExecutionContext(&context)
+ , m_handler(WTFMove(handler))
+ , m_scheduledEventTimer(*this, &RTCDataChannel::scheduledEventTimerFired)
+ , m_label(WTFMove(label))
+ , m_options(WTFMove(options))
{
- return m_handler->id();
}
-AtomicString RTCDataChannel::readyState() const
+const AtomicString& RTCDataChannel::readyState() const
{
static NeverDestroyed<AtomicString> connectingState("connecting", AtomicString::ConstructFromLiteral);
static NeverDestroyed<AtomicString> openState("open", AtomicString::ConstructFromLiteral);
static NeverDestroyed<AtomicString> closingState("closing", AtomicString::ConstructFromLiteral);
static NeverDestroyed<AtomicString> closedState("closed", AtomicString::ConstructFromLiteral);
-
+
switch (m_readyState) {
case ReadyStateConnecting:
return connectingState;
@@ -150,17 +91,17 @@ AtomicString RTCDataChannel::readyState() const
return emptyAtom;
}
-unsigned long RTCDataChannel::bufferedAmount() const
+size_t RTCDataChannel::bufferedAmount() const
{
return m_handler->bufferedAmount();
}
-AtomicString RTCDataChannel::binaryType() const
+const AtomicString& RTCDataChannel::binaryType() const
{
switch (m_binaryType) {
- case BinaryTypeBlob:
+ case BinaryType::Blob:
return blobKeyword();
- case BinaryTypeArrayBuffer:
+ case BinaryType::ArrayBuffer:
return arraybufferKeyword();
}
@@ -168,60 +109,58 @@ AtomicString RTCDataChannel::binaryType() const
return emptyAtom;
}
-void RTCDataChannel::setBinaryType(const AtomicString& binaryType, ExceptionCode& ec)
+ExceptionOr<void> RTCDataChannel::setBinaryType(const AtomicString& binaryType)
{
if (binaryType == blobKeyword())
- ec = NOT_SUPPORTED_ERR;
- else if (binaryType == arraybufferKeyword())
- m_binaryType = BinaryTypeArrayBuffer;
- else
- ec = TYPE_MISMATCH_ERR;
+ return Exception { NOT_SUPPORTED_ERR };
+ if (binaryType == arraybufferKeyword()) {
+ m_binaryType = BinaryType::ArrayBuffer;
+ return { };
+ }
+ return Exception { TYPE_MISMATCH_ERR };
}
-void RTCDataChannel::send(const String& data, ExceptionCode& ec)
+ExceptionOr<void> RTCDataChannel::send(const String& data)
{
- if (m_readyState != ReadyStateOpen) {
- ec = INVALID_STATE_ERR;
- return;
- }
+ if (m_readyState != ReadyStateOpen)
+ return Exception { INVALID_STATE_ERR };
if (!m_handler->sendStringData(data)) {
// FIXME: Decide what the right exception here is.
- ec = SYNTAX_ERR;
+ return Exception { SYNTAX_ERR };
}
+
+ return { };
}
-void RTCDataChannel::send(PassRefPtr<ArrayBuffer> prpData, ExceptionCode& ec)
+ExceptionOr<void> RTCDataChannel::send(ArrayBuffer& data)
{
- if (m_readyState != ReadyStateOpen) {
- ec = INVALID_STATE_ERR;
- return;
- }
-
- RefPtr<ArrayBuffer> data = prpData;
+ if (m_readyState != ReadyStateOpen)
+ return Exception { INVALID_STATE_ERR };
- size_t dataLength = data->byteLength();
+ size_t dataLength = data.byteLength();
if (!dataLength)
- return;
+ return { };
- const char* dataPointer = static_cast<const char*>(data->data());
+ const char* dataPointer = static_cast<const char*>(data.data());
if (!m_handler->sendRawData(dataPointer, dataLength)) {
// FIXME: Decide what the right exception here is.
- ec = SYNTAX_ERR;
+ return Exception { SYNTAX_ERR };
}
+
+ return { };
}
-void RTCDataChannel::send(PassRefPtr<ArrayBufferView> data, ExceptionCode& ec)
+ExceptionOr<void> RTCDataChannel::send(ArrayBufferView& data)
{
- RefPtr<ArrayBuffer> arrayBuffer(data->buffer());
- send(arrayBuffer.release(), ec);
+ return send(*data.unsharedBuffer());
}
-void RTCDataChannel::send(PassRefPtr<Blob>, ExceptionCode& ec)
+ExceptionOr<void> RTCDataChannel::send(Blob&)
{
- // FIXME: implement
- ec = NOT_SUPPORTED_ERR;
+ // FIXME: Implement.
+ return Exception { NOT_SUPPORTED_ERR };
}
void RTCDataChannel::close()
@@ -264,14 +203,13 @@ void RTCDataChannel::didReceiveRawData(const char* data, size_t dataLength)
if (m_stopped)
return;
- if (m_binaryType == BinaryTypeBlob) {
+ if (m_binaryType == BinaryType::Blob) {
// FIXME: Implement.
return;
}
- if (m_binaryType == BinaryTypeArrayBuffer) {
- RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(data, dataLength);
- scheduleDispatchEvent(MessageEvent::create(buffer.release()));
+ if (m_binaryType == BinaryType::ArrayBuffer) {
+ scheduleDispatchEvent(MessageEvent::create(ArrayBuffer::create(data, dataLength)));
return;
}
ASSERT_NOT_REACHED();
@@ -285,37 +223,43 @@ void RTCDataChannel::didDetectError()
scheduleDispatchEvent(Event::create(eventNames().errorEvent, false, false));
}
+void RTCDataChannel::bufferedAmountIsDecreasing()
+{
+ if (m_stopped)
+ return;
+
+ if (bufferedAmount() <= m_bufferedAmountLowThreshold)
+ scheduleDispatchEvent(Event::create(eventNames().bufferedAmountLowThresholdEvent, false, false));
+}
+
void RTCDataChannel::stop()
{
m_stopped = true;
m_readyState = ReadyStateClosed;
- m_handler->setClient(0);
- m_scriptExecutionContext = 0;
+ m_handler->setClient(nullptr);
+ m_scriptExecutionContext = nullptr;
}
-void RTCDataChannel::scheduleDispatchEvent(PassRefPtr<Event> event)
+void RTCDataChannel::scheduleDispatchEvent(Ref<Event>&& event)
{
- m_scheduledEvents.append(event);
+ m_scheduledEvents.append(WTFMove(event));
if (!m_scheduledEventTimer.isActive())
m_scheduledEventTimer.startOneShot(0);
}
-void RTCDataChannel::scheduledEventTimerFired(Timer<RTCDataChannel>*)
+void RTCDataChannel::scheduledEventTimerFired()
{
if (m_stopped)
return;
- Vector<RefPtr<Event>> events;
+ Vector<Ref<Event>> events;
events.swap(m_scheduledEvents);
- Vector<RefPtr<Event>>::iterator it = events.begin();
- for (; it != events.end(); ++it)
- dispatchEvent((*it).release());
-
- events.clear();
+ for (auto& event : events)
+ dispatchEvent(event);
}
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCDataChannel.h b/Source/WebCore/Modules/mediastream/RTCDataChannel.h
index 54a21d441..cd860f184 100644
--- a/Source/WebCore/Modules/mediastream/RTCDataChannel.h
+++ b/Source/WebCore/Modules/mediastream/RTCDataChannel.h
@@ -22,16 +22,17 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCDataChannel_h
-#define RTCDataChannel_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
+#include "Event.h"
#include "EventTarget.h"
+#include "ExceptionOr.h"
+#include "RTCDataChannelHandler.h"
#include "RTCDataChannelHandlerClient.h"
#include "ScriptWrappable.h"
#include "Timer.h"
-#include <wtf/RefCounted.h>
namespace JSC {
class ArrayBuffer;
@@ -41,85 +42,78 @@ namespace JSC {
namespace WebCore {
class Blob;
-class Dictionary;
-class RTCDataChannelHandler;
class RTCPeerConnectionHandler;
-class RTCDataChannel final : public RefCounted<RTCDataChannel>, public ScriptWrappable, public EventTargetWithInlineData, public RTCDataChannelHandlerClient {
+class RTCDataChannel final : public RTCDataChannelHandlerClient, public EventTargetWithInlineData {
public:
- static PassRefPtr<RTCDataChannel> create(ScriptExecutionContext*, std::unique_ptr<RTCDataChannelHandler>);
- static PassRefPtr<RTCDataChannel> create(ScriptExecutionContext*, RTCPeerConnectionHandler*, const String& , const Dictionary&, ExceptionCode&);
- ~RTCDataChannel();
-
- String label() const;
- bool ordered() const;
- unsigned short maxRetransmitTime() const;
- unsigned short maxRetransmits() const;
- String protocol() const;
- bool negotiated() const;
- unsigned short id() const;
- AtomicString readyState() const;
- unsigned long bufferedAmount() const;
-
- AtomicString binaryType() const;
- void setBinaryType(const AtomicString&, ExceptionCode&);
-
- void send(const String&, ExceptionCode&);
- void send(PassRefPtr<JSC::ArrayBuffer>, ExceptionCode&);
- void send(PassRefPtr<JSC::ArrayBufferView>, ExceptionCode&);
- void send(PassRefPtr<Blob>, ExceptionCode&);
+ static Ref<RTCDataChannel> create(ScriptExecutionContext&, std::unique_ptr<RTCDataChannelHandler>&&, String&&, RTCDataChannelInit&&);
- void close();
+ bool ordered() const { return m_options.ordered; }
+ unsigned short maxRetransmitTime() const { return m_options.maxRetransmitTime; }
+ unsigned short maxRetransmits() const { return m_options.maxRetransmits; }
+ String protocol() const { return m_options.protocol; }
+ bool negotiated() const { return m_options.negotiated; };
+ unsigned short id() const { return m_options.id; };
- DEFINE_ATTRIBUTE_EVENT_LISTENER(open);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(close);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
+ String label() const { return m_label; }
+ const AtomicString& readyState() const;
+ size_t bufferedAmount() const;
+ size_t bufferedAmountLowThreshold() const { return m_bufferedAmountLowThreshold; }
+ void setBufferedAmountLowThreshold(size_t value) { m_bufferedAmountLowThreshold = value; }
- void stop();
+ const AtomicString& binaryType() const;
+ ExceptionOr<void> setBinaryType(const AtomicString&);
+
+ ExceptionOr<void> send(const String&);
+ ExceptionOr<void> send(JSC::ArrayBuffer&);
+ ExceptionOr<void> send(JSC::ArrayBufferView&);
+ ExceptionOr<void> send(Blob&);
+
+ void close();
- // EventTarget
- virtual EventTargetInterface eventTargetInterface() const override { return RTCDataChannelEventTargetInterfaceType; }
- virtual ScriptExecutionContext* scriptExecutionContext() const override { return m_scriptExecutionContext; }
+ void stop();
- using RefCounted<RTCDataChannel>::ref;
- using RefCounted<RTCDataChannel>::deref;
+ using RTCDataChannelHandlerClient::ref;
+ using RTCDataChannelHandlerClient::deref;
private:
- RTCDataChannel(ScriptExecutionContext*, std::unique_ptr<RTCDataChannelHandler>);
+ RTCDataChannel(ScriptExecutionContext&, std::unique_ptr<RTCDataChannelHandler>&&, String&&, RTCDataChannelInit&&);
+
+ void scheduleDispatchEvent(Ref<Event>&&);
+ void scheduledEventTimerFired();
- void scheduleDispatchEvent(PassRefPtr<Event>);
- void scheduledEventTimerFired(Timer<RTCDataChannel>*);
+ EventTargetInterface eventTargetInterface() const final { return RTCDataChannelEventTargetInterfaceType; }
+ ScriptExecutionContext* scriptExecutionContext() const final { return m_scriptExecutionContext; }
- // EventTarget
- virtual void refEventTarget() override { ref(); }
- virtual void derefEventTarget() override { deref(); }
+ void refEventTarget() final { ref(); }
+ void derefEventTarget() final { deref(); }
ScriptExecutionContext* m_scriptExecutionContext;
- // RTCDataChannelHandlerClient
- virtual void didChangeReadyState(ReadyState) override;
- virtual void didReceiveStringData(const String&) override;
- virtual void didReceiveRawData(const char*, size_t) override;
- virtual void didDetectError() override;
+ // RTCDataChannelHandlerClient API
+ void didChangeReadyState(ReadyState) final;
+ void didReceiveStringData(const String&) final;
+ void didReceiveRawData(const char*, size_t) final;
+ void didDetectError() final;
+ void bufferedAmountIsDecreasing() final;
std::unique_ptr<RTCDataChannelHandler> m_handler;
- bool m_stopped;
+ bool m_stopped { false };
+
+ ReadyState m_readyState { ReadyStateConnecting };
- ReadyState m_readyState;
- enum BinaryType {
- BinaryTypeBlob,
- BinaryTypeArrayBuffer
- };
- BinaryType m_binaryType;
+ enum class BinaryType { Blob, ArrayBuffer };
+ BinaryType m_binaryType { BinaryType::ArrayBuffer };
- Timer<RTCDataChannel> m_scheduledEventTimer;
- Vector<RefPtr<Event>> m_scheduledEvents;
+ Timer m_scheduledEventTimer;
+ Vector<Ref<Event>> m_scheduledEvents;
+
+ String m_label;
+ RTCDataChannelInit m_options;
+ size_t m_bufferedAmountLowThreshold { 0 };
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCDataChannel_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCDataChannel.idl b/Source/WebCore/Modules/mediastream/RTCDataChannel.idl
index 19c24fa1b..e778c0f96 100644
--- a/Source/WebCore/Modules/mediastream/RTCDataChannel.idl
+++ b/Source/WebCore/Modules/mediastream/RTCDataChannel.idl
@@ -23,10 +23,9 @@
*/
[
+ Conditional=WEB_RTC,
NoInterfaceObject,
- Conditional=MEDIA_STREAM,
- EventTarget,
-] interface RTCDataChannel {
+] interface RTCDataChannel : EventTarget {
readonly attribute DOMString label;
readonly attribute boolean ordered;
readonly attribute unsigned short maxRetransmitTime;
@@ -37,26 +36,17 @@
readonly attribute DOMString readyState;
readonly attribute unsigned long bufferedAmount;
- [SetterRaisesException] attribute DOMString binaryType;
+ [SetterMayThrowException] attribute DOMString binaryType;
- [RaisesException] void send(ArrayBuffer data);
- [RaisesException] void send(ArrayBufferView data);
- [RaisesException] void send(Blob data);
- [RaisesException] void send(DOMString data);
+ [MayThrowException] void send(ArrayBuffer data);
+ [MayThrowException] void send(ArrayBufferView data);
+ [MayThrowException] void send(Blob data);
+ [MayThrowException] void send(DOMString data);
void close();
- attribute EventListener onopen;
- attribute EventListener onerror;
- attribute EventListener onclose;
- attribute EventListener onmessage;
-
- // EventTarget interface
- void addEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- void removeEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event event);
+ attribute EventHandler onopen;
+ attribute EventHandler onerror;
+ attribute EventHandler onclose;
+ attribute EventHandler onmessage;
};
diff --git a/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.cpp b/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.cpp
index 136581384..17f81aa34 100644
--- a/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.cpp
+++ b/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.cpp
@@ -25,41 +25,26 @@
#include "config.h"
#include "RTCDataChannelEvent.h"
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
-#include "EventNames.h"
#include "RTCDataChannel.h"
namespace WebCore {
-PassRefPtr<RTCDataChannelEvent> RTCDataChannelEvent::create()
+Ref<RTCDataChannelEvent> RTCDataChannelEvent::create(const AtomicString& type, bool canBubble, bool cancelable, Ref<RTCDataChannel>&& channel)
{
- return adoptRef(new RTCDataChannelEvent);
+ return adoptRef(*new RTCDataChannelEvent(type, canBubble, cancelable, WTFMove(channel)));
}
-PassRefPtr<RTCDataChannelEvent> RTCDataChannelEvent::create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<RTCDataChannel> channel)
-{
- return adoptRef(new RTCDataChannelEvent(type, canBubble, cancelable, channel));
-}
-
-
-RTCDataChannelEvent::RTCDataChannelEvent()
-{
-}
-
-RTCDataChannelEvent::RTCDataChannelEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<RTCDataChannel> channel)
+RTCDataChannelEvent::RTCDataChannelEvent(const AtomicString& type, bool canBubble, bool cancelable, Ref<RTCDataChannel>&& channel)
: Event(type, canBubble, cancelable)
- , m_channel(channel)
-{
-}
-
-RTCDataChannelEvent::~RTCDataChannelEvent()
+ , m_channel(WTFMove(channel))
{
}
-RTCDataChannel* RTCDataChannelEvent::channel() const
+RTCDataChannel* RTCDataChannelEvent::channel()
{
- return m_channel.get();
+ return m_channel.ptr();
}
EventInterface RTCDataChannelEvent::eventInterface() const
@@ -69,5 +54,5 @@ EventInterface RTCDataChannelEvent::eventInterface() const
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.h b/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.h
index 41b003610..5241e2790 100644
--- a/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.h
+++ b/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.h
@@ -22,10 +22,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCDataChannelEvent_h
-#define RTCDataChannelEvent_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include "Event.h"
#include "RTCDataChannel.h"
@@ -35,24 +34,18 @@ namespace WebCore {
class RTCDataChannelEvent : public Event {
public:
- virtual ~RTCDataChannelEvent();
+ static Ref<RTCDataChannelEvent> create(const AtomicString& type, bool canBubble, bool cancelable, Ref<RTCDataChannel>&&);
- static PassRefPtr<RTCDataChannelEvent> create();
- static PassRefPtr<RTCDataChannelEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<RTCDataChannel>);
-
- RTCDataChannel* channel() const;
+ RTCDataChannel* channel();
virtual EventInterface eventInterface() const;
private:
- RTCDataChannelEvent();
- RTCDataChannelEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<RTCDataChannel>);
+ RTCDataChannelEvent(const AtomicString& type, bool canBubble, bool cancelable, Ref<RTCDataChannel>&&);
- RefPtr<RTCDataChannel> m_channel;
+ Ref<RTCDataChannel> m_channel;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCDataChannelEvent_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.idl b/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.idl
index 946337594..1dc11f986 100644
--- a/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.idl
+++ b/Source/WebCore/Modules/mediastream/RTCDataChannelEvent.idl
@@ -24,7 +24,7 @@
[
NoInterfaceObject,
- Conditional=MEDIA_STREAM,
+ Conditional=WEB_RTC,
] interface RTCDataChannelEvent : Event {
readonly attribute RTCDataChannel channel;
};
diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp b/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp
index 353e309dd..2c7e0d364 100644
--- a/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp
+++ b/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2015, 2016 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,84 +31,34 @@
*/
#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
#include "RTCIceCandidate.h"
-#include "Dictionary.h"
+#if ENABLE(WEB_RTC)
+
#include "ExceptionCode.h"
-#include "RTCIceCandidateDescriptor.h"
namespace WebCore {
-PassRefPtr<RTCIceCandidate> RTCIceCandidate::create(const Dictionary& dictionary, ExceptionCode& ec)
-{
- String candidate;
- bool ok = dictionary.get("candidate", candidate);
- if (ok && candidate.isEmpty()) {
- ec = TYPE_MISMATCH_ERR;
- return nullptr;
- }
-
- String sdpMid;
- ok = dictionary.get("sdpMid", sdpMid);
- if (ok && sdpMid.isEmpty()) {
- ec = TYPE_MISMATCH_ERR;
- return nullptr;
- }
-
- String tempLineIndex;
- unsigned short sdpMLineIndex = 0;
- // First we check if the property exists in the Dictionary.
- ok = dictionary.get("sdpMLineIndex", tempLineIndex);
- // Then we try to convert it to a number and check if it was successful.
- if (ok) {
- bool intConversionOk;
- sdpMLineIndex = tempLineIndex.toUIntStrict(&intConversionOk);
- if (!intConversionOk) {
- ec = TYPE_MISMATCH_ERR;
- return nullptr;
- }
- }
-
- return adoptRef(new RTCIceCandidate(RTCIceCandidateDescriptor::create(candidate, sdpMid, sdpMLineIndex)));
-}
-
-PassRefPtr<RTCIceCandidate> RTCIceCandidate::create(PassRefPtr<RTCIceCandidateDescriptor> descriptor)
-{
- return adoptRef(new RTCIceCandidate(descriptor));
-}
-
-RTCIceCandidate::RTCIceCandidate(PassRefPtr<RTCIceCandidateDescriptor> descriptor)
- : m_descriptor(descriptor)
-{
-}
-
-RTCIceCandidate::~RTCIceCandidate()
-{
-}
-
-const String& RTCIceCandidate::candidate() const
-{
- return m_descriptor->candidate();
-}
-
-const String& RTCIceCandidate::sdpMid() const
+inline RTCIceCandidate::RTCIceCandidate(const String& candidate, const String& sdpMid, std::optional<unsigned short> sdpMLineIndex)
+ : m_candidate(candidate)
+ , m_sdpMid(sdpMid)
+ , m_sdpMLineIndex(sdpMLineIndex)
{
- return m_descriptor->sdpMid();
+ ASSERT(!sdpMid.isNull() || sdpMLineIndex);
}
-unsigned short RTCIceCandidate::sdpMLineIndex() const
+ExceptionOr<Ref<RTCIceCandidate>> RTCIceCandidate::create(const Init& dictionary)
{
- return m_descriptor->sdpMLineIndex();
+ if (dictionary.sdpMid.isNull() && !dictionary.sdpMLineIndex)
+ return Exception { TypeError };
+ return create(dictionary.candidate, dictionary.sdpMid, dictionary.sdpMLineIndex);
}
-RTCIceCandidateDescriptor* RTCIceCandidate::descriptor()
+Ref<RTCIceCandidate> RTCIceCandidate::create(const String& candidate, const String& sdpMid, std::optional<unsigned short> sdpMLineIndex)
{
- return m_descriptor.get();
+ return adoptRef(*new RTCIceCandidate(candidate, sdpMid, sdpMLineIndex));
}
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidate.h b/Source/WebCore/Modules/mediastream/RTCIceCandidate.h
index 0dad25c27..2c665491d 100644
--- a/Source/WebCore/Modules/mediastream/RTCIceCandidate.h
+++ b/Source/WebCore/Modules/mediastream/RTCIceCandidate.h
@@ -28,43 +28,38 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCIceCandidate_h
-#define RTCIceCandidate_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
-#include "ExceptionBase.h"
+#include "ExceptionOr.h"
#include "ScriptWrappable.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/WTFString.h>
namespace WebCore {
-class Dictionary;
-class RTCIceCandidateDescriptor;
-
class RTCIceCandidate : public RefCounted<RTCIceCandidate>, public ScriptWrappable {
public:
- static PassRefPtr<RTCIceCandidate> create(const Dictionary&, ExceptionCode&);
- static PassRefPtr<RTCIceCandidate> create(PassRefPtr<RTCIceCandidateDescriptor>);
- virtual ~RTCIceCandidate();
+ struct Init {
+ String candidate;
+ String sdpMid;
+ std::optional<unsigned short> sdpMLineIndex;
+ };
- const String& candidate() const;
- const String& sdpMid() const;
- unsigned short sdpMLineIndex() const;
+ static ExceptionOr<Ref<RTCIceCandidate>> create(const Init&);
+ static Ref<RTCIceCandidate> create(const String& candidate, const String& sdpMid, std::optional<unsigned short> sdpMLineIndex);
- RTCIceCandidateDescriptor* descriptor();
+ const String& candidate() const { return m_candidate; }
+ const String& sdpMid() const { return m_sdpMid; }
+ std::optional<unsigned short> sdpMLineIndex() const { return m_sdpMLineIndex; }
private:
- explicit RTCIceCandidate(PassRefPtr<RTCIceCandidateDescriptor>);
+ RTCIceCandidate(const String& candidate, const String& sdpMid, std::optional<unsigned short> sdpMLineIndex);
- RefPtr<RTCIceCandidateDescriptor> m_descriptor;
+ String m_candidate;
+ String m_sdpMid;
+ std::optional<unsigned short> m_sdpMLineIndex;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCIceCandidate_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidate.idl b/Source/WebCore/Modules/mediastream/RTCIceCandidate.idl
index 4fb49586d..49c74e15c 100644
--- a/Source/WebCore/Modules/mediastream/RTCIceCandidate.idl
+++ b/Source/WebCore/Modules/mediastream/RTCIceCandidate.idl
@@ -30,12 +30,23 @@
*/
[
- Conditional=MEDIA_STREAM,
- CustomConstructor(optional Dictionary dictionary),
- ConstructorRaisesException
+ Conditional=WEB_RTC,
+ Constructor(RTCIceCandidateInit candidateInitDict),
+ ConstructorMayThrowException,
+ EnabledAtRuntime=PeerConnection,
+ ImplementationLacksVTable,
+ PrivateIdentifier,
+ PublicIdentifier
] interface RTCIceCandidate {
readonly attribute DOMString candidate;
- readonly attribute DOMString sdpMid;
- readonly attribute unsigned short sdpMLineIndex;
+ readonly attribute DOMString? sdpMid;
+ readonly attribute unsigned short? sdpMLineIndex;
+
+ serializer = {candidate, sdpMid, sdpMLineIndex};
};
+dictionary RTCIceCandidateInit {
+ required DOMString candidate;
+ DOMString? sdpMid = null;
+ unsigned short? sdpMLineIndex = null;
+};
diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.cpp b/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.cpp
index 1c28e58e2..ba62fbbe1 100644
--- a/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.cpp
+++ b/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.cpp
@@ -24,7 +24,7 @@
#include "config.h"
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include "RTCIceCandidateEvent.h"
@@ -33,23 +33,14 @@
namespace WebCore {
-PassRefPtr<RTCIceCandidateEvent> RTCIceCandidateEvent::create()
+Ref<RTCIceCandidateEvent> RTCIceCandidateEvent::create(bool canBubble, bool cancelable, RefPtr<RTCIceCandidate>&& candidate)
{
- return adoptRef(new RTCIceCandidateEvent);
+ return adoptRef(*new RTCIceCandidateEvent(canBubble, cancelable, WTFMove(candidate)));
}
-PassRefPtr<RTCIceCandidateEvent> RTCIceCandidateEvent::create(bool canBubble, bool cancelable, PassRefPtr<RTCIceCandidate> candidate)
-{
- return adoptRef(new RTCIceCandidateEvent(canBubble, cancelable, candidate));
-}
-
-RTCIceCandidateEvent::RTCIceCandidateEvent()
-{
-}
-
-RTCIceCandidateEvent::RTCIceCandidateEvent(bool canBubble, bool cancelable, PassRefPtr<RTCIceCandidate> candidate)
+RTCIceCandidateEvent::RTCIceCandidateEvent(bool canBubble, bool cancelable, RefPtr<RTCIceCandidate>&& candidate)
: Event(eventNames().icecandidateEvent, canBubble, cancelable)
- , m_candidate(candidate)
+ , m_candidate(WTFMove(candidate))
{
}
@@ -69,5 +60,5 @@ EventInterface RTCIceCandidateEvent::eventInterface() const
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.h b/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.h
index 466636831..8d371d4ab 100644
--- a/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.h
+++ b/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.h
@@ -22,10 +22,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCIceCandidateEvent_h
-#define RTCIceCandidateEvent_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include "Event.h"
#include <wtf/text/AtomicString.h>
@@ -37,22 +36,18 @@ class RTCIceCandidateEvent : public Event {
public:
virtual ~RTCIceCandidateEvent();
- static PassRefPtr<RTCIceCandidateEvent> create();
- static PassRefPtr<RTCIceCandidateEvent> create(bool canBubble, bool cancelable, PassRefPtr<RTCIceCandidate>);
+ static Ref<RTCIceCandidateEvent> create(bool canBubble, bool cancelable, RefPtr<RTCIceCandidate>&&);
RTCIceCandidate* candidate() const;
virtual EventInterface eventInterface() const;
private:
- RTCIceCandidateEvent();
- RTCIceCandidateEvent(bool canBubble, bool cancelable, PassRefPtr<RTCIceCandidate>);
+ RTCIceCandidateEvent(bool canBubble, bool cancelable, RefPtr<RTCIceCandidate>&&);
RefPtr<RTCIceCandidate> m_candidate;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCIceCandidateEvent_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.idl b/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.idl
index 3fa06379d..ff00d5bd2 100644
--- a/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.idl
+++ b/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.idl
@@ -24,7 +24,7 @@
[
NoInterfaceObject,
- Conditional=MEDIA_STREAM,
+ Conditional=WEB_RTC,
] interface RTCIceCandidateEvent : Event {
readonly attribute RTCIceCandidate candidate;
};
diff --git a/Source/WebCore/Modules/mediastream/VideoStreamTrack.idl b/Source/WebCore/Modules/mediastream/RTCIceServer.h
index 65c763d79..b0b1798ea 100644
--- a/Source/WebCore/Modules/mediastream/VideoStreamTrack.idl
+++ b/Source/WebCore/Modules/mediastream/RTCIceServer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -23,10 +23,22 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- Conditional=MEDIA_STREAM,
- ConstructorCallWith=ScriptExecutionContext,
- Constructor(optional Dictionary videoConstraints),
-] interface VideoStreamTrack : MediaStreamTrack {
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include <wtf/Variant.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+struct RTCIceServer {
+ Variant<String, Vector<String>> urls;
+ String credential;
+ String username;
};
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/MediaTrackConstraint.idl b/Source/WebCore/Modules/mediastream/RTCIceServer.idl
index 54af7b920..b2529c664 100644
--- a/Source/WebCore/Modules/mediastream/MediaTrackConstraint.idl
+++ b/Source/WebCore/Modules/mediastream/RTCIceServer.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -24,8 +24,10 @@
*/
[
- Conditional=MEDIA_STREAM,
- NoInterfaceObject,
-] interface MediaTrackConstraint {
+ Conditional=WEB_RTC,
+ JSGenerateToJSObject,
+] dictionary RTCIceServer {
+ required (DOMString or sequence<DOMString>) urls;
+ DOMString username;
+ DOMString credential;
};
-
diff --git a/Source/WebCore/Modules/mediastream/RTCIceTransport.h b/Source/WebCore/Modules/mediastream/RTCIceTransport.h
new file mode 100644
index 000000000..45cf7ed84
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCIceTransport.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "PeerConnectionStates.h"
+#include "ScriptWrappable.h"
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class RTCIceTransport : public RefCounted<RTCIceTransport>, public ScriptWrappable {
+public:
+
+ using TransportState = PeerConnectionStates::IceTransportState;
+ using GatheringState = PeerConnectionStates::IceGatheringState;
+
+ static Ref<RTCIceTransport> create()
+ {
+ return adoptRef(*new RTCIceTransport());
+ }
+ virtual ~RTCIceTransport() { }
+
+ TransportState transportState() const { return m_transportState; }
+ void setTransportState(TransportState state) { m_transportState = state; }
+
+ GatheringState gatheringState() const { return m_gatheringState; }
+ void setGatheringState(GatheringState state) { m_gatheringState = state; }
+
+private:
+ RTCIceTransport() { };
+
+ TransportState m_transportState { TransportState::New };
+ GatheringState m_gatheringState { GatheringState::New };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesCallback.h b/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.h
index fcee4df8a..f42af80c3 100644
--- a/Source/WebCore/Modules/mediastream/MediaStreamTrackSourcesCallback.h
+++ b/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -23,24 +24,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaStreamTrackSourcesCallback_h
-#define MediaStreamTrackSourcesCallback_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
-
-#include "SourceInfo.h"
-#include <wtf/RefCounted.h>
+#if ENABLE(WEB_RTC)
namespace WebCore {
-class MediaStreamTrackSourcesCallback : public RefCounted<MediaStreamTrackSourcesCallback> {
-public:
- virtual ~MediaStreamTrackSourcesCallback() { }
- virtual bool handleEvent(Vector<RefPtr<SourceInfo>>) = 0;
+struct RTCOfferAnswerOptions {
+ bool voiceActivityDetection { true };
};
-} // namespace WebCore
+struct RTCOfferOptions : RTCOfferAnswerOptions {
+ int64_t offerToReceiveVideo { 0 };
+ int64_t offerToReceiveAudio { 0 };
+ bool iceRestart { false };
+};
-#endif
+struct RTCAnswerOptions : RTCOfferAnswerOptions {
+};
+
+} // namespace WebCore
-#endif // MediaStreamTrackSourcesCallback_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp
index bb895c92f..8e4dcb113 100644
--- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp
+++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2015, 2016 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,335 +31,278 @@
*/
#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
#include "RTCPeerConnection.h"
-#include "ArrayValue.h"
+#if ENABLE(WEB_RTC)
+
#include "Document.h"
#include "Event.h"
-#include "ExceptionCode.h"
+#include "EventNames.h"
#include "Frame.h"
-#include "FrameLoader.h"
-#include "FrameLoaderClient.h"
-#include "MediaConstraintsImpl.h"
-#include "MediaStreamEvent.h"
+#include "MediaEndpointConfiguration.h"
+#include "MediaStream.h"
+#include "MediaStreamTrack.h"
#include "RTCConfiguration.h"
-#include "RTCDTMFSender.h"
#include "RTCDataChannel.h"
-#include "RTCDataChannelEvent.h"
-#include "RTCDataChannelHandler.h"
#include "RTCIceCandidate.h"
-#include "RTCIceCandidateDescriptor.h"
#include "RTCIceCandidateEvent.h"
-#include "RTCPeerConnectionErrorCallback.h"
+#include "RTCOfferAnswerOptions.h"
#include "RTCSessionDescription.h"
-#include "RTCSessionDescriptionCallback.h"
-#include "RTCSessionDescriptionDescriptor.h"
-#include "RTCSessionDescriptionRequestImpl.h"
-#include "RTCStatsCallback.h"
-#include "RTCStatsRequestImpl.h"
-#include "RTCVoidRequestImpl.h"
-#include "ScriptExecutionContext.h"
-#include "VoidCallback.h"
-#include <wtf/Functional.h>
+#include "RTCTrackEvent.h"
+#include "UUID.h"
#include <wtf/MainThread.h>
+#include <wtf/text/Base64.h>
namespace WebCore {
-PassRefPtr<RTCConfiguration> RTCPeerConnection::parseConfiguration(const Dictionary& configuration, ExceptionCode& ec)
-{
- if (configuration.isUndefinedOrNull())
- return nullptr;
-
- ArrayValue iceServers;
- bool ok = configuration.get("iceServers", iceServers);
- if (!ok || iceServers.isUndefinedOrNull()) {
- ec = TYPE_MISMATCH_ERR;
- return nullptr;
- }
+using namespace PeerConnection;
+using namespace PeerConnectionStates;
- size_t numberOfServers;
- ok = iceServers.length(numberOfServers);
- if (!ok) {
- ec = TYPE_MISMATCH_ERR;
- return nullptr;
- }
+Ref<RTCPeerConnection> RTCPeerConnection::create(ScriptExecutionContext& context)
+{
+ Ref<RTCPeerConnection> peerConnection = adoptRef(*new RTCPeerConnection(context));
+ peerConnection->suspendIfNeeded();
- RefPtr<RTCConfiguration> rtcConfiguration = RTCConfiguration::create();
+ return peerConnection;
+}
- for (size_t i = 0; i < numberOfServers; ++i) {
- Dictionary iceServer;
- ok = iceServers.get(i, iceServer);
- if (!ok) {
- ec = TYPE_MISMATCH_ERR;
- return nullptr;
- }
+RTCPeerConnection::RTCPeerConnection(ScriptExecutionContext& context)
+ : ActiveDOMObject(&context)
+ , m_backend(PeerConnectionBackend::create(*this))
+{
+}
- String urlString, credential, username;
- ok = iceServer.get("url", urlString);
- if (!ok) {
- ec = TYPE_MISMATCH_ERR;
- return nullptr;
- }
- URL url(URL(), urlString);
- if (!url.isValid() || !(url.protocolIs("turn") || url.protocolIs("stun"))) {
- ec = TYPE_MISMATCH_ERR;
- return nullptr;
- }
+RTCPeerConnection::~RTCPeerConnection()
+{
+ stop();
+}
- iceServer.get("credential", credential);
- iceServer.get("username", username);
+ExceptionOr<void> RTCPeerConnection::initializeWith(Document& document, RTCConfiguration&& configuration)
+{
+ if (!document.frame())
+ return Exception { NOT_SUPPORTED_ERR };
- rtcConfiguration->appendServer(RTCIceServer::create(url, credential, username));
- }
+ if (!m_backend)
+ return Exception { NOT_SUPPORTED_ERR };
- return rtcConfiguration.release();
+ return setConfiguration(WTFMove(configuration));
}
-PassRefPtr<RTCPeerConnection> RTCPeerConnection::create(ScriptExecutionContext& context, const Dictionary& rtcConfiguration, const Dictionary& mediaConstraints, ExceptionCode& ec)
+ExceptionOr<Ref<RTCRtpSender>> RTCPeerConnection::addTrack(Ref<MediaStreamTrack>&& track, const Vector<std::reference_wrapper<MediaStream>>& streams)
{
- RefPtr<RTCConfiguration> configuration = parseConfiguration(rtcConfiguration, ec);
- if (ec)
- return nullptr;
+ if (m_signalingState == SignalingState::Closed)
+ return Exception { INVALID_STATE_ERR };
- RefPtr<MediaConstraints> constraints = MediaConstraintsImpl::create(mediaConstraints, ec);
- if (ec)
- return nullptr;
+ // Require at least one stream until https://github.com/w3c/webrtc-pc/issues/288 is resolved
+ if (!streams.size())
+ return Exception { NOT_SUPPORTED_ERR };
- RefPtr<RTCPeerConnection> peerConnection = adoptRef(new RTCPeerConnection(context, configuration.release(), constraints.release(), ec));
- peerConnection->suspendIfNeeded();
- if (ec)
- return nullptr;
+ for (RTCRtpSender& sender : m_transceiverSet->senders()) {
+ if (sender.trackId() == track->id())
+ return Exception { INVALID_ACCESS_ERR };
+ }
- return peerConnection.release();
-}
+ Vector<String> mediaStreamIds;
+ for (auto stream : streams)
+ mediaStreamIds.append(stream.get().id());
-RTCPeerConnection::RTCPeerConnection(ScriptExecutionContext& context, PassRefPtr<RTCConfiguration> configuration, PassRefPtr<MediaConstraints> constraints, ExceptionCode& ec)
- : ActiveDOMObject(&context)
- , m_signalingState(SignalingStateStable)
- , m_iceGatheringState(IceGatheringStateNew)
- , m_iceConnectionState(IceConnectionStateNew)
- , m_scheduledEventTimer(this, &RTCPeerConnection::scheduledEventTimerFired)
- , m_stopped(false)
-{
- Document& document = toDocument(context);
+ RTCRtpSender* sender = nullptr;
- if (!document.frame()) {
- ec = NOT_SUPPORTED_ERR;
- return;
+ // Reuse an existing sender with the same track kind if it has never been used to send before.
+ for (auto& transceiver : m_transceiverSet->list()) {
+ auto& existingSender = transceiver->sender();
+ if (existingSender.trackKind() == track->kind() && existingSender.trackId().isNull() && !transceiver->hasSendingDirection()) {
+ existingSender.setTrack(WTFMove(track));
+ existingSender.setMediaStreamIds(WTFMove(mediaStreamIds));
+ transceiver->enableSendingDirection();
+ sender = &existingSender;
+ break;
+ }
}
- m_peerHandler = RTCPeerConnectionHandler::create(this);
- if (!m_peerHandler) {
- ec = NOT_SUPPORTED_ERR;
- return;
- }
+ if (!sender) {
+ String transceiverMid = RTCRtpTransceiver::getNextMid();
+ const String& trackKind = track->kind();
+ String trackId = createCanonicalUUIDString();
- document.frame()->loader().client().dispatchWillStartUsingPeerConnectionHandler(m_peerHandler.get());
+ auto newSender = RTCRtpSender::create(WTFMove(track), WTFMove(mediaStreamIds), *this);
+ auto receiver = m_backend->createReceiver(transceiverMid, trackKind, trackId);
+ auto transceiver = RTCRtpTransceiver::create(WTFMove(newSender), WTFMove(receiver));
- if (!m_peerHandler->initialize(configuration, constraints)) {
- ec = NOT_SUPPORTED_ERR;
- return;
+ // This transceiver is not yet associated with an m-line (null mid), but we need a
+ // provisional mid if the transceiver is used to create an offer.
+ transceiver->setProvisionalMid(transceiverMid);
+
+ sender = &transceiver->sender();
+ m_transceiverSet->append(WTFMove(transceiver));
}
-}
-RTCPeerConnection::~RTCPeerConnection()
-{
- stop();
+ m_backend->markAsNeedingNegotiation();
- for (auto stream = m_localStreams.begin(), end = m_localStreams.end(); stream != end; ++stream)
- (*stream)->removeObserver(this);
+ return Ref<RTCRtpSender> { *sender };
}
-void RTCPeerConnection::createOffer(PassRefPtr<RTCSessionDescriptionCallback> successCallback, PassRefPtr<RTCPeerConnectionErrorCallback> errorCallback, const Dictionary& mediaConstraints, ExceptionCode& ec)
+ExceptionOr<void> RTCPeerConnection::removeTrack(RTCRtpSender& sender)
{
- if (m_signalingState == SignalingStateClosed) {
- ec = INVALID_STATE_ERR;
- return;
- }
+ if (m_signalingState == SignalingState::Closed)
+ return Exception { INVALID_STATE_ERR };
- if (!successCallback) {
- ec = TYPE_MISMATCH_ERR;
- return;
+ bool shouldAbort = true;
+ for (RTCRtpSender& senderInSet : m_transceiverSet->senders()) {
+ if (&senderInSet == &sender) {
+ shouldAbort = sender.isStopped();
+ break;
+ }
}
+ if (shouldAbort)
+ return { };
- RefPtr<MediaConstraints> constraints = MediaConstraintsImpl::create(mediaConstraints, ec);
- if (ec)
- return;
+ sender.stop();
- RefPtr<RTCSessionDescriptionRequestImpl> request = RTCSessionDescriptionRequestImpl::create(scriptExecutionContext(), successCallback, errorCallback);
- m_peerHandler->createOffer(request.release(), constraints);
+ m_backend->markAsNeedingNegotiation();
+ return { };
}
-void RTCPeerConnection::createAnswer(PassRefPtr<RTCSessionDescriptionCallback> successCallback, PassRefPtr<RTCPeerConnectionErrorCallback> errorCallback, const Dictionary& mediaConstraints, ExceptionCode& ec)
+ExceptionOr<Ref<RTCRtpTransceiver>> RTCPeerConnection::addTransceiver(Ref<MediaStreamTrack>&& track, const RtpTransceiverInit& init)
{
- if (m_signalingState == SignalingStateClosed) {
- ec = INVALID_STATE_ERR;
- return;
- }
+ if (m_signalingState == SignalingState::Closed)
+ return Exception { INVALID_STATE_ERR };
- if (!successCallback) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
+ String transceiverMid = RTCRtpTransceiver::getNextMid();
+ const String& trackKind = track->kind();
+ const String& trackId = track->id();
- RefPtr<MediaConstraints> constraints = MediaConstraintsImpl::create(mediaConstraints, ec);
- if (ec)
- return;
+ auto sender = RTCRtpSender::create(WTFMove(track), Vector<String>(), *this);
+ auto receiver = m_backend->createReceiver(transceiverMid, trackKind, trackId);
+ auto transceiver = RTCRtpTransceiver::create(WTFMove(sender), WTFMove(receiver));
+ transceiver->setProvisionalMid(transceiverMid);
- RefPtr<RTCSessionDescriptionRequestImpl> request = RTCSessionDescriptionRequestImpl::create(scriptExecutionContext(), successCallback, errorCallback);
- m_peerHandler->createAnswer(request.release(), constraints.release());
+ completeAddTransceiver(transceiver, init);
+ return WTFMove(transceiver);
}
-bool RTCPeerConnection::checkStateForLocalDescription(RTCSessionDescription* localDescription)
+ExceptionOr<Ref<RTCRtpTransceiver>> RTCPeerConnection::addTransceiver(const String& kind, const RtpTransceiverInit& init)
{
- if (localDescription->type() == "offer")
- return m_signalingState == SignalingStateStable || m_signalingState == SignalingStateHaveLocalOffer;
- if (localDescription->type() == "answer")
- return m_signalingState == SignalingStateHaveRemoteOffer || m_signalingState == SignalingStateHaveLocalPrAnswer;
- if (localDescription->type() == "pranswer")
- return m_signalingState == SignalingStateHaveLocalPrAnswer || m_signalingState == SignalingStateHaveRemoteOffer;
+ if (m_signalingState == SignalingState::Closed)
+ return Exception { INVALID_STATE_ERR };
- return false;
-}
+ if (kind != "audio" && kind != "video")
+ return Exception { TypeError };
-bool RTCPeerConnection::checkStateForRemoteDescription(RTCSessionDescription* remoteDescription)
-{
- if (remoteDescription->type() == "offer")
- return m_signalingState == SignalingStateStable || m_signalingState == SignalingStateHaveRemoteOffer;
- if (remoteDescription->type() == "answer")
- return m_signalingState == SignalingStateHaveLocalOffer || m_signalingState == SignalingStateHaveRemotePrAnswer;
- if (remoteDescription->type() == "pranswer")
- return m_signalingState == SignalingStateHaveRemotePrAnswer || m_signalingState == SignalingStateHaveLocalOffer;
+ String transceiverMid = RTCRtpTransceiver::getNextMid();
+ String trackId = createCanonicalUUIDString();
- return false;
+ auto sender = RTCRtpSender::create(kind, Vector<String>(), *this);
+ auto receiver = m_backend->createReceiver(transceiverMid, kind, trackId);
+ auto transceiver = RTCRtpTransceiver::create(WTFMove(sender), WTFMove(receiver));
+ transceiver->setProvisionalMid(transceiverMid);
+
+ completeAddTransceiver(transceiver, init);
+ return WTFMove(transceiver);
}
-void RTCPeerConnection::setLocalDescription(PassRefPtr<RTCSessionDescription> prpSessionDescription, PassRefPtr<VoidCallback> successCallback, PassRefPtr<RTCPeerConnectionErrorCallback> errorCallback, ExceptionCode& ec)
+void RTCPeerConnection::completeAddTransceiver(RTCRtpTransceiver& transceiver, const RtpTransceiverInit& init)
{
- if (m_signalingState == SignalingStateClosed) {
- ec = INVALID_STATE_ERR;
- return;
- }
+ transceiver.setDirection(static_cast<RTCRtpTransceiver::Direction>(init.direction));
- RefPtr<RTCSessionDescription> sessionDescription = prpSessionDescription;
- if (!sessionDescription) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
+ m_transceiverSet->append(transceiver);
+ m_backend->markAsNeedingNegotiation();
+}
- if (!checkStateForLocalDescription(sessionDescription.get())) {
- RefPtr<DOMError> error = DOMError::create(RTCPeerConnectionHandler::invalidSessionDescriptionErrorName());
- callOnMainThread(bind(&RTCPeerConnectionErrorCallback::handleEvent, errorCallback.get(), error.release()));
+void RTCPeerConnection::queuedCreateOffer(RTCOfferOptions&& options, SessionDescriptionPromise&& promise)
+{
+ if (m_signalingState == SignalingState::Closed) {
+ promise.reject(INVALID_STATE_ERR);
return;
}
- RefPtr<RTCVoidRequestImpl> request = RTCVoidRequestImpl::create(scriptExecutionContext(), successCallback, errorCallback);
- m_peerHandler->setLocalDescription(request.release(), sessionDescription->descriptor());
+ m_backend->createOffer(WTFMove(options), WTFMove(promise));
}
-PassRefPtr<RTCSessionDescription> RTCPeerConnection::localDescription(ExceptionCode& ec)
+void RTCPeerConnection::queuedCreateAnswer(RTCAnswerOptions&& options, SessionDescriptionPromise&& promise)
{
- RefPtr<RTCSessionDescriptionDescriptor> descriptor = m_peerHandler->localDescription();
- if (!descriptor) {
- ec = INVALID_STATE_ERR;
- return nullptr;
+ if (m_signalingState == SignalingState::Closed) {
+ promise.reject(INVALID_STATE_ERR);
+ return;
}
- RefPtr<RTCSessionDescription> sessionDescription = RTCSessionDescription::create(descriptor.release());
- return sessionDescription.release();
+ m_backend->createAnswer(WTFMove(options), WTFMove(promise));
}
-void RTCPeerConnection::setRemoteDescription(PassRefPtr<RTCSessionDescription> prpSessionDescription, PassRefPtr<VoidCallback> successCallback, PassRefPtr<RTCPeerConnectionErrorCallback> errorCallback, ExceptionCode& ec)
+void RTCPeerConnection::queuedSetLocalDescription(RTCSessionDescription& description, DOMPromise<void>&& promise)
{
- if (m_signalingState == SignalingStateClosed) {
- ec = INVALID_STATE_ERR;
+ if (m_signalingState == SignalingState::Closed) {
+ promise.reject(INVALID_STATE_ERR);
return;
}
- RefPtr<RTCSessionDescription> sessionDescription = prpSessionDescription;
- if (!sessionDescription) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
-
- if (!checkStateForRemoteDescription(sessionDescription.get())) {
- RefPtr<DOMError> error = DOMError::create(RTCPeerConnectionHandler::invalidSessionDescriptionErrorName());
- callOnMainThread(bind(&RTCPeerConnectionErrorCallback::handleEvent, errorCallback.get(), error.release()));
- return;
- }
+ m_backend->setLocalDescription(description, WTFMove(promise));
+}
- RefPtr<RTCVoidRequestImpl> request = RTCVoidRequestImpl::create(scriptExecutionContext(), successCallback, errorCallback);
- m_peerHandler->setRemoteDescription(request.release(), sessionDescription->descriptor());
+RefPtr<RTCSessionDescription> RTCPeerConnection::localDescription() const
+{
+ return m_backend->localDescription();
}
-PassRefPtr<RTCSessionDescription> RTCPeerConnection::remoteDescription(ExceptionCode& ec)
+RefPtr<RTCSessionDescription> RTCPeerConnection::currentLocalDescription() const
{
- RefPtr<RTCSessionDescriptionDescriptor> descriptor = m_peerHandler->remoteDescription();
- if (!descriptor) {
- ec = INVALID_STATE_ERR;
- return nullptr;
- }
+ return m_backend->currentLocalDescription();
+}
- RefPtr<RTCSessionDescription> desc = RTCSessionDescription::create(descriptor.release());
- return desc.release();
+RefPtr<RTCSessionDescription> RTCPeerConnection::pendingLocalDescription() const
+{
+ return m_backend->pendingLocalDescription();
}
-void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, const Dictionary& mediaConstraints, ExceptionCode& ec)
+void RTCPeerConnection::queuedSetRemoteDescription(RTCSessionDescription& description, DOMPromise<void>&& promise)
{
- if (m_signalingState == SignalingStateClosed) {
- ec = INVALID_STATE_ERR;
+ if (m_signalingState == SignalingState::Closed) {
+ promise.reject(INVALID_STATE_ERR);
return;
}
- RefPtr<RTCConfiguration> configuration = parseConfiguration(rtcConfiguration, ec);
- if (ec)
- return;
+ m_backend->setRemoteDescription(description, WTFMove(promise));
+}
- RefPtr<MediaConstraints> constraints = MediaConstraintsImpl::create(mediaConstraints, ec);
- if (ec)
- return;
+RefPtr<RTCSessionDescription> RTCPeerConnection::remoteDescription() const
+{
+ return m_backend->remoteDescription();
+}
- bool valid = m_peerHandler->updateIce(configuration, constraints);
- if (!valid)
- ec = SYNTAX_ERR;
+RefPtr<RTCSessionDescription> RTCPeerConnection::currentRemoteDescription() const
+{
+ return m_backend->currentRemoteDescription();
}
-void RTCPeerConnection::addIceCandidate(RTCIceCandidate* iceCandidate, PassRefPtr<VoidCallback> successCallback, PassRefPtr<RTCPeerConnectionErrorCallback> errorCallback, ExceptionCode& ec)
+RefPtr<RTCSessionDescription> RTCPeerConnection::pendingRemoteDescription() const
{
- if (m_signalingState == SignalingStateClosed) {
- ec = INVALID_STATE_ERR;
- return;
- }
+ return m_backend->pendingRemoteDescription();
+}
- if (!iceCandidate || !successCallback || !errorCallback) {
- ec = TYPE_MISMATCH_ERR;
+void RTCPeerConnection::queuedAddIceCandidate(RTCIceCandidate& rtcCandidate, DOMPromise<void>&& promise)
+{
+ if (m_signalingState == SignalingState::Closed) {
+ promise.reject(INVALID_STATE_ERR);
return;
}
- RefPtr<RTCVoidRequestImpl> request = RTCVoidRequestImpl::create(scriptExecutionContext(), successCallback, errorCallback);
-
- bool implemented = m_peerHandler->addIceCandidate(request.release(), iceCandidate->descriptor());
- if (!implemented)
- ec = SYNTAX_ERR;
+ m_backend->addIceCandidate(rtcCandidate, WTFMove(promise));
}
String RTCPeerConnection::signalingState() const
{
switch (m_signalingState) {
- case SignalingStateStable:
+ case SignalingState::Stable:
return ASCIILiteral("stable");
- case SignalingStateHaveLocalOffer:
+ case SignalingState::HaveLocalOffer:
return ASCIILiteral("have-local-offer");
- case SignalingStateHaveRemoteOffer:
+ case SignalingState::HaveRemoteOffer:
return ASCIILiteral("have-remote-offer");
- case SignalingStateHaveLocalPrAnswer:
+ case SignalingState::HaveLocalPrAnswer:
return ASCIILiteral("have-local-pranswer");
- case SignalingStateHaveRemotePrAnswer:
+ case SignalingState::HaveRemotePrAnswer:
return ASCIILiteral("have-remote-pranswer");
- case SignalingStateClosed:
+ case SignalingState::Closed:
return ASCIILiteral("closed");
}
@@ -369,11 +313,11 @@ String RTCPeerConnection::signalingState() const
String RTCPeerConnection::iceGatheringState() const
{
switch (m_iceGatheringState) {
- case IceGatheringStateNew:
+ case IceGatheringState::New:
return ASCIILiteral("new");
- case IceGatheringStateGathering:
+ case IceGatheringState::Gathering:
return ASCIILiteral("gathering");
- case IceGatheringStateComplete:
+ case IceGatheringState::Complete:
return ASCIILiteral("complete");
}
@@ -384,19 +328,19 @@ String RTCPeerConnection::iceGatheringState() const
String RTCPeerConnection::iceConnectionState() const
{
switch (m_iceConnectionState) {
- case IceConnectionStateNew:
+ case IceConnectionState::New:
return ASCIILiteral("new");
- case IceConnectionStateChecking:
+ case IceConnectionState::Checking:
return ASCIILiteral("checking");
- case IceConnectionStateConnected:
+ case IceConnectionState::Connected:
return ASCIILiteral("connected");
- case IceConnectionStateCompleted:
+ case IceConnectionState::Completed:
return ASCIILiteral("completed");
- case IceConnectionStateFailed:
+ case IceConnectionState::Failed:
return ASCIILiteral("failed");
- case IceConnectionStateDisconnected:
+ case IceConnectionState::Disconnected:
return ASCIILiteral("disconnected");
- case IceConnectionStateClosed:
+ case IceConnectionState::Closed:
return ASCIILiteral("closed");
}
@@ -404,295 +348,145 @@ String RTCPeerConnection::iceConnectionState() const
return String();
}
-void RTCPeerConnection::addStream(PassRefPtr<MediaStream> prpStream, const Dictionary& mediaConstraints, ExceptionCode& ec)
-{
- if (m_signalingState == SignalingStateClosed) {
- ec = INVALID_STATE_ERR;
- return;
- }
-
- RefPtr<MediaStream> stream = prpStream;
- if (!stream) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
-
- if (m_localStreams.contains(stream))
- return;
-
- RefPtr<MediaConstraints> constraints = MediaConstraintsImpl::create(mediaConstraints, ec);
- if (ec)
- return;
-
- bool valid = m_peerHandler->addStream(stream->privateStream(), constraints);
- if (!valid)
- ec = SYNTAX_ERR;
- else {
- m_localStreams.append(stream);
- stream->addObserver(this);
- }
-}
-
-void RTCPeerConnection::removeStream(PassRefPtr<MediaStream> prpStream, ExceptionCode& ec)
-{
- if (m_signalingState == SignalingStateClosed) {
- ec = INVALID_STATE_ERR;
- return;
- }
-
- if (!prpStream) {
- ec = TYPE_MISMATCH_ERR;
- return;
- }
-
- RefPtr<MediaStream> stream = prpStream;
-
- size_t pos = m_localStreams.find(stream);
- if (pos == notFound)
- return;
-
- m_localStreams.remove(pos);
- stream->removeObserver(this);
- m_peerHandler->removeStream(stream->privateStream());
-}
-
-MediaStreamVector RTCPeerConnection::getLocalStreams() const
-{
- return m_localStreams;
-}
-
-MediaStreamVector RTCPeerConnection::getRemoteStreams() const
-{
- return m_remoteStreams;
-}
-
-MediaStream* RTCPeerConnection::getStreamById(const String& streamId)
-{
- for (MediaStreamVector::iterator iter = m_localStreams.begin(); iter != m_localStreams.end(); ++iter) {
- if ((*iter)->id() == streamId)
- return iter->get();
- }
-
- for (MediaStreamVector::iterator iter = m_remoteStreams.begin(); iter != m_remoteStreams.end(); ++iter) {
- if ((*iter)->id() == streamId)
- return iter->get();
+ExceptionOr<void> RTCPeerConnection::setConfiguration(RTCConfiguration&& configuration)
+{
+ if (m_signalingState == SignalingState::Closed)
+ return Exception { INVALID_STATE_ERR };
+
+ Vector<MediaEndpointConfiguration::IceServerInfo> servers;
+ if (configuration.iceServers) {
+ servers.reserveInitialCapacity(configuration.iceServers->size());
+ for (auto& server : configuration.iceServers.value()) {
+ Vector<URL> serverURLs;
+ WTF::switchOn(server.urls,
+ [&serverURLs] (const String& string) {
+ serverURLs.reserveInitialCapacity(1);
+ serverURLs.uncheckedAppend(URL { URL { }, string });
+ },
+ [&serverURLs] (const Vector<String>& vector) {
+ serverURLs.reserveInitialCapacity(vector.size());
+ for (auto& string : vector)
+ serverURLs.uncheckedAppend(URL { URL { }, string });
+ }
+ );
+ for (auto& serverURL : serverURLs) {
+ if (!(serverURL.protocolIs("turn") || serverURL.protocolIs("turns") || serverURL.protocolIs("stun")))
+ return Exception { INVALID_ACCESS_ERR };
+ }
+ servers.uncheckedAppend({ WTFMove(serverURLs), server.credential, server.username });
+ }
}
- return nullptr;
+ m_backend->setConfiguration({ WTFMove(servers), configuration.iceTransportPolicy, configuration.bundlePolicy });
+ m_configuration = WTFMove(configuration);
+ return { };
}
-void RTCPeerConnection::getStats(PassRefPtr<RTCStatsCallback> successCallback, PassRefPtr<MediaStreamTrack> selector)
+void RTCPeerConnection::getStats(MediaStreamTrack* selector, Ref<DeferredPromise>&& promise)
{
- RefPtr<RTCStatsRequestImpl> statsRequest = RTCStatsRequestImpl::create(scriptExecutionContext(), successCallback, selector);
- // FIXME: Add passing selector as part of the statsRequest.
- m_peerHandler->getStats(statsRequest.release());
+ m_backend->getStats(selector, WTFMove(promise));
}
-PassRefPtr<RTCDataChannel> RTCPeerConnection::createDataChannel(String label, const Dictionary& options, ExceptionCode& ec)
+ExceptionOr<Ref<RTCDataChannel>> RTCPeerConnection::createDataChannel(ScriptExecutionContext& context, String&& label, RTCDataChannelInit&& options)
{
- if (m_signalingState == SignalingStateClosed) {
- ec = INVALID_STATE_ERR;
- return nullptr;
- }
+ if (m_signalingState == SignalingState::Closed)
+ return Exception { INVALID_STATE_ERR };
- RefPtr<RTCDataChannel> channel = RTCDataChannel::create(scriptExecutionContext(), m_peerHandler.get(), label, options, ec);
- if (ec)
- return nullptr;
+ // FIXME: Check options
+ auto channelHandler = m_backend->createDataChannelHandler(label, options);
+ if (!channelHandler)
+ return Exception { NOT_SUPPORTED_ERR };
- m_dataChannels.append(channel);
- return channel.release();
+ return RTCDataChannel::create(context, WTFMove(channelHandler), WTFMove(label), WTFMove(options));
}
-bool RTCPeerConnection::hasLocalStreamWithTrackId(const String& trackId)
+void RTCPeerConnection::close()
{
- for (MediaStreamVector::iterator iter = m_localStreams.begin(); iter != m_localStreams.end(); ++iter) {
- if ((*iter)->getTrackById(trackId))
- return true;
- }
- return false;
-}
-
-PassRefPtr<RTCDTMFSender> RTCPeerConnection::createDTMFSender(PassRefPtr<MediaStreamTrack> prpTrack, ExceptionCode& ec)
-{
- if (m_signalingState == SignalingStateClosed) {
- ec = INVALID_STATE_ERR;
- return nullptr;
- }
-
- if (!prpTrack) {
- ec = TypeError;
- return nullptr;
- }
-
- RefPtr<MediaStreamTrack> track = prpTrack;
-
- if (!hasLocalStreamWithTrackId(track->id())) {
- ec = SYNTAX_ERR;
- return nullptr;
- }
-
- RefPtr<RTCDTMFSender> dtmfSender = RTCDTMFSender::create(scriptExecutionContext(), m_peerHandler.get(), track.release(), ec);
- if (ec)
- return nullptr;
- return dtmfSender.release();
-}
-
-void RTCPeerConnection::close(ExceptionCode& ec)
-{
- if (m_signalingState == SignalingStateClosed) {
- ec = INVALID_STATE_ERR;
+ if (m_signalingState == SignalingState::Closed)
return;
- }
- m_peerHandler->stop();
+ m_backend->stop();
- changeIceConnectionState(IceConnectionStateClosed);
- changeIceGatheringState(IceGatheringStateComplete);
- changeSignalingState(SignalingStateClosed);
-}
+ m_iceConnectionState = IceConnectionState::Closed;
+ m_signalingState = SignalingState::Closed;
-void RTCPeerConnection::negotiationNeeded()
-{
- scheduleDispatchEvent(Event::create(eventNames().negotiationneededEvent, false, false));
-}
-
-void RTCPeerConnection::didGenerateIceCandidate(PassRefPtr<RTCIceCandidateDescriptor> iceCandidateDescriptor)
-{
- ASSERT(scriptExecutionContext()->isContextThread());
- if (!iceCandidateDescriptor)
- scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, 0));
- else {
- RefPtr<RTCIceCandidate> iceCandidate = RTCIceCandidate::create(iceCandidateDescriptor);
- scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, iceCandidate.release()));
- }
+ for (RTCRtpSender& sender : m_transceiverSet->senders())
+ sender.stop();
}
-void RTCPeerConnection::didChangeSignalingState(SignalingState newState)
+void RTCPeerConnection::emulatePlatformEvent(const String& action)
{
- ASSERT(scriptExecutionContext()->isContextThread());
- changeSignalingState(newState);
+ m_backend->emulatePlatformEvent(action);
}
-void RTCPeerConnection::didChangeIceGatheringState(IceGatheringState newState)
+void RTCPeerConnection::stop()
{
- ASSERT(scriptExecutionContext()->isContextThread());
- changeIceGatheringState(newState);
+ close();
}
-void RTCPeerConnection::didChangeIceConnectionState(IceConnectionState newState)
+const char* RTCPeerConnection::activeDOMObjectName() const
{
- ASSERT(scriptExecutionContext()->isContextThread());
- changeIceConnectionState(newState);
+ return "RTCPeerConnection";
}
-void RTCPeerConnection::didAddRemoteStream(PassRefPtr<MediaStreamPrivate> privateStream)
+bool RTCPeerConnection::canSuspendForDocumentSuspension() const
{
- ASSERT(scriptExecutionContext()->isContextThread());
-
- if (m_signalingState == SignalingStateClosed)
- return;
-
- RefPtr<MediaStream> stream = MediaStream::create(*scriptExecutionContext(), privateStream);
- m_remoteStreams.append(stream);
-
- scheduleDispatchEvent(MediaStreamEvent::create(eventNames().addstreamEvent, false, false, stream.release()));
+ // FIXME: We should try and do better here.
+ return false;
}
-void RTCPeerConnection::didRemoveRemoteStream(MediaStreamPrivate* privateStream)
+void RTCPeerConnection::addTransceiver(Ref<RTCRtpTransceiver>&& transceiver)
{
- ASSERT(scriptExecutionContext()->isContextThread());
- ASSERT(privateStream->client());
-
- // FIXME: this class shouldn't know that the private stream client is a MediaStream!
- RefPtr<MediaStream> stream = static_cast<MediaStream*>(privateStream->client());
- stream->setEnded();
-
- if (m_signalingState == SignalingStateClosed)
- return;
-
- size_t pos = m_remoteStreams.find(stream);
- ASSERT(pos != notFound);
- m_remoteStreams.remove(pos);
-
- scheduleDispatchEvent(MediaStreamEvent::create(eventNames().removestreamEvent, false, false, stream.release()));
+ m_transceiverSet->append(WTFMove(transceiver));
}
-void RTCPeerConnection::didAddRemoteDataChannel(std::unique_ptr<RTCDataChannelHandler> handler)
+void RTCPeerConnection::setSignalingState(SignalingState newState)
{
- ASSERT(scriptExecutionContext()->isContextThread());
-
- if (m_signalingState == SignalingStateClosed)
- return;
-
- RefPtr<RTCDataChannel> channel = RTCDataChannel::create(scriptExecutionContext(), std::move(handler));
- m_dataChannels.append(channel);
-
- scheduleDispatchEvent(RTCDataChannelEvent::create(eventNames().datachannelEvent, false, false, channel.release()));
+ m_signalingState = newState;
}
-void RTCPeerConnection::stop()
+void RTCPeerConnection::updateIceGatheringState(IceGatheringState newState)
{
- if (m_stopped)
- return;
-
- m_stopped = true;
- m_iceConnectionState = IceConnectionStateClosed;
- m_signalingState = SignalingStateClosed;
+ scriptExecutionContext()->postTask([=](ScriptExecutionContext&) {
+ if (m_signalingState == SignalingState::Closed || m_iceGatheringState == newState)
+ return;
- Vector<RefPtr<RTCDataChannel>>::iterator i = m_dataChannels.begin();
- for (; i != m_dataChannels.end(); ++i)
- (*i)->stop();
+ m_iceGatheringState = newState;
+ dispatchEvent(Event::create(eventNames().icegatheringstatechangeEvent, false, false));
+ });
}
-void RTCPeerConnection::didAddOrRemoveTrack()
+void RTCPeerConnection::updateIceConnectionState(IceConnectionState newState)
{
- negotiationNeeded();
-}
+ scriptExecutionContext()->postTask([=](ScriptExecutionContext&) {
+ if (m_signalingState == SignalingState::Closed || m_iceConnectionState == newState)
+ return;
-void RTCPeerConnection::changeSignalingState(SignalingState signalingState)
-{
- if (m_signalingState != SignalingStateClosed && m_signalingState != signalingState) {
- m_signalingState = signalingState;
- scheduleDispatchEvent(Event::create(eventNames().signalingstatechangeEvent, false, false));
- }
+ m_iceConnectionState = newState;
+ dispatchEvent(Event::create(eventNames().iceconnectionstatechangeEvent, false, false));
+ });
}
-void RTCPeerConnection::changeIceGatheringState(IceGatheringState iceGatheringState)
+void RTCPeerConnection::scheduleNegotiationNeededEvent()
{
- m_iceGatheringState = iceGatheringState;
-}
-
-void RTCPeerConnection::changeIceConnectionState(IceConnectionState iceConnectionState)
-{
- if (m_iceConnectionState != IceConnectionStateClosed && m_iceConnectionState != iceConnectionState) {
- m_iceConnectionState = iceConnectionState;
- scheduleDispatchEvent(Event::create(eventNames().iceconnectionstatechangeEvent, false, false));
- }
+ scriptExecutionContext()->postTask([=](ScriptExecutionContext&) {
+ if (m_backend->isNegotiationNeeded()) {
+ m_backend->clearNegotiationNeededState();
+ dispatchEvent(Event::create(eventNames().negotiationneededEvent, false, false));
+ }
+ });
}
-void RTCPeerConnection::scheduleDispatchEvent(PassRefPtr<Event> event)
+void RTCPeerConnection::fireEvent(Event& event)
{
- m_scheduledEvents.append(event);
-
- if (!m_scheduledEventTimer.isActive())
- m_scheduledEventTimer.startOneShot(0);
+ dispatchEvent(event);
}
-void RTCPeerConnection::scheduledEventTimerFired(Timer<RTCPeerConnection>*)
+void RTCPeerConnection::replaceTrack(RTCRtpSender& sender, RefPtr<MediaStreamTrack>&& withTrack, DOMPromise<void>&& promise)
{
- if (m_stopped)
- return;
-
- Vector<RefPtr<Event>> events;
- events.swap(m_scheduledEvents);
-
- Vector<RefPtr<Event>>::iterator it = events.begin();
- for (; it != events.end(); ++it)
- dispatchEvent((*it).release());
-
- events.clear();
+ m_backend->replaceTrack(sender, WTFMove(withTrack), WTFMove(promise));
}
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h
index 0d375be4c..a10aaeb4c 100644
--- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h
+++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,148 +30,142 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCPeerConnection_h
-#define RTCPeerConnection_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include "ActiveDOMObject.h"
-#include "Dictionary.h"
#include "EventTarget.h"
-#include "ExceptionBase.h"
#include "MediaStream.h"
-#include "RTCIceCandidate.h"
-#include "RTCPeerConnectionHandler.h"
-#include "RTCPeerConnectionHandlerClient.h"
-#include "ScriptWrappable.h"
-#include "Timer.h"
-#include <wtf/RefCounted.h>
+#include "RTCConfiguration.h"
+#include "RTCDataChannel.h"
+#include "RTCOfferAnswerOptions.h"
+#include "RTCRtpTransceiver.h"
namespace WebCore {
-class MediaConstraints;
class MediaStreamTrack;
-class RTCConfiguration;
-class RTCDTMFSender;
-class RTCDataChannel;
+class PeerConnectionBackend;
+class RTCIceCandidate;
class RTCPeerConnectionErrorCallback;
class RTCSessionDescription;
-class RTCSessionDescriptionCallback;
class RTCStatsCallback;
-class VoidCallback;
-class RTCPeerConnection final : public RefCounted<RTCPeerConnection>, public ScriptWrappable, public RTCPeerConnectionHandlerClient, public EventTargetWithInlineData, public ActiveDOMObject, public MediaStream::Observer {
+class RTCPeerConnection final : public RefCounted<RTCPeerConnection>, public RTCRtpSenderClient, public EventTargetWithInlineData, public ActiveDOMObject {
public:
- static PassRefPtr<RTCPeerConnection> create(ScriptExecutionContext&, const Dictionary& rtcConfiguration, const Dictionary& mediaConstraints, ExceptionCode&);
- ~RTCPeerConnection();
+ static Ref<RTCPeerConnection> create(ScriptExecutionContext&);
+ virtual ~RTCPeerConnection();
- void createOffer(PassRefPtr<RTCSessionDescriptionCallback>, PassRefPtr<RTCPeerConnectionErrorCallback>, const Dictionary& mediaConstraints, ExceptionCode&);
+ using AnswerOptions = RTCAnswerOptions;
+ using DataChannelInit = RTCDataChannelInit;
+ using OfferAnswerOptions = RTCOfferAnswerOptions;
+ using OfferOptions = RTCOfferOptions;
- void createAnswer(PassRefPtr<RTCSessionDescriptionCallback>, PassRefPtr<RTCPeerConnectionErrorCallback>, const Dictionary& mediaConstraints, ExceptionCode&);
+ ExceptionOr<void> initializeWith(Document&, RTCConfiguration&&);
- void setLocalDescription(PassRefPtr<RTCSessionDescription>, PassRefPtr<VoidCallback>, PassRefPtr<RTCPeerConnectionErrorCallback>, ExceptionCode&);
- PassRefPtr<RTCSessionDescription> localDescription(ExceptionCode&);
+ const Vector<std::reference_wrapper<RTCRtpSender>>& getSenders() const { return m_transceiverSet->senders(); }
+ const Vector<std::reference_wrapper<RTCRtpReceiver>>& getReceivers() const { return m_transceiverSet->receivers(); }
+ const Vector<RefPtr<RTCRtpTransceiver>>& getTransceivers() const { return m_transceiverSet->list(); }
- void setRemoteDescription(PassRefPtr<RTCSessionDescription>, PassRefPtr<VoidCallback>, PassRefPtr<RTCPeerConnectionErrorCallback>, ExceptionCode&);
- PassRefPtr<RTCSessionDescription> remoteDescription(ExceptionCode&);
+ // Part of legacy MediaStream-based API (mostly implemented as JS built-ins)
+ Vector<RefPtr<MediaStream>> getRemoteStreams() const { return m_backend->getRemoteStreams(); }
- String signalingState() const;
+ ExceptionOr<Ref<RTCRtpSender>> addTrack(Ref<MediaStreamTrack>&&, const Vector<std::reference_wrapper<MediaStream>>&);
+ ExceptionOr<void> removeTrack(RTCRtpSender&);
- void updateIce(const Dictionary& rtcConfiguration, const Dictionary& mediaConstraints, ExceptionCode&);
+ // This enum is mirrored in RTCRtpTransceiver.h
+ enum class RtpTransceiverDirection { Sendrecv, Sendonly, Recvonly, Inactive };
- void addIceCandidate(RTCIceCandidate*, PassRefPtr<VoidCallback>, PassRefPtr<RTCPeerConnectionErrorCallback>, ExceptionCode&);
+ struct RtpTransceiverInit {
+ RtpTransceiverDirection direction;
+ };
- String iceGatheringState() const;
+ ExceptionOr<Ref<RTCRtpTransceiver>> addTransceiver(Ref<MediaStreamTrack>&&, const RtpTransceiverInit&);
+ ExceptionOr<Ref<RTCRtpTransceiver>> addTransceiver(const String& kind, const RtpTransceiverInit&);
- String iceConnectionState() const;
+ void queuedCreateOffer(RTCOfferOptions&&, PeerConnection::SessionDescriptionPromise&&);
+ void queuedCreateAnswer(RTCAnswerOptions&&, PeerConnection::SessionDescriptionPromise&&);
- MediaStreamVector getLocalStreams() const;
+ void queuedSetLocalDescription(RTCSessionDescription&, DOMPromise<void>&&);
+ RefPtr<RTCSessionDescription> localDescription() const;
+ RefPtr<RTCSessionDescription> currentLocalDescription() const;
+ RefPtr<RTCSessionDescription> pendingLocalDescription() const;
- MediaStreamVector getRemoteStreams() const;
+ void queuedSetRemoteDescription(RTCSessionDescription&, DOMPromise<void>&&);
+ RefPtr<RTCSessionDescription> remoteDescription() const;
+ RefPtr<RTCSessionDescription> currentRemoteDescription() const;
+ RefPtr<RTCSessionDescription> pendingRemoteDescription() const;
- MediaStream* getStreamById(const String& streamId);
+ String signalingState() const;
- void addStream(PassRefPtr<MediaStream>, const Dictionary& mediaConstraints, ExceptionCode&);
+ void queuedAddIceCandidate(RTCIceCandidate&, DOMPromise<void>&&);
- void removeStream(PassRefPtr<MediaStream>, ExceptionCode&);
+ String iceGatheringState() const;
+ String iceConnectionState() const;
- void getStats(PassRefPtr<RTCStatsCallback> successCallback, PassRefPtr<MediaStreamTrack> selector);
+ const RTCConfiguration& getConfiguration() const { return m_configuration; }
+ ExceptionOr<void> setConfiguration(RTCConfiguration&&);
- PassRefPtr<RTCDataChannel> createDataChannel(String label, const Dictionary& dataChannelDict, ExceptionCode&);
+ void getStats(MediaStreamTrack*, Ref<DeferredPromise>&&);
- PassRefPtr<RTCDTMFSender> createDTMFSender(PassRefPtr<MediaStreamTrack>, ExceptionCode&);
+ ExceptionOr<Ref<RTCDataChannel>> createDataChannel(ScriptExecutionContext&, String&&, RTCDataChannelInit&&);
- void close(ExceptionCode&);
+ void close();
- DEFINE_ATTRIBUTE_EVENT_LISTENER(negotiationneeded);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(icecandidate);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(signalingstatechange);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(addstream);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(removestream);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(iceconnectionstatechange);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(datachannel);
+ // EventTarget
+ EventTargetInterface eventTargetInterface() const final { return RTCPeerConnectionEventTargetInterfaceType; }
+ ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
- // RTCPeerConnectionHandlerClient
- virtual void negotiationNeeded() override;
- virtual void didGenerateIceCandidate(PassRefPtr<RTCIceCandidateDescriptor>) override;
- virtual void didChangeSignalingState(SignalingState) override;
- virtual void didChangeIceGatheringState(IceGatheringState) override;
- virtual void didChangeIceConnectionState(IceConnectionState) override;
- virtual void didAddRemoteStream(PassRefPtr<MediaStreamPrivate>) override;
- virtual void didRemoveRemoteStream(MediaStreamPrivate*) override;
- virtual void didAddRemoteDataChannel(std::unique_ptr<RTCDataChannelHandler>) override;
+ using RefCounted::ref;
+ using RefCounted::deref;
- // EventTarget
- virtual EventTargetInterface eventTargetInterface() const override { return RTCPeerConnectionEventTargetInterfaceType; }
- virtual ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); }
+ // Used for testing with a mock
+ WEBCORE_EXPORT void emulatePlatformEvent(const String& action);
- // ActiveDOMObject
- virtual void stop() override;
+ // API used by PeerConnectionBackend and relatives
+ void addTransceiver(Ref<RTCRtpTransceiver>&&);
+ void setSignalingState(PeerConnectionStates::SignalingState);
+ void updateIceGatheringState(PeerConnectionStates::IceGatheringState);
+ void updateIceConnectionState(PeerConnectionStates::IceConnectionState);
- // MediaStream::Observer
- virtual void didAddOrRemoveTrack() override;
+ void scheduleNegotiationNeededEvent();
- using RefCounted<RTCPeerConnection>::ref;
- using RefCounted<RTCPeerConnection>::deref;
+ RTCRtpSenderClient& senderClient() { return *this; }
+ void fireEvent(Event&);
+ PeerConnectionStates::SignalingState internalSignalingState() const { return m_signalingState; }
+ PeerConnectionStates::IceGatheringState internalIceGatheringState() const { return m_iceGatheringState; }
+ PeerConnectionStates::IceConnectionState internalIceConnectionState() const { return m_iceConnectionState; }
private:
- RTCPeerConnection(ScriptExecutionContext&, PassRefPtr<RTCConfiguration>, PassRefPtr<MediaConstraints>, ExceptionCode&);
+ RTCPeerConnection(ScriptExecutionContext&);
- static PassRefPtr<RTCConfiguration> parseConfiguration(const Dictionary& configuration, ExceptionCode&);
- void scheduleDispatchEvent(PassRefPtr<Event>);
- void scheduledEventTimerFired(Timer<RTCPeerConnection>*);
- bool hasLocalStreamWithTrackId(const String& trackId);
+ void completeAddTransceiver(RTCRtpTransceiver&, const RtpTransceiverInit&);
// EventTarget implementation.
- virtual void refEventTarget() override { ref(); }
- virtual void derefEventTarget() override { deref(); }
+ void refEventTarget() final { ref(); }
+ void derefEventTarget() final { deref(); }
- void changeSignalingState(SignalingState);
- void changeIceGatheringState(IceGatheringState);
- void changeIceConnectionState(IceConnectionState);
+ // ActiveDOMObject
+ void stop() final;
+ const char* activeDOMObjectName() const final;
+ bool canSuspendForDocumentSuspension() const final;
- bool checkStateForLocalDescription(RTCSessionDescription*);
- bool checkStateForRemoteDescription(RTCSessionDescription*);
+ // RTCRtpSenderClient
+ void replaceTrack(RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromise<void>&&) final;
- SignalingState m_signalingState;
- IceGatheringState m_iceGatheringState;
- IceConnectionState m_iceConnectionState;
+ PeerConnectionStates::SignalingState m_signalingState { PeerConnectionStates::SignalingState::Stable };
+ PeerConnectionStates::IceGatheringState m_iceGatheringState { PeerConnectionStates::IceGatheringState::New };
+ PeerConnectionStates::IceConnectionState m_iceConnectionState { PeerConnectionStates::IceConnectionState::New };
- MediaStreamVector m_localStreams;
- MediaStreamVector m_remoteStreams;
+ std::unique_ptr<RtpTransceiverSet> m_transceiverSet { std::unique_ptr<RtpTransceiverSet>(new RtpTransceiverSet()) };
Vector<RefPtr<RTCDataChannel>> m_dataChannels;
- std::unique_ptr<RTCPeerConnectionHandler> m_peerHandler;
-
- Timer<RTCPeerConnection> m_scheduledEventTimer;
- Vector<RefPtr<Event>> m_scheduledEvents;
+ std::unique_ptr<PeerConnectionBackend> m_backend;
- bool m_stopped;
+ RTCConfiguration m_configuration;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCPeerConnection_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl
index 1d6017f65..9ad581351 100644
--- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl
+++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2015, 2016 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,65 +30,126 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- Conditional=MEDIA_STREAM,
- ActiveDOMObject,
- CustomConstructor(Dictionary rtcIceServers, optional Dictionary mediaConstraints),
- ConstructorCallWith=ScriptExecutionContext,
- ConstructorRaisesException,
- ConstructorCallWith=ScriptExecutionContext,
- EventTarget,
- InterfaceName=webkitRTCPeerConnection,
-] interface RTCPeerConnection {
- [RaisesException] void createOffer(RTCSessionDescriptionCallback successCallback, [Default=Undefined] optional RTCPeerConnectionErrorCallback failureCallback, optional Dictionary mediaConstraints);
+dictionary RTCOfferAnswerOptions {
+ boolean voiceActivityDetection = true;
+};
+
+dictionary RTCOfferOptions : RTCOfferAnswerOptions {
+ boolean iceRestart = false;
+};
- [RaisesException] void createAnswer(RTCSessionDescriptionCallback successCallback, [Default=Undefined] optional RTCPeerConnectionErrorCallback failureCallback, optional Dictionary mediaConstraints);
+dictionary RTCAnswerOptions : RTCOfferAnswerOptions {
+};
- [RaisesException] void setLocalDescription(RTCSessionDescription description, [Default=Undefined] optional VoidCallback successCallback, [Default=Undefined] optional RTCPeerConnectionErrorCallback failureCallback);
- [GetterRaisesException] readonly attribute RTCSessionDescription localDescription;
+dictionary RTCDataChannelInit {
+ boolean ordered = true;
+ unsigned short maxRetransmitTime;
+ unsigned short maxRetransmits;
+ USVString protocol = "";
+ boolean negotiated = false;
+ unsigned short id;
+};
- [RaisesException] void setRemoteDescription(RTCSessionDescription description, [Default=Undefined] optional VoidCallback successCallback, [Default=Undefined] optional RTCPeerConnectionErrorCallback failureCallback);
- [GetterRaisesException] readonly attribute RTCSessionDescription remoteDescription;
+[
+ ActiveDOMObject,
+ Conditional=WEB_RTC,
+ ConstructorCallWith=ScriptExecutionContext,
+ EnabledAtRuntime=PeerConnection,
+ ExportMacro=WEBCORE_EXPORT,
+ JSBuiltinConstructor,
+] interface RTCPeerConnection : EventTarget {
+ // Private initializer
+ [PrivateIdentifier, CallWith=Document, MayThrowException] void initializeWith(RTCConfiguration configuration);
+
+ // RTP Media API extensions
+ [PrivateIdentifier, PublicIdentifier] sequence<RTCRtpSender> getSenders();
+ sequence<RTCRtpReceiver> getReceivers();
+ sequence<RTCRtpTransceiver> getTransceivers();
+
+ [PrivateIdentifier, PublicIdentifier, MayThrowException] RTCRtpSender addTrack(MediaStreamTrack track, MediaStream... streams);
+ [PrivateIdentifier, PublicIdentifier, MayThrowException] void removeTrack(RTCRtpSender sender);
+
+ [MayThrowException] RTCRtpTransceiver addTransceiver(MediaStreamTrack track, optional RTCRtpTransceiverInit init);
+ [MayThrowException] RTCRtpTransceiver addTransceiver(DOMString kind, optional RTCRtpTransceiverInit init);
+
+ // Legacy MediaSream-based API (implemented on top of the RTP Media API)
+ [JSBuiltin] sequence<MediaStream> getLocalStreams();
+ [PrivateIdentifier, PublicIdentifier] sequence<MediaStream> getRemoteStreams();
+ [JSBuiltin] MediaStream getStreamById(DOMString streamId);
+
+ [JSBuiltin] void addStream(MediaStream stream);
+ [JSBuiltin] void removeStream(MediaStream stream);
+
+ [JSBuiltin] Promise<RTCSessionDescriptionInit> createOffer(optional RTCOfferOptions offerOptions);
+ // Legacy signature: Promise<void> createOffer(RTCSessionDescriptionCallback successCallback
+ // RTCPeerConnectionErrorCallback errorCallback,
+ // optional Dictionary offerOptions);
+
+ [JSBuiltin] Promise<RTCSessionDescriptionInit> createAnswer(optional RTCAnswerOptions answerOptions);
+ // Legacy signature: Promise<void> createAnswer(RTCSessionDescriptionCallback successCallback
+ // RTCPeerConnectionErrorCallback errorCallback,
+ // optional Dictionary answerOptions);
+
+ [JSBuiltin] Promise<void> setLocalDescription(RTCSessionDescription description);
+ // Legacy signature: Promise<void> setLocalDescription(RTCSessionDescription description
+ // VoidCallback successCallback,
+ // RTCPeerConnectionErrorCallback errorCallback);
+
+ readonly attribute RTCSessionDescription localDescription;
+ readonly attribute RTCSessionDescription currentLocalDescription;
+ readonly attribute RTCSessionDescription pendingLocalDescription;
+
+ [JSBuiltin] Promise<void> setRemoteDescription(RTCSessionDescription description);
+ // Legacy signature: Promise<void> setRemoteDescription(RTCSessionDescription description
+ // VoidCallback successCallback,
+ // RTCPeerConnectionErrorCallback errorCallback);
+
+ readonly attribute RTCSessionDescription remoteDescription;
+ readonly attribute RTCSessionDescription currentRemoteDescription;
+ readonly attribute RTCSessionDescription pendingRemoteDescription;
readonly attribute DOMString signalingState;
- [RaisesException] void updateIce(optional Dictionary configuration, optional Dictionary mediaConstraints);
-
- [RaisesException] void addIceCandidate(RTCIceCandidate candidate, VoidCallback successCallback, RTCPeerConnectionErrorCallback failureCallback);
+ [JSBuiltin] Promise<void> addIceCandidate(RTCIceCandidate candidate);
+ // Legacy signature: Promise<void> addIceCandidate(RTCIceCandidate candidate
+ // VoidCallback successCallback,
+ // RTCPeerConnectionErrorCallback errorCallback);
readonly attribute DOMString iceGatheringState;
readonly attribute DOMString iceConnectionState;
- sequence<MediaStream> getLocalStreams();
- sequence<MediaStream> getRemoteStreams();
- MediaStream getStreamById(DOMString streamId);
-
- [StrictTypeChecking, RaisesException] void addStream(MediaStream stream, optional Dictionary mediaConstraints);
- [StrictTypeChecking, RaisesException] void removeStream(MediaStream stream);
+ RTCConfiguration getConfiguration();
+ [MayThrowException] void setConfiguration(RTCConfiguration configuration);
- void getStats(RTCStatsCallback successCallback, [Default=Undefined] optional MediaStreamTrack selector);
+ Promise<RTCStatsReport> getStats(optional MediaStreamTrack? selector = null);
- [RaisesException] RTCDataChannel createDataChannel([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString label, optional Dictionary options);
+ // Private API used to implement the overloaded operations above. Queued functions are called by
+ // runQueuedOperation() (defined in RTCPeerConnectionInternals.js).
+ [PrivateIdentifier] Promise<RTCSessionDescriptionInit> queuedCreateOffer(optional RTCOfferOptions offerOptions);
+ [PrivateIdentifier] Promise<RTCSessionDescriptionInit> queuedCreateAnswer(optional RTCAnswerOptions answerOptions);
+ [PrivateIdentifier] Promise<void> queuedSetLocalDescription(RTCSessionDescription description);
+ [PrivateIdentifier] Promise<void> queuedSetRemoteDescription(RTCSessionDescription description);
+ [PrivateIdentifier] Promise<void> queuedAddIceCandidate(RTCIceCandidate candidate);
- [RaisesException] RTCDTMFSender createDTMFSender(MediaStreamTrack track);
+ [CallWith=ScriptExecutionContext, MayThrowException] RTCDataChannel createDataChannel([TreatNullAs=EmptyString] DOMString label, optional RTCDataChannelInit options);
- [RaisesException] void close();
+ void close();
- attribute EventListener onnegotiationneeded;
- attribute EventListener onicecandidate;
- attribute EventListener onsignalingstatechange;
- attribute EventListener onaddstream;
- attribute EventListener onremovestream;
- attribute EventListener oniceconnectionstatechange;
- attribute EventListener ondatachannel;
+ attribute EventHandler onnegotiationneeded;
+ attribute EventHandler onicecandidate;
+ attribute EventHandler onsignalingstatechange;
+ attribute EventHandler ontrack;
+ attribute EventHandler oniceconnectionstatechange;
+ attribute EventHandler onicegatheringstatechange;
+ attribute EventHandler ondatachannel;
- // EventTarget interface
- void addEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- void removeEventListener(DOMString type,
- EventListener listener,
- optional boolean useCapture);
- [RaisesException] boolean dispatchEvent(Event event);
+ // Legacy event handler (MediaStream-based API)
+ attribute EventHandler onaddstream;
};
+// This enum is mirrored in RTCRtpTransceiver.idl
+enum RTCRtpTransceiverDirection { "sendrecv", "sendonly", "recvonly", "inactive" };
+
+dictionary RTCRtpTransceiverInit {
+ RTCRtpTransceiverDirection direction = "sendrecv";
+};
diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.js b/Source/WebCore/Modules/mediastream/RTCPeerConnection.js
new file mode 100644
index 000000000..2cb6a4036
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.js
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2015, 2016 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// @conditional=ENABLE(WEB_RTC)
+
+function initializeRTCPeerConnection(configuration)
+{
+ "use strict";
+
+ if (configuration == null)
+ configuration = {};
+ else if (!@isObject(configuration))
+ @throwTypeError("RTCPeerConnection argument must be a valid dictionary");
+
+ // FIXME: Handle errors in a better way than catching and re-throwing (http://webkit.org/b/158936)
+ try {
+ this.@initializeWith(configuration);
+ } catch (e) {
+ const message = e.name === "TypeMismatchError" ? "Invalid RTCPeerConnection constructor arguments"
+ : "Error creating RTCPeerConnection";
+ @throwTypeError(message);
+ }
+ this.@operations = [];
+ this.@localStreams = [];
+
+ return this;
+}
+
+function getLocalStreams()
+{
+ "use strict";
+
+ if (!@isRTCPeerConnection(this))
+ throw @makeThisTypeError("RTCPeerConnection", "getLocalStreams");
+
+ return this.@localStreams.slice();
+}
+
+function getStreamById(streamIdArg)
+{
+ "use strict";
+
+ if (!@isRTCPeerConnection(this))
+ throw @makeThisTypeError("RTCPeerConnection", "getStreamById");
+
+ if (arguments.length < 1)
+ @throwTypeError("Not enough arguments");
+
+ const streamId = @String(streamIdArg);
+
+ return this.@localStreams.find(stream => stream.id === streamId)
+ || this.@getRemoteStreams().find(stream => stream.id === streamId)
+ || null;
+}
+
+function addStream(stream)
+{
+ "use strict";
+
+ if (!@isRTCPeerConnection(this))
+ throw @makeThisTypeError("RTCPeerConnection", "addStream");
+
+ if (arguments.length < 1)
+ @throwTypeError("Not enough arguments");
+
+ if (!(stream instanceof @MediaStream))
+ @throwTypeError("Argument 1 ('stream') to RTCPeerConnection.addStream must be an instance of MediaStream");
+
+ if (this.@localStreams.find(localStream => localStream.id === stream.id))
+ return;
+
+ this.@localStreams.@push(stream);
+ stream.@getTracks().forEach(track => this.@addTrack(track, stream));
+}
+
+function removeStream(stream)
+{
+ "use strict";
+
+ if (!@isRTCPeerConnection(this))
+ throw @makeThisTypeError("RTCPeerConnection", "removeStream");
+
+ if (arguments.length < 1)
+ @throwTypeError("Not enough arguments");
+
+ if (!(stream instanceof @MediaStream))
+ @throwTypeError("Argument 1 ('stream') to RTCPeerConnection.removeStream must be an instance of MediaStream");
+
+ const indexOfStreamToRemove = this.@localStreams.findIndex(localStream => localStream.id === stream.id);
+ if (indexOfStreamToRemove === -1)
+ return;
+
+ const senders = this.@getSenders();
+ this.@localStreams[indexOfStreamToRemove].@getTracks().forEach(track => {
+ const senderForTrack = senders.find(sender => sender.track && sender.track.id === track.id);
+ if (senderForTrack)
+ this.@removeTrack(senderForTrack);
+ });
+
+ this.@localStreams.splice(indexOfStreamToRemove, 1);
+}
+
+function createOffer()
+{
+ "use strict";
+
+ if (!@isRTCPeerConnection(this))
+ return @Promise.@reject(@makeThisTypeError("RTCPeerConnection", "createOffer"));
+
+ const peerConnection = this;
+
+ return @callbacksAndDictionaryOverload(arguments, "createOffer", function (options) {
+ // Promise mode
+ return @enqueueOperation(peerConnection, function () {
+ return peerConnection.@queuedCreateOffer(options);
+ });
+ }, function (successCallback, errorCallback, options) {
+ // Legacy callbacks mode
+ @enqueueOperation(peerConnection, function () {
+ return peerConnection.@queuedCreateOffer(options).@then(successCallback, errorCallback);
+ });
+
+ return @Promise.@resolve(@undefined);
+ });
+}
+
+function createAnswer()
+{
+ "use strict";
+
+ if (!@isRTCPeerConnection(this))
+ return @Promise.@reject(@makeThisTypeError("RTCPeerConnection", "createAnswer"));
+
+ const peerConnection = this;
+
+ return @callbacksAndDictionaryOverload(arguments, "createAnswer", function (options) {
+ // Promise mode
+ return @enqueueOperation(peerConnection, function () {
+ return peerConnection.@queuedCreateAnswer(options);
+ });
+ }, function (successCallback, errorCallback, options) {
+ // Legacy callbacks mode
+ @enqueueOperation(peerConnection, function () {
+ return peerConnection.@queuedCreateAnswer(options).@then(successCallback, errorCallback);
+ });
+
+ return @Promise.@resolve(@undefined);
+ });
+}
+
+function setLocalDescription()
+{
+ "use strict";
+
+ if (!@isRTCPeerConnection(this))
+ return @Promise.@reject(@makeThisTypeError("RTCPeerConnection", "setLocalDescription"));
+
+ const peerConnection = this;
+
+ // FIXME: According the spec, we should throw when receiving a RTCSessionDescription.
+ const objectInfo = {
+ "constructor": @RTCSessionDescription,
+ "argName": "description",
+ "argType": "RTCSessionDescription",
+ "maybeDictionary": "true"
+ };
+ return @objectAndCallbacksOverload(arguments, "setLocalDescription", objectInfo, function (description) {
+ // Promise mode
+ return @enqueueOperation(peerConnection, function () {
+ return peerConnection.@queuedSetLocalDescription(description);
+ });
+ }, function (description, successCallback, errorCallback) {
+ // Legacy callbacks mode
+ @enqueueOperation(peerConnection, function () {
+ return peerConnection.@queuedSetLocalDescription(description).@then(successCallback, errorCallback);
+ });
+
+ return @Promise.@resolve(@undefined);
+ });
+}
+
+function setRemoteDescription()
+{
+ "use strict";
+
+ if (!@isRTCPeerConnection(this))
+ return @Promise.@reject(@makeThisTypeError("RTCPeerConnection", "setRemoteDescription"));
+
+ const peerConnection = this;
+
+ // FIXME: According the spec, we should throw when receiving a RTCSessionDescription.
+ const objectInfo = {
+ "constructor": @RTCSessionDescription,
+ "argName": "description",
+ "argType": "RTCSessionDescription",
+ "maybeDictionary": "true"
+ };
+ return @objectAndCallbacksOverload(arguments, "setRemoteDescription", objectInfo, function (description) {
+ // Promise mode
+ return @enqueueOperation(peerConnection, function () {
+ return peerConnection.@queuedSetRemoteDescription(description);
+ });
+ }, function (description, successCallback, errorCallback) {
+ // Legacy callbacks mode
+ @enqueueOperation(peerConnection, function () {
+ return peerConnection.@queuedSetRemoteDescription(description).@then(successCallback, errorCallback);
+ });
+
+ return @Promise.@resolve(@undefined);
+ });
+}
+
+function addIceCandidate()
+{
+ "use strict";
+
+ if (!@isRTCPeerConnection(this))
+ return @Promise.@reject(@makeThisTypeError("RTCPeerConnection", "addIceCandidate"));
+
+ const peerConnection = this;
+
+ const objectInfo = {
+ "constructor": @RTCIceCandidate,
+ "argName": "candidate",
+ "argType": "RTCIceCandidate",
+ "maybeDictionary": "true"
+ };
+ return @objectAndCallbacksOverload(arguments, "addIceCandidate", objectInfo, function (candidate) {
+ // Promise mode
+ return @enqueueOperation(peerConnection, function () {
+ return peerConnection.@queuedAddIceCandidate(candidate);
+ });
+ }, function (candidate, successCallback, errorCallback) {
+ // Legacy callbacks mode
+ @enqueueOperation(peerConnection, function () {
+ return peerConnection.@queuedAddIceCandidate(candidate).@then(successCallback, errorCallback);
+ });
+
+ return @Promise.@resolve(@undefined);
+ });
+}
diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnectionInternals.js b/Source/WebCore/Modules/mediastream/RTCPeerConnectionInternals.js
new file mode 100644
index 000000000..498d4f886
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCPeerConnectionInternals.js
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2015, 2016 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// @conditional=ENABLE(WEB_RTC)
+// @internal
+
+// Operation queue as specified in section 4.3.1 (WebRTC 1.0)
+function enqueueOperation(peerConnection, operation)
+{
+ "use strict";
+
+ const operations = peerConnection.@operations;
+
+ function runNext() {
+ operations.@shift();
+ if (operations.length)
+ operations[0]();
+ };
+
+ return new @Promise(function (resolve, reject) {
+ operations.@push(function() {
+ operation().@then(resolve, reject).@then(runNext, runNext);
+ });
+
+ if (operations.length == 1)
+ operations[0]();
+ });
+}
+
+function objectAndCallbacksOverload(args, functionName, objectInfo, promiseMode, legacyMode)
+{
+ "use strict";
+
+ let argsCount = args.length;
+ let objectArg = args[0];
+ let objectArgOk = false;
+
+ if (!argsCount) {
+ if (!objectInfo.defaultsToNull)
+ return @Promise.@reject(new @TypeError("Not enough arguments"));
+
+ objectArg = null;
+ objectArgOk = true;
+ argsCount = 1;
+ } else {
+ const hasMatchingType = objectArg instanceof objectInfo.constructor;
+ if (hasMatchingType)
+ objectArgOk = true;
+ else if (objectInfo.defaultsToNull)
+ objectArgOk = objectArg === null || typeof objectArg === "undefined";
+ else if (objectInfo.maybeDictionary) {
+ try {
+ objectArg = new objectInfo.constructor(objectArg);
+ objectArgOk = true;
+ } catch (e) {
+ objectArgOk = false;
+ }
+ }
+ }
+
+ if (!objectArgOk)
+ return @Promise.@reject(new @TypeError(`Argument 1 ('${objectInfo.argName}') to RTCPeerConnection.${functionName} must be an instance of ${objectInfo.argType}`));
+
+ if (argsCount === 1)
+ return promiseMode(objectArg);
+
+ // More than one argument: Legacy mode
+ if (argsCount < 3)
+ return @Promise.@reject(new @TypeError("Not enough arguments"));
+
+ const successCallback = args[1];
+ const errorCallback = args[2];
+
+ if (typeof successCallback !== "function")
+ return @Promise.@reject(new @TypeError(`Argument 2 ('successCallback') to RTCPeerConnection.${functionName} must be a function`));
+
+ if (typeof errorCallback !== "function")
+ return @Promise.@reject(new @TypeError(`Argument 3 ('errorCallback') to RTCPeerConnection.${functionName} must be a function`));
+
+ return legacyMode(objectArg, successCallback, errorCallback);
+}
+
+function callbacksAndDictionaryOverload(args, functionName, promiseMode, legacyMode)
+{
+ "use strict";
+
+ if (args.length <= 1) {
+ // Zero or one arguments: Promise mode
+ const options = args[0];
+ if (args.length && !@isDictionary(options))
+ return @Promise.@reject(new @TypeError(`Argument 1 ('options') to RTCPeerConnection.${functionName} must be a dictionary`));
+
+ return promiseMode(options);
+ }
+
+ // More than one argument: Legacy mode
+ const successCallback = args[0];
+ const errorCallback = args[1];
+ const options = args[2];
+
+ if (typeof successCallback !== "function")
+ return @Promise.@reject(new @TypeError(`Argument 1 ('successCallback') to RTCPeerConnection.${functionName} must be a function`));
+
+ if (typeof errorCallback !== "function")
+ return @Promise.@reject(new @TypeError(`Argument 2 ('errorCallback') to RTCPeerConnection.${functionName} must be a function`));
+
+ if (args.length > 2 && !@isDictionary(options))
+ return @Promise.@reject(new @TypeError(`Argument 3 ('options') to RTCPeerConnection.${functionName} must be a dictionary`));
+
+ return legacyMode(successCallback, errorCallback, args[2]);
+}
+
+function isRTCPeerConnection(connection)
+{
+ "use strict";
+
+ return @isObject(connection) && !!connection.@operations;
+}
diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnectionErrorCallback.h b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.cpp
index c2aecba0a..152e60270 100644
--- a/Source/WebCore/Modules/mediastream/RTCPeerConnectionErrorCallback.h
+++ b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.cpp
@@ -1,14 +1,19 @@
/*
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
+ *
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -23,24 +28,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCPeerConnectionErrorCallback_h
-#define RTCPeerConnectionErrorCallback_h
-
-#if ENABLE(MEDIA_STREAM)
+#include "config.h"
+#include "RTCRtpReceiver.h"
-#include "DOMError.h"
-#include <wtf/RefCounted.h>
+#if ENABLE(WEB_RTC)
namespace WebCore {
-class RTCPeerConnectionErrorCallback : public RefCounted<RTCPeerConnectionErrorCallback> {
-public:
- virtual ~RTCPeerConnectionErrorCallback() { }
- virtual bool handleEvent(DOMError*) = 0;
-};
+RTCRtpReceiver::RTCRtpReceiver(Ref<MediaStreamTrack>&& track)
+ : RTCRtpSenderReceiverBase(WTFMove(track))
+{
+}
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCPeerConnectionErrorCallback_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h
new file mode 100644
index 000000000..ba787a63e
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "RTCRtpSenderReceiverBase.h"
+
+namespace WebCore {
+
+class RTCRtpReceiver : public RTCRtpSenderReceiverBase {
+public:
+ static Ref<RTCRtpReceiver> create(Ref<MediaStreamTrack>&& track)
+ {
+ return adoptRef(*new RTCRtpReceiver(WTFMove(track)));
+ }
+
+ bool isDispatched() const { return m_isDispatched; }
+ void setDispatched(bool isDispatched) { m_isDispatched = isDispatched; }
+
+private:
+ explicit RTCRtpReceiver(Ref<MediaStreamTrack>&&);
+
+ bool m_isDispatched { false };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnectionErrorCallback.idl b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.idl
index 4b87ad7ff..645ab3cbc 100644
--- a/Source/WebCore/Modules/mediastream/RTCPeerConnectionErrorCallback.idl
+++ b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.idl
@@ -1,14 +1,19 @@
/*
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
+ *
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -24,8 +29,8 @@
*/
[
- Conditional=MEDIA_STREAM,
-] callback interface RTCPeerConnectionErrorCallback {
- boolean handleEvent(DOMError error);
+ Conditional=WEB_RTC,
+ EnabledAtRuntime=PeerConnection,
+] interface RTCRtpReceiver {
+ readonly attribute MediaStreamTrack track;
};
-
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp b/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp
new file mode 100644
index 000000000..53b6f2cd4
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RTCRtpSender.h"
+
+#if ENABLE(WEB_RTC)
+
+#include "ExceptionCode.h"
+
+namespace WebCore {
+
+Ref<RTCRtpSender> RTCRtpSender::create(Ref<MediaStreamTrack>&& track, Vector<String>&& mediaStreamIds, RTCRtpSenderClient& client)
+{
+ const String& trackKind = track->kind();
+ return adoptRef(*new RTCRtpSender(WTFMove(track), trackKind, WTFMove(mediaStreamIds), client));
+}
+
+Ref<RTCRtpSender> RTCRtpSender::create(const String& trackKind, Vector<String>&& mediaStreamIds, RTCRtpSenderClient& client)
+{
+ return adoptRef(*new RTCRtpSender(nullptr, trackKind, WTFMove(mediaStreamIds), client));
+}
+
+RTCRtpSender::RTCRtpSender(RefPtr<MediaStreamTrack>&& track, const String& trackKind, Vector<String>&& mediaStreamIds, RTCRtpSenderClient& client)
+ : RTCRtpSenderReceiverBase()
+ , m_trackKind(trackKind)
+ , m_mediaStreamIds(WTFMove(mediaStreamIds))
+ , m_client(&client)
+{
+ setTrack(WTFMove(track));
+}
+
+void RTCRtpSender::setTrack(RefPtr<MediaStreamTrack>&& track)
+{
+ // Save the id from the first non-null track set. That id will be used to negotiate the sender
+ // even if the track is replaced.
+ if (!m_track && track)
+ m_trackId = track->id();
+
+ m_track = WTFMove(track);
+}
+
+ExceptionOr<void> RTCRtpSender::replaceTrack(Ref<MediaStreamTrack>&& withTrack, DOMPromise<void>&& promise)
+{
+ if (isStopped()) {
+ promise.reject(INVALID_STATE_ERR);
+ return { };
+ }
+
+ if (m_trackKind != withTrack->kind())
+ return Exception { TypeError };
+
+ m_client->replaceTrack(*this, WTFMove(withTrack), WTFMove(promise));
+
+ return { };
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.h b/Source/WebCore/Modules/mediastream/RTCRtpSender.h
new file mode 100644
index 000000000..95bea8b7b
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "PeerConnectionBackend.h"
+#include "RTCRtpSenderReceiverBase.h"
+
+namespace WebCore {
+
+class RTCRtpSenderClient {
+public:
+ virtual void replaceTrack(RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromise<void>&&) = 0;
+
+ virtual ~RTCRtpSenderClient() { }
+};
+
+class RTCRtpSender : public RTCRtpSenderReceiverBase {
+public:
+ static Ref<RTCRtpSender> create(Ref<MediaStreamTrack>&&, Vector<String>&& mediaStreamIds, RTCRtpSenderClient&);
+ static Ref<RTCRtpSender> create(const String& trackKind, Vector<String>&& mediaStreamIds, RTCRtpSenderClient&);
+
+ const String& trackId() const { return m_trackId; }
+ const String& trackKind() const { return m_trackKind; }
+
+ const Vector<String>& mediaStreamIds() const { return m_mediaStreamIds; }
+ void setMediaStreamIds(Vector<String>&& mediaStreamIds) { m_mediaStreamIds = WTFMove(mediaStreamIds); }
+
+ bool isStopped() const { return !m_client; }
+ void stop() { m_client = nullptr; }
+ void setTrack(RefPtr<MediaStreamTrack>&&);
+
+ ExceptionOr<void> replaceTrack(Ref<MediaStreamTrack>&&, DOMPromise<void>&&);
+
+private:
+ RTCRtpSender(RefPtr<MediaStreamTrack>&&, const String& trackKind, Vector<String>&& mediaStreamIds, RTCRtpSenderClient&);
+
+ String m_trackId;
+ String m_trackKind;
+ Vector<String> m_mediaStreamIds;
+ RTCRtpSenderClient* m_client;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.idl b/Source/WebCore/Modules/mediastream/RTCRtpSender.idl
new file mode 100644
index 000000000..21f91fd8e
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.idl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_RTC,
+ EnabledAtRuntime=PeerConnection,
+] interface RTCRtpSender {
+ readonly attribute MediaStreamTrack? track;
+
+ [MayThrowException] Promise<void> replaceTrack(MediaStreamTrack withTrack);
+};
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.h b/Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.h
new file mode 100644
index 000000000..3dd219a26
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "MediaStreamTrack.h"
+#include "ScriptWrappable.h"
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class MediaStreamTrack;
+
+class RTCRtpSenderReceiverBase : public RefCounted<RTCRtpSenderReceiverBase>, public ScriptWrappable {
+public:
+ virtual ~RTCRtpSenderReceiverBase() = default;
+
+ MediaStreamTrack* track() { return m_track.get(); }
+
+protected:
+ RTCRtpSenderReceiverBase() = default;
+
+ RTCRtpSenderReceiverBase(Ref<MediaStreamTrack>&& track)
+ : m_track(WTFMove(track))
+ { }
+
+ RefPtr<MediaStreamTrack> m_track;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.cpp b/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.cpp
new file mode 100644
index 000000000..733db7be0
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RTCRtpTransceiver.h"
+
+#if ENABLE(WEB_RTC)
+
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+#define STRING_FUNCTION(name) \
+ static const String& name##String() \
+ { \
+ static NeverDestroyed<const String> name { ASCIILiteral(#name) }; \
+ return name; \
+ }
+
+STRING_FUNCTION(sendrecv)
+STRING_FUNCTION(sendonly)
+STRING_FUNCTION(recvonly)
+STRING_FUNCTION(inactive)
+
+String RTCRtpTransceiver::getNextMid()
+{
+ static unsigned mid = 0;
+ return String::number(++mid);
+}
+
+RTCRtpTransceiver::RTCRtpTransceiver(Ref<RTCRtpSender>&& sender, Ref<RTCRtpReceiver>&& receiver)
+ : m_direction(Direction::Sendrecv)
+ , m_sender(WTFMove(sender))
+ , m_receiver(WTFMove(receiver))
+ , m_iceTransport(RTCIceTransport::create())
+{
+}
+
+const String& RTCRtpTransceiver::directionString() const
+{
+ switch (m_direction) {
+ case Direction::Sendrecv: return sendrecvString();
+ case Direction::Sendonly: return sendonlyString();
+ case Direction::Recvonly: return recvonlyString();
+ case Direction::Inactive: return inactiveString();
+ }
+
+ ASSERT_NOT_REACHED();
+ return inactiveString();
+}
+
+bool RTCRtpTransceiver::hasSendingDirection() const
+{
+ return m_direction == Direction::Sendrecv || m_direction == Direction::Sendonly;
+}
+
+void RTCRtpTransceiver::enableSendingDirection()
+{
+ if (m_direction == Direction::Recvonly)
+ m_direction = Direction::Sendrecv;
+ else if (m_direction == Direction::Inactive)
+ m_direction = Direction::Sendonly;
+}
+
+void RTCRtpTransceiver::disableSendingDirection()
+{
+ if (m_direction == Direction::Sendrecv)
+ m_direction = Direction::Recvonly;
+ else if (m_direction == Direction::Sendonly)
+ m_direction = Direction::Inactive;
+}
+
+void RtpTransceiverSet::append(Ref<RTCRtpTransceiver>&& transceiver)
+{
+ m_senders.append(transceiver->sender());
+ m_receivers.append(transceiver->receiver());
+
+ m_transceivers.append(WTFMove(transceiver));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.h b/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.h
new file mode 100644
index 000000000..e000cb2c1
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2016 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "RTCIceTransport.h"
+#include "RTCRtpReceiver.h"
+#include "RTCRtpSender.h"
+#include "ScriptWrappable.h"
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class RTCRtpTransceiver : public RefCounted<RTCRtpTransceiver>, public ScriptWrappable {
+public:
+ // This enum is mirrored in RTCPeerConnection.h
+ enum class Direction { Sendrecv, Sendonly, Recvonly, Inactive };
+
+ static Ref<RTCRtpTransceiver> create(Ref<RTCRtpSender>&& sender, Ref<RTCRtpReceiver>&& receiver) { return adoptRef(*new RTCRtpTransceiver(WTFMove(sender), WTFMove(receiver))); }
+ virtual ~RTCRtpTransceiver() { }
+
+ bool hasSendingDirection() const;
+ void enableSendingDirection();
+ void disableSendingDirection();
+
+ const String& directionString() const;
+ Direction direction() const { return m_direction; }
+ void setDirection(Direction direction) { m_direction = direction; }
+
+ const String& provisionalMid() const { return m_provisionalMid; }
+ void setProvisionalMid(const String& provisionalMid) { m_provisionalMid = provisionalMid; }
+
+ const String& mid() const { return m_mid; }
+ void setMid(const String& mid) { m_mid = mid; }
+
+ RTCRtpSender& sender() { return m_sender.get(); }
+ RTCRtpReceiver& receiver() { return m_receiver.get(); }
+
+ bool stopped() const { return m_stopped; }
+ void stop() { m_stopped = true; }
+
+ // FIXME: Temporary solution to keep track of ICE states for this transceiver. Later, each
+ // sender and receiver will have up to two DTLS transports, which in turn will have an ICE
+ // transport each.
+ RTCIceTransport& iceTransport() { return m_iceTransport.get(); }
+
+ static String getNextMid();
+
+private:
+ RTCRtpTransceiver(Ref<RTCRtpSender>&&, Ref<RTCRtpReceiver>&&);
+
+ String m_provisionalMid;
+ String m_mid;
+
+ Direction m_direction;
+
+ Ref<RTCRtpSender> m_sender;
+ Ref<RTCRtpReceiver> m_receiver;
+
+ bool m_stopped { false };
+
+ Ref<RTCIceTransport> m_iceTransport;
+};
+
+class RtpTransceiverSet {
+public:
+ const Vector<RefPtr<RTCRtpTransceiver>>& list() const { return m_transceivers; }
+ void append(Ref<RTCRtpTransceiver>&&);
+
+ const Vector<std::reference_wrapper<RTCRtpSender>>& senders() const { return m_senders; }
+ const Vector<std::reference_wrapper<RTCRtpReceiver>>& receivers() const { return m_receivers; }
+
+private:
+ Vector<RefPtr<RTCRtpTransceiver>> m_transceivers;
+
+ Vector<std::reference_wrapper<RTCRtpSender>> m_senders;
+ Vector<std::reference_wrapper<RTCRtpReceiver>> m_receivers;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.idl b/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.idl
new file mode 100644
index 000000000..68cf1ea48
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCRtpTransceiver.idl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_RTC,
+ EnabledAtRuntime=PeerConnection,
+] interface RTCRtpTransceiver {
+ readonly attribute DOMString? mid;
+ readonly attribute RTCRtpSender sender;
+ readonly attribute RTCRtpReceiver receiver;
+ readonly attribute boolean stopped;
+ readonly attribute RTCRtpTransceiverDirection direction;
+
+ void setDirection(RTCRtpTransceiverDirection direction);
+ void stop();
+};
+
+// This enum is mirrored in RTCPeerConnection.idl
+enum RTCRtpTransceiverDirection { "sendrecv", "sendonly", "recvonly", "inactive" };
diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp b/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp
index 85bfb5c31..4dab0632b 100644
--- a/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp
+++ b/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp
@@ -30,84 +30,28 @@
*/
#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
#include "RTCSessionDescription.h"
-#include "Dictionary.h"
-#include "ExceptionCode.h"
-#include "RTCSessionDescriptionDescriptor.h"
+#if ENABLE(WEB_RTC)
namespace WebCore {
-static bool verifyType(const String& type)
-{
- return type == "offer" || type == "pranswer" || type == "answer";
-}
-
-PassRefPtr<RTCSessionDescription> RTCSessionDescription::create(const Dictionary& dictionary, ExceptionCode& ec)
-{
- String type;
- bool ok = dictionary.get("type", type);
- if (ok && !verifyType(type)) {
- ec = TYPE_MISMATCH_ERR;
- return nullptr;
- }
-
- String sdp;
- ok = dictionary.get("sdp", sdp);
- if (ok && sdp.isEmpty()) {
- ec = TYPE_MISMATCH_ERR;
- return nullptr;
- }
-
- return adoptRef(new RTCSessionDescription(RTCSessionDescriptionDescriptor::create(type, sdp)));
-}
-
-PassRefPtr<RTCSessionDescription> RTCSessionDescription::create(PassRefPtr<RTCSessionDescriptionDescriptor> descriptor)
-{
- ASSERT(descriptor);
- return adoptRef(new RTCSessionDescription(descriptor));
-}
-
-RTCSessionDescription::RTCSessionDescription(PassRefPtr<RTCSessionDescriptionDescriptor> descriptor)
- : m_descriptor(descriptor)
-{
-}
-
-RTCSessionDescription::~RTCSessionDescription()
-{
-}
-
-const String& RTCSessionDescription::type() const
-{
- return m_descriptor->type();
-}
-
-void RTCSessionDescription::setType(const String& type, ExceptionCode& ec)
-{
- if (verifyType(type))
- m_descriptor->setType(type);
- else
- ec = TYPE_MISMATCH_ERR;
-}
-
-const String& RTCSessionDescription::sdp() const
+inline RTCSessionDescription::RTCSessionDescription(SdpType type, const String& sdp)
+ : m_type(type)
+ , m_sdp(sdp)
{
- return m_descriptor->sdp();
}
-void RTCSessionDescription::setSdp(const String& sdp)
+Ref<RTCSessionDescription> RTCSessionDescription::create(const Init& dictionary)
{
- m_descriptor->setSdp(sdp);
+ return create(dictionary.type, dictionary.sdp);
}
-RTCSessionDescriptionDescriptor* RTCSessionDescription::descriptor()
+Ref<RTCSessionDescription> RTCSessionDescription::create(SdpType type, const String& sdp)
{
- return m_descriptor.get();
+ return adoptRef(*new RTCSessionDescription(type, sdp));
}
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescription.h b/Source/WebCore/Modules/mediastream/RTCSessionDescription.h
index fafe2b65a..df3fc6b7a 100644
--- a/Source/WebCore/Modules/mediastream/RTCSessionDescription.h
+++ b/Source/WebCore/Modules/mediastream/RTCSessionDescription.h
@@ -28,44 +28,38 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCSessionDescription_h
-#define RTCSessionDescription_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
-#include "ExceptionBase.h"
+#include "ExceptionOr.h"
#include "ScriptWrappable.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/text/WTFString.h>
namespace WebCore {
-class Dictionary;
-class RTCSessionDescriptionDescriptor;
-
class RTCSessionDescription : public RefCounted<RTCSessionDescription>, public ScriptWrappable {
public:
- static PassRefPtr<RTCSessionDescription> create(const Dictionary&, ExceptionCode&);
- static PassRefPtr<RTCSessionDescription> create(PassRefPtr<RTCSessionDescriptionDescriptor>);
- virtual ~RTCSessionDescription();
+ enum class SdpType { Offer, Pranswer, Answer, Rollback };
- const String& type() const;
- void setType(const String&, ExceptionCode&);
+ struct Init {
+ SdpType type;
+ String sdp;
+ };
+ static Ref<RTCSessionDescription> create(const Init&);
+ static Ref<RTCSessionDescription> create(SdpType, const String& sdp);
- const String& sdp() const;
- void setSdp(const String&);
+ SdpType type() const { return m_type; }
- RTCSessionDescriptionDescriptor* descriptor();
+ const String& sdp() const { return m_sdp; }
+ void setSdp(const String& sdp) { m_sdp = sdp; }
private:
- explicit RTCSessionDescription(PassRefPtr<RTCSessionDescriptionDescriptor>);
+ explicit RTCSessionDescription(SdpType, const String& sdp);
- RefPtr<RTCSessionDescriptionDescriptor> m_descriptor;
+ SdpType m_type;
+ String m_sdp;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCSessionDescription_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescription.idl b/Source/WebCore/Modules/mediastream/RTCSessionDescription.idl
index e62998b16..27c6571ea 100644
--- a/Source/WebCore/Modules/mediastream/RTCSessionDescription.idl
+++ b/Source/WebCore/Modules/mediastream/RTCSessionDescription.idl
@@ -30,11 +30,22 @@
*/
[
- Conditional=MEDIA_STREAM,
- CustomConstructor(optional Dictionary dictionary),
- ConstructorRaisesException
+ Conditional=WEB_RTC,
+ Constructor(RTCSessionDescriptionInit descriptionInitDict),
+ EnabledAtRuntime=PeerConnection,
+ ImplementationLacksVTable,
+ PrivateIdentifier,
+ PublicIdentifier,
] interface RTCSessionDescription {
- [SetterRaisesException] attribute DOMString type;
- attribute DOMString sdp;
+ [SetterMayThrowException] readonly attribute RTCSdpType type;
+ readonly attribute DOMString sdp;
+
+ serializer = {type, sdp};
};
+enum RTCSdpType { "offer", "pranswer", "answer", "rollback" };
+
+dictionary RTCSessionDescriptionInit {
+ required RTCSdpType type;
+ DOMString sdp = "";
+};
diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescriptionRequestImpl.cpp b/Source/WebCore/Modules/mediastream/RTCSessionDescriptionRequestImpl.cpp
deleted file mode 100644
index 872a54e18..000000000
--- a/Source/WebCore/Modules/mediastream/RTCSessionDescriptionRequestImpl.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "RTCSessionDescriptionRequestImpl.h"
-
-#include "RTCPeerConnection.h"
-#include "RTCPeerConnectionErrorCallback.h"
-#include "RTCSessionDescription.h"
-#include "RTCSessionDescriptionCallback.h"
-#include "RTCSessionDescriptionDescriptor.h"
-
-namespace WebCore {
-
-PassRefPtr<RTCSessionDescriptionRequestImpl> RTCSessionDescriptionRequestImpl::create(ScriptExecutionContext* context, PassRefPtr<RTCSessionDescriptionCallback> successCallback, PassRefPtr<RTCPeerConnectionErrorCallback> errorCallback)
-{
- RefPtr<RTCSessionDescriptionRequestImpl> request = adoptRef(new RTCSessionDescriptionRequestImpl(context, successCallback, errorCallback));
- request->suspendIfNeeded();
- return request.release();
-}
-
-RTCSessionDescriptionRequestImpl::RTCSessionDescriptionRequestImpl(ScriptExecutionContext* context, PassRefPtr<RTCSessionDescriptionCallback> successCallback, PassRefPtr<RTCPeerConnectionErrorCallback> errorCallback)
- : ActiveDOMObject(context)
- , m_successCallback(successCallback)
- , m_errorCallback(errorCallback)
-{
-}
-
-RTCSessionDescriptionRequestImpl::~RTCSessionDescriptionRequestImpl()
-{
-}
-
-void RTCSessionDescriptionRequestImpl::requestSucceeded(PassRefPtr<RTCSessionDescriptionDescriptor> descriptor)
-{
- if (m_successCallback) {
- RefPtr<RTCSessionDescription> sessionDescription = RTCSessionDescription::create(descriptor);
- m_successCallback->handleEvent(sessionDescription.get());
- }
-
- clear();
-}
-
-void RTCSessionDescriptionRequestImpl::requestFailed(const String& error)
-{
- if (m_errorCallback)
- m_errorCallback->handleEvent(DOMError::create(error).get());
-
- clear();
-}
-
-void RTCSessionDescriptionRequestImpl::stop()
-{
- clear();
-}
-
-void RTCSessionDescriptionRequestImpl::clear()
-{
- m_successCallback.clear();
- m_errorCallback.clear();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/RTCStatsCallback.h b/Source/WebCore/Modules/mediastream/RTCStatsCallback.h
deleted file mode 100644
index 419b82025..000000000
--- a/Source/WebCore/Modules/mediastream/RTCStatsCallback.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTCStatsCallback_h
-#define RTCStatsCallback_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class RTCStatsResponse;
-
-class RTCStatsCallback : public RefCounted<RTCStatsCallback> {
-public:
- virtual ~RTCStatsCallback() { }
- virtual bool handleEvent(RTCStatsResponse*) = 0;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCStatsCallback_h
diff --git a/Source/WebCore/Modules/mediastream/RTCStatsReport.cpp b/Source/WebCore/Modules/mediastream/RTCStatsReport.cpp
index 27937eba3..146415b89 100644
--- a/Source/WebCore/Modules/mediastream/RTCStatsReport.cpp
+++ b/Source/WebCore/Modules/mediastream/RTCStatsReport.cpp
@@ -24,51 +24,12 @@
*/
#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
#include "RTCStatsReport.h"
-#include <wtf/text/StringHash.h>
+#if ENABLE(WEB_RTC)
namespace WebCore {
-PassRefPtr<RTCStatsReport> RTCStatsReport::create(const String& id, const String& type, double timestamp)
-{
- return adoptRef(new RTCStatsReport(id, type, timestamp));
-}
-
-RTCStatsReport::RTCStatsReport(const String& id, const String& type, double timestamp)
- : m_id(id)
- , m_type(type)
- , m_timestamp(timestamp)
-{
-}
-
-Vector<String> RTCStatsReport::names() const
-{
- Vector<String> result;
- for (HashMap<String, String>::const_iterator it = m_stats.begin(); it != m_stats.end(); ++it) {
- result.append(it->key);
- }
- return result;
-}
-
-const PassRefPtr<RTCStatsReport> RTCStatsReport::local()
-{
- return this;
-}
-
-const PassRefPtr<RTCStatsReport> RTCStatsReport::remote()
-{
- return this;
-}
-
-void RTCStatsReport::addStatistic(const String& name, const String& value)
-{
- m_stats.add(name, value);
-}
-
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCStatsReport.h b/Source/WebCore/Modules/mediastream/RTCStatsReport.h
index f7b8afe29..3f4918020 100644
--- a/Source/WebCore/Modules/mediastream/RTCStatsReport.h
+++ b/Source/WebCore/Modules/mediastream/RTCStatsReport.h
@@ -22,44 +22,19 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCStatsReport_h
-#define RTCStatsReport_h
+#pragma once
-#include "ScriptWrappable.h"
-#include <wtf/HashMap.h>
-#include <wtf/PassRefPtr.h>
+#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
namespace WebCore {
-class RTCStatsReport : public RefCounted<RTCStatsReport>, public ScriptWrappable {
+class RTCStatsReport : public RefCounted<RTCStatsReport> {
public:
- static PassRefPtr<RTCStatsReport> create(const String& id, const String& type, double timestamp);
-
- double timestamp() const { return m_timestamp; }
- String id() { return m_id; }
- String type() { return m_type; }
- String stat(const String& name) { return m_stats.get(name); }
- Vector<String> names() const;
-
- // DEPRECATED
- const PassRefPtr<RTCStatsReport> local();
- // DEPRECATED
- const PassRefPtr<RTCStatsReport> remote();
-
- void addStatistic(const String& name, const String& value);
+ static Ref<RTCStatsReport> create() { return adoptRef(*new RTCStatsReport); }
private:
- RTCStatsReport(const String& id, const String& type, double timestamp);
-
- String m_id;
- String m_type;
- double m_timestamp;
- HashMap<String, String> m_stats;
+ RTCStatsReport() = default;
};
} // namespace WebCore
-
-#endif // RTCStatsReport_h
diff --git a/Source/WebCore/Modules/mediastream/RTCStatsReport.idl b/Source/WebCore/Modules/mediastream/RTCStatsReport.idl
index aa04b7358..8452534b3 100644
--- a/Source/WebCore/Modules/mediastream/RTCStatsReport.idl
+++ b/Source/WebCore/Modules/mediastream/RTCStatsReport.idl
@@ -24,15 +24,9 @@
[
NoInterfaceObject,
- Conditional=MEDIA_STREAM,
+ Conditional=WEB_RTC,
ImplementationLacksVTable,
] interface RTCStatsReport {
- readonly attribute Date timestamp;
- readonly attribute DOMString id;
- readonly attribute DOMString type;
- DOMString stat(DOMString name);
- sequence<DOMString> names();
- // DEPRECATED - fake for old RTCStatsElement object.
- readonly attribute RTCStatsReport local;
- readonly attribute RTCStatsReport remote;
+ // FIXME: Make it setlike
+ //readonly maplike<DOMString, object>;
};
diff --git a/Source/WebCore/Modules/mediastream/RTCStatsRequestImpl.cpp b/Source/WebCore/Modules/mediastream/RTCStatsRequestImpl.cpp
deleted file mode 100644
index 26456087c..000000000
--- a/Source/WebCore/Modules/mediastream/RTCStatsRequestImpl.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "RTCStatsRequestImpl.h"
-
-#include "MediaStreamTrack.h"
-#include "RTCStatsCallback.h"
-#include "RTCStatsRequest.h"
-#include "RTCStatsResponse.h"
-
-namespace WebCore {
-
-PassRefPtr<RTCStatsRequestImpl> RTCStatsRequestImpl::create(ScriptExecutionContext* context, PassRefPtr<RTCStatsCallback> callback, PassRefPtr<MediaStreamTrack> selector)
-{
- RefPtr<RTCStatsRequestImpl> request = adoptRef(new RTCStatsRequestImpl(context, callback, selector));
- request->suspendIfNeeded();
- return request.release();
-}
-
-RTCStatsRequestImpl::RTCStatsRequestImpl(ScriptExecutionContext* context, PassRefPtr<RTCStatsCallback> callback, PassRefPtr<MediaStreamTrack> selector)
- : ActiveDOMObject(context)
- , m_successCallback(callback)
- , m_track(selector)
-{
-}
-
-RTCStatsRequestImpl::~RTCStatsRequestImpl()
-{
-}
-
-PassRefPtr<RTCStatsResponseBase> RTCStatsRequestImpl::createResponse()
-{
- return RTCStatsResponse::create();
-}
-
-bool RTCStatsRequestImpl::hasSelector()
-{
- return m_track;
-}
-
-MediaStreamTrack* RTCStatsRequestImpl::track()
-{
- return m_track.get();
-}
-
-void RTCStatsRequestImpl::requestSucceeded(PassRefPtr<RTCStatsResponseBase> response)
-{
- if (!m_successCallback)
- return;
- m_successCallback->handleEvent(static_cast<RTCStatsResponse*>(response.get()));
- clear();
-}
-
-void RTCStatsRequestImpl::stop()
-{
- clear();
-}
-
-void RTCStatsRequestImpl::clear()
-{
- m_successCallback.clear();
-}
-
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/RTCStatsRequestImpl.h b/Source/WebCore/Modules/mediastream/RTCStatsRequestImpl.h
deleted file mode 100644
index b95f4503c..000000000
--- a/Source/WebCore/Modules/mediastream/RTCStatsRequestImpl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTCStatsRequestImpl_h
-#define RTCStatsRequestImpl_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "ActiveDOMObject.h"
-#include "RTCStatsRequest.h"
-#include "RTCStatsResponse.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class RTCStatsCallback;
-
-class RTCStatsRequestImpl : public RTCStatsRequest, public ActiveDOMObject {
-public:
- static PassRefPtr<RTCStatsRequestImpl> create(ScriptExecutionContext*, PassRefPtr<RTCStatsCallback>, PassRefPtr<MediaStreamTrack>);
- virtual ~RTCStatsRequestImpl();
-
- virtual PassRefPtr<RTCStatsResponseBase> createResponse() override;
- virtual bool hasSelector() override;
- virtual MediaStreamTrack* track() override;
-
- virtual void requestSucceeded(PassRefPtr<RTCStatsResponseBase>) override;
-
- // ActiveDOMObject
- virtual void stop() override;
-
-private:
- RTCStatsRequestImpl(ScriptExecutionContext*, PassRefPtr<RTCStatsCallback>, PassRefPtr<MediaStreamTrack>);
-
- void clear();
-
- RefPtr<RTCStatsCallback> m_successCallback;
- RefPtr<MediaStreamTrack> m_track;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCStatsRequestImpl_h
diff --git a/Source/WebCore/Modules/mediastream/RTCStatsResponse.cpp b/Source/WebCore/Modules/mediastream/RTCStatsResponse.cpp
deleted file mode 100644
index c3b41fe19..000000000
--- a/Source/WebCore/Modules/mediastream/RTCStatsResponse.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "RTCStatsResponse.h"
-
-namespace WebCore {
-
-PassRefPtr<RTCStatsResponse> RTCStatsResponse::create()
-{
- return adoptRef(new RTCStatsResponse());
-}
-
-RTCStatsResponse::RTCStatsResponse()
-{
-}
-
-PassRefPtr<RTCStatsReport> RTCStatsResponse::namedItem(const AtomicString& name)
-{
- if (m_idmap.find(name) != m_idmap.end())
- return m_result[m_idmap.get(name)];
- return nullptr;
-}
-
-bool RTCStatsResponse::canGetItemsForName(const AtomicString& name)
-{
- return m_idmap.contains(name);
-}
-
-size_t RTCStatsResponse::addReport(String id, String type, double timestamp)
-{
- m_result.append(RTCStatsReport::create(id, type, timestamp));
- m_idmap.add(id, m_result.size() - 1);
- return m_result.size() - 1;
-}
-
-void RTCStatsResponse::addStatistic(size_t report, String name, String value)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(report < m_result.size());
- m_result[report]->addStatistic(name, value);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/RTCStatsResponse.h b/Source/WebCore/Modules/mediastream/RTCStatsResponse.h
deleted file mode 100644
index 30e89e4a1..000000000
--- a/Source/WebCore/Modules/mediastream/RTCStatsResponse.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTCStatsResponse_h
-#define RTCStatsResponse_h
-
-#include "ActiveDOMObject.h"
-#include "DOMError.h"
-#include "DOMStringList.h"
-#include "Event.h"
-#include "EventListener.h"
-#include "EventNames.h"
-#include "EventTarget.h"
-#include "MediaStreamTrack.h"
-#include "RTCStatsReport.h"
-#include "RTCStatsResponseBase.h"
-#include "ScriptWrappable.h"
-#include <wtf/HashMap.h>
-
-namespace WebCore {
-
-class RTCStatsResponse : public RTCStatsResponseBase, public ScriptWrappable {
-public:
- static PassRefPtr<RTCStatsResponse> create();
-
- const Vector<RefPtr<RTCStatsReport>>& result() const { return m_result; };
-
- PassRefPtr<RTCStatsReport> namedItem(const AtomicString&);
- bool canGetItemsForName(const AtomicString&);
-
- virtual size_t addReport(String id, String type, double timestamp) override;
- virtual void addStatistic(size_t report, String name, String value) override;
-
-private:
- RTCStatsResponse();
- Vector<RefPtr<RTCStatsReport>> m_result;
- HashMap<String, int> m_idmap;
-};
-
-} // namespace WebCore
-
-#endif // RTCStatsResponse_h
diff --git a/Source/WebCore/Modules/mediastream/RTCTrackEvent.cpp b/Source/WebCore/Modules/mediastream/RTCTrackEvent.cpp
new file mode 100644
index 000000000..c090157f3
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCTrackEvent.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RTCTrackEvent.h"
+
+#if ENABLE(WEB_RTC)
+
+#include "MediaStream.h"
+#include "MediaStreamTrack.h"
+#include "RTCRtpTransceiver.h"
+
+namespace WebCore {
+
+Ref<RTCTrackEvent> RTCTrackEvent::create(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<RTCRtpReceiver>&& receiver, RefPtr<MediaStreamTrack>&& track, Vector<RefPtr<MediaStream>>&& streams, RefPtr<RTCRtpTransceiver>&& transceiver)
+{
+ return adoptRef(*new RTCTrackEvent(type, canBubble, cancelable, WTFMove(receiver), WTFMove(track), WTFMove(streams), WTFMove(transceiver)));
+}
+
+Ref<RTCTrackEvent> RTCTrackEvent::create(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
+{
+ return adoptRef(*new RTCTrackEvent(type, initializer, isTrusted));
+}
+
+RTCTrackEvent::RTCTrackEvent(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<RTCRtpReceiver>&& receiver, RefPtr<MediaStreamTrack>&& track, Vector<RefPtr<MediaStream>>&& streams, RefPtr<RTCRtpTransceiver>&& transceiver)
+ : Event(type, canBubble, cancelable)
+ , m_receiver(WTFMove(receiver))
+ , m_track(WTFMove(track))
+ , m_streams(WTFMove(streams))
+ , m_transceiver(WTFMove(transceiver))
+{
+}
+
+RTCTrackEvent::RTCTrackEvent(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
+ : Event(type, initializer, isTrusted)
+ , m_receiver(initializer.receiver)
+ , m_track(initializer.track)
+ , m_streams(initializer.streams)
+ , m_transceiver(initializer.transceiver)
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCTrackEvent.h b/Source/WebCore/Modules/mediastream/RTCTrackEvent.h
new file mode 100644
index 000000000..3617cbd36
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCTrackEvent.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "Event.h"
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+class MediaStream;
+class MediaStreamTrack;
+class RTCRtpReceiver;
+class RTCRtpTransceiver;
+
+typedef Vector<RefPtr<MediaStream>> MediaStreamArray;
+
+class RTCTrackEvent : public Event {
+public:
+ static Ref<RTCTrackEvent> create(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<RTCRtpReceiver>&&, RefPtr<MediaStreamTrack>&&, MediaStreamArray&&, RefPtr<RTCRtpTransceiver>&&);
+
+ struct Init : EventInit {
+ RefPtr<RTCRtpReceiver> receiver;
+ RefPtr<MediaStreamTrack> track;
+ MediaStreamArray streams;
+ RefPtr<RTCRtpTransceiver> transceiver;
+ };
+ static Ref<RTCTrackEvent> create(const AtomicString& type, const Init&, IsTrusted = IsTrusted::No);
+
+ RTCRtpReceiver* receiver() const { return m_receiver.get(); }
+ MediaStreamTrack* track() const { return m_track.get(); }
+ const MediaStreamArray& streams() const { return m_streams; }
+ RTCRtpTransceiver* transceiver() const { return m_transceiver.get(); }
+
+ virtual EventInterface eventInterface() const { return RTCTrackEventInterfaceType; }
+
+private:
+ RTCTrackEvent(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<RTCRtpReceiver>&&, RefPtr<MediaStreamTrack>&&, MediaStreamArray&&, RefPtr<RTCRtpTransceiver>&&);
+ RTCTrackEvent(const AtomicString& type, const Init&, IsTrusted);
+
+ RefPtr<RTCRtpReceiver> m_receiver;
+ RefPtr<MediaStreamTrack> m_track;
+ MediaStreamArray m_streams;
+ RefPtr<RTCRtpTransceiver> m_transceiver;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/RTCTrackEvent.idl b/Source/WebCore/Modules/mediastream/RTCTrackEvent.idl
new file mode 100644
index 000000000..04fe5558a
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/RTCTrackEvent.idl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=WEB_RTC,
+ Constructor(DOMString type, RTCTrackEventInit eventInitDict),
+ EnabledAtRuntime=PeerConnection,
+] interface RTCTrackEvent : Event {
+ readonly attribute RTCRtpReceiver receiver;
+ readonly attribute MediaStreamTrack track;
+ readonly attribute FrozenArray<MediaStream> streams;
+ readonly attribute RTCRtpTransceiver transceiver;
+};
+
+dictionary RTCTrackEventInit : EventInit {
+ required RTCRtpReceiver receiver;
+ required MediaStreamTrack track;
+ sequence<MediaStream> streams = [];
+ required RTCRtpTransceiver transceiver;
+};
diff --git a/Source/WebCore/Modules/mediastream/SDPProcessor.cpp b/Source/WebCore/Modules/mediastream/SDPProcessor.cpp
new file mode 100644
index 000000000..9254fdc07
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/SDPProcessor.cpp
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2015, 2016 Ericsson AB. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_RTC)
+#include "SDPProcessor.h"
+
+#include "CommonVM.h"
+#include "Document.h"
+#include "Frame.h"
+#include "SDPProcessorScriptResource.h"
+#include "ScriptController.h"
+#include "ScriptSourceCode.h"
+#include "inspector/InspectorValues.h"
+#include <bindings/ScriptObject.h>
+#include <wtf/NeverDestroyed.h>
+
+using namespace Inspector;
+
+namespace WebCore {
+
+#define STRING_FUNCTION(name) \
+ static const String& name##String() \
+ { \
+ static NeverDestroyed<const String> name { ASCIILiteral(#name) }; \
+ return name; \
+ }
+
+STRING_FUNCTION(address)
+STRING_FUNCTION(apt)
+STRING_FUNCTION(candidates)
+STRING_FUNCTION(ccmfir)
+STRING_FUNCTION(channels)
+STRING_FUNCTION(clockRate)
+STRING_FUNCTION(cname)
+STRING_FUNCTION(componentId)
+STRING_FUNCTION(dtls)
+STRING_FUNCTION(encodingName)
+STRING_FUNCTION(fingerprint)
+STRING_FUNCTION(fingerprintHashFunction)
+STRING_FUNCTION(foundation)
+STRING_FUNCTION(ice)
+STRING_FUNCTION(mediaDescriptions)
+STRING_FUNCTION(mediaStreamId)
+STRING_FUNCTION(mediaStreamTrackId)
+STRING_FUNCTION(mid)
+STRING_FUNCTION(mode)
+STRING_FUNCTION(mux)
+STRING_FUNCTION(nack)
+STRING_FUNCTION(nackpli)
+STRING_FUNCTION(originator)
+STRING_FUNCTION(packetizationMode)
+STRING_FUNCTION(parameters)
+STRING_FUNCTION(password)
+STRING_FUNCTION(payloads)
+STRING_FUNCTION(port)
+STRING_FUNCTION(priority)
+STRING_FUNCTION(relatedAddress)
+STRING_FUNCTION(relatedPort)
+STRING_FUNCTION(rtcp)
+STRING_FUNCTION(rtcpAddress)
+STRING_FUNCTION(rtcpPort)
+STRING_FUNCTION(rtxTime)
+STRING_FUNCTION(sessionId)
+STRING_FUNCTION(sessionVersion)
+STRING_FUNCTION(setup)
+STRING_FUNCTION(ssrcs)
+STRING_FUNCTION(tcpType)
+STRING_FUNCTION(transport)
+STRING_FUNCTION(type)
+STRING_FUNCTION(ufrag)
+
+SDPProcessor::SDPProcessor(ScriptExecutionContext* context)
+ : ContextDestructionObserver(context)
+{
+}
+
+// Note that MediaEndpointSessionConfiguration is a "flatter" structure that the JSON representation. For
+// example, the JSON representation has an "ice" object which collects a set of properties under a
+// namespace. MediaEndpointSessionConfiguration has "ice"-prefixes on the corresponding properties.
+
+static RefPtr<InspectorObject> createCandidateObject(const IceCandidate& candidate)
+{
+ RefPtr<InspectorObject> candidateObject = InspectorObject::create();
+
+ candidateObject->setString(typeString(), candidate.type);
+ candidateObject->setString(foundationString(), candidate.foundation);
+ candidateObject->setInteger(componentIdString(), candidate.componentId);
+ candidateObject->setString(transportString(), candidate.transport);
+ candidateObject->setInteger(priorityString(), candidate.priority);
+ candidateObject->setString(addressString(), candidate.address);
+ candidateObject->setInteger(portString(), candidate.port);
+ if (!candidate.tcpType.isEmpty())
+ candidateObject->setString(tcpTypeString(), candidate.tcpType);
+ if (candidate.type.convertToASCIIUppercase() != "HOST") {
+ candidateObject->setString(relatedAddressString(), candidate.relatedAddress);
+ candidateObject->setInteger(relatedPortString(), candidate.relatedPort);
+ }
+
+ return candidateObject;
+}
+
+static IceCandidate createCandidate(const InspectorObject& candidateObject)
+{
+ IceCandidate candidate;
+ String stringValue;
+ unsigned intValue;
+
+ if (candidateObject.getString(typeString(), stringValue))
+ candidate.type = stringValue;
+
+ if (candidateObject.getString(foundationString(), stringValue))
+ candidate.foundation = stringValue;
+
+ if (candidateObject.getInteger(componentIdString(), intValue))
+ candidate.componentId = intValue;
+
+ if (candidateObject.getString(transportString(), stringValue))
+ candidate.transport = stringValue;
+
+ if (candidateObject.getInteger(priorityString(), intValue))
+ candidate.priority = intValue;
+
+ if (candidateObject.getString(addressString(), stringValue))
+ candidate.address = stringValue;
+
+ if (candidateObject.getInteger(portString(), intValue))
+ candidate.port = intValue;
+
+ if (candidateObject.getString(tcpTypeString(), stringValue))
+ candidate.tcpType = stringValue;
+
+ if (candidateObject.getString(relatedAddressString(), stringValue))
+ candidate.relatedAddress = stringValue;
+
+ if (candidateObject.getInteger(relatedPortString(), intValue))
+ candidate.relatedPort = intValue;
+
+ return candidate;
+}
+
+static RefPtr<MediaEndpointSessionConfiguration> configurationFromJSON(const String& json)
+{
+ RefPtr<InspectorValue> value;
+ if (!InspectorValue::parseJSON(json, value))
+ return nullptr;
+
+ RefPtr<InspectorObject> object;
+ if (!value->asObject(object))
+ return nullptr;
+
+ RefPtr<MediaEndpointSessionConfiguration> configuration = MediaEndpointSessionConfiguration::create();
+
+ String stringValue;
+ unsigned intValue;
+ unsigned long longValue;
+ bool boolValue;
+
+ RefPtr<InspectorObject> originatorObject = InspectorObject::create();
+ if (object->getObject(originatorString(), originatorObject)) {
+ if (originatorObject->getInteger(sessionIdString(), longValue))
+ configuration->setSessionId(longValue);
+ if (originatorObject->getInteger(sessionVersionString(), intValue))
+ configuration->setSessionVersion(intValue);
+ }
+
+ RefPtr<InspectorArray> mediaDescriptionsArray = InspectorArray::create();
+ object->getArray(mediaDescriptionsString(), mediaDescriptionsArray);
+
+ for (unsigned i = 0; i < mediaDescriptionsArray->length(); ++i) {
+ RefPtr<InspectorObject> mediaDescriptionObject = InspectorObject::create();
+ mediaDescriptionsArray->get(i)->asObject(mediaDescriptionObject);
+
+ PeerMediaDescription mediaDescription;
+
+ if (mediaDescriptionObject->getString(typeString(), stringValue))
+ mediaDescription.type = stringValue;
+
+ if (mediaDescriptionObject->getInteger(portString(), intValue))
+ mediaDescription.port = intValue;
+
+ if (mediaDescriptionObject->getString(addressString(), stringValue))
+ mediaDescription.address = stringValue;
+
+ if (mediaDescriptionObject->getString(modeString(), stringValue))
+ mediaDescription.mode = stringValue;
+
+ if (mediaDescriptionObject->getString(midString(), stringValue))
+ mediaDescription.mid = stringValue;
+
+ RefPtr<InspectorArray> payloadsArray = InspectorArray::create();
+ mediaDescriptionObject->getArray(payloadsString(), payloadsArray);
+
+ for (unsigned j = 0; j < payloadsArray->length(); ++j) {
+ RefPtr<InspectorObject> payloadsObject = InspectorObject::create();
+ payloadsArray->get(j)->asObject(payloadsObject);
+
+ MediaPayload payload;
+
+ if (payloadsObject->getInteger(typeString(), intValue))
+ payload.type = intValue;
+
+ if (payloadsObject->getString(encodingNameString(), stringValue))
+ payload.encodingName = stringValue;
+
+ if (payloadsObject->getInteger(clockRateString(), intValue))
+ payload.clockRate = intValue;
+
+ if (payloadsObject->getInteger(channelsString(), intValue))
+ payload.channels = intValue;
+
+ if (payloadsObject->getBoolean(ccmfirString(), boolValue))
+ payload.ccmfir = boolValue;
+
+ if (payloadsObject->getBoolean(nackpliString(), boolValue))
+ payload.nackpli = boolValue;
+
+ if (payloadsObject->getBoolean(nackString(), boolValue))
+ payload.nack = boolValue;
+
+ RefPtr<InspectorObject> parametersObject = InspectorObject::create();
+ if (payloadsObject->getObject(parametersString(), parametersObject)) {
+ if (parametersObject->getInteger(packetizationModeString(), intValue))
+ payload.addParameter("packetizationMode", intValue);
+
+ if (parametersObject->getInteger(aptString(), intValue))
+ payload.addParameter("apt", intValue);
+
+ if (parametersObject->getInteger(rtxTimeString(), intValue))
+ payload.addParameter("rtxTime", intValue);
+ }
+
+ mediaDescription.addPayload(WTFMove(payload));
+ }
+
+ RefPtr<InspectorObject> rtcpObject = InspectorObject::create();
+ if (mediaDescriptionObject->getObject(rtcpString(), rtcpObject)) {
+ if (rtcpObject->getBoolean(muxString(), boolValue))
+ mediaDescription.rtcpMux = boolValue;
+
+ if (rtcpObject->getString(rtcpAddressString(), stringValue))
+ mediaDescription.rtcpAddress = stringValue;
+
+ if (rtcpObject->getInteger(rtcpPortString(), intValue))
+ mediaDescription.rtcpPort = intValue;
+ }
+
+ if (mediaDescriptionObject->getString(mediaStreamIdString(), stringValue))
+ mediaDescription.mediaStreamId = stringValue;
+
+ if (mediaDescriptionObject->getString(mediaStreamTrackIdString(), stringValue))
+ mediaDescription.mediaStreamTrackId = stringValue;
+
+ RefPtr<InspectorObject> dtlsObject = InspectorObject::create();
+ if (mediaDescriptionObject->getObject(dtlsString(), dtlsObject)) {
+ if (dtlsObject->getString(setupString(), stringValue))
+ mediaDescription.dtlsSetup = stringValue;
+
+ if (dtlsObject->getString(fingerprintHashFunctionString(), stringValue))
+ mediaDescription.dtlsFingerprintHashFunction = stringValue;
+
+ if (dtlsObject->getString(fingerprintString(), stringValue))
+ mediaDescription.dtlsFingerprint = stringValue;
+ }
+
+ RefPtr<InspectorArray> ssrcsArray = InspectorArray::create();
+ mediaDescriptionObject->getArray(ssrcsString(), ssrcsArray);
+
+ for (unsigned j = 0; j < ssrcsArray->length(); ++j) {
+ ssrcsArray->get(j)->asInteger(intValue);
+ mediaDescription.addSsrc(intValue);
+ }
+
+ if (mediaDescriptionObject->getString(cnameString(), stringValue))
+ mediaDescription.cname = stringValue;
+
+ RefPtr<InspectorObject> iceObject = InspectorObject::create();
+ if (mediaDescriptionObject->getObject(iceString(), iceObject)) {
+ if (iceObject->getString(ufragString(), stringValue))
+ mediaDescription.iceUfrag = stringValue;
+
+ if (iceObject->getString(passwordString(), stringValue))
+ mediaDescription.icePassword = stringValue;
+
+ RefPtr<InspectorArray> candidatesArray = InspectorArray::create();
+ iceObject->getArray(candidatesString(), candidatesArray);
+
+ for (unsigned j = 0; j < candidatesArray->length(); ++j) {
+ RefPtr<InspectorObject> candidateObject = InspectorObject::create();
+ candidatesArray->get(j)->asObject(candidateObject);
+
+ mediaDescription.addIceCandidate(createCandidate(*candidateObject));
+ }
+ }
+
+ configuration->addMediaDescription(WTFMove(mediaDescription));
+ }
+
+ return configuration;
+}
+
+static std::optional<IceCandidate> iceCandidateFromJSON(const String& json)
+{
+ RefPtr<InspectorValue> value;
+ if (!InspectorValue::parseJSON(json, value))
+ return std::nullopt;
+
+ RefPtr<InspectorObject> candidateObject;
+ if (!value->asObject(candidateObject))
+ return std::nullopt;
+
+ return createCandidate(*candidateObject);
+}
+
+static String configurationToJSON(const MediaEndpointSessionConfiguration& configuration)
+{
+ RefPtr<InspectorObject> object = InspectorObject::create();
+
+ RefPtr<InspectorObject> originatorObject = InspectorObject::create();
+ originatorObject->setDouble(sessionIdString(), configuration.sessionId());
+ originatorObject->setInteger(sessionVersionString(), configuration.sessionVersion());
+ object->setObject(originatorString(), originatorObject);
+
+ RefPtr<InspectorArray> mediaDescriptionsArray = InspectorArray::create();
+
+ for (const auto& mediaDescription : configuration.mediaDescriptions()) {
+ RefPtr<InspectorObject> mediaDescriptionObject = InspectorObject::create();
+
+ mediaDescriptionObject->setString(typeString(), mediaDescription.type);
+ mediaDescriptionObject->setInteger(portString(), mediaDescription.port);
+ mediaDescriptionObject->setString(addressString(), mediaDescription.address);
+ mediaDescriptionObject->setString(modeString(), mediaDescription.mode);
+ mediaDescriptionObject->setString(midString(), mediaDescription.mid);
+
+ RefPtr<InspectorArray> payloadsArray = InspectorArray::create();
+
+ for (auto& payload : mediaDescription.payloads) {
+ RefPtr<InspectorObject> payloadObject = InspectorObject::create();
+
+ payloadObject->setInteger(typeString(), payload.type);
+ payloadObject->setString(encodingNameString(), payload.encodingName);
+ payloadObject->setInteger(clockRateString(), payload.clockRate);
+ payloadObject->setInteger(channelsString(), payload.channels);
+ payloadObject->setBoolean(ccmfirString(), payload.ccmfir);
+ payloadObject->setBoolean(nackpliString(), payload.nackpli);
+ payloadObject->setBoolean(nackString(), payload.nack);
+
+ if (!payload.parameters.isEmpty()) {
+ RefPtr<InspectorObject> parametersObject = InspectorObject::create();
+
+ for (auto& name : payload.parameters.keys())
+ parametersObject->setInteger(name, payload.parameters.get(name));
+
+ payloadObject->setObject(parametersString(), parametersObject);
+ }
+
+ payloadsArray->pushObject(payloadObject);
+ }
+ mediaDescriptionObject->setArray(payloadsString(), payloadsArray);
+
+ RefPtr<InspectorObject> rtcpObject = InspectorObject::create();
+ rtcpObject->setBoolean(muxString(), mediaDescription.rtcpMux);
+ rtcpObject->setString(addressString(), mediaDescription.rtcpAddress);
+ rtcpObject->setInteger(portString(), mediaDescription.rtcpPort);
+ mediaDescriptionObject->setObject(rtcpString(), rtcpObject);
+
+ mediaDescriptionObject->setString(mediaStreamIdString(), mediaDescription.mediaStreamId);
+ mediaDescriptionObject->setString(mediaStreamTrackIdString(), mediaDescription.mediaStreamTrackId);
+
+ RefPtr<InspectorObject> dtlsObject = InspectorObject::create();
+ dtlsObject->setString(setupString(), mediaDescription.dtlsSetup);
+ dtlsObject->setString(fingerprintHashFunctionString(), mediaDescription.dtlsFingerprintHashFunction);
+ dtlsObject->setString(fingerprintString(), mediaDescription.dtlsFingerprint);
+ mediaDescriptionObject->setObject(dtlsString(), dtlsObject);
+
+ RefPtr<InspectorArray> ssrcsArray = InspectorArray::create();
+
+ for (auto ssrc : mediaDescription.ssrcs)
+ ssrcsArray->pushDouble(ssrc);
+ mediaDescriptionObject->setArray(ssrcsString(), ssrcsArray);
+
+ mediaDescriptionObject->setString(cnameString(), mediaDescription.cname);
+
+ RefPtr<InspectorObject> iceObject = InspectorObject::create();
+ iceObject->setString(ufragString(), mediaDescription.iceUfrag);
+ iceObject->setString(passwordString(), mediaDescription.icePassword);
+
+ RefPtr<InspectorArray> candidatesArray = InspectorArray::create();
+
+ for (auto& candidate : mediaDescription.iceCandidates)
+ candidatesArray->pushObject(createCandidateObject(candidate));
+
+ iceObject->setArray(candidatesString(), candidatesArray);
+ mediaDescriptionObject->setObject(iceString(), iceObject);
+
+ mediaDescriptionsArray->pushObject(mediaDescriptionObject);
+ }
+ object->setArray(mediaDescriptionsString(), mediaDescriptionsArray);
+
+ return object->toJSONString();
+}
+
+static String iceCandidateToJSON(const IceCandidate& candidate)
+{
+ return createCandidateObject(candidate)->toJSONString();
+}
+
+SDPProcessor::Result SDPProcessor::generate(const MediaEndpointSessionConfiguration& configuration, String& outSdpString) const
+{
+ String sdpString;
+ if (!callScript("generate", configurationToJSON(configuration), sdpString))
+ return Result::InternalError;
+
+ outSdpString = sdpString;
+ return Result::Success;
+}
+
+SDPProcessor::Result SDPProcessor::parse(const String& sdp, RefPtr<MediaEndpointSessionConfiguration>& outConfiguration) const
+{
+ String scriptOutput;
+ if (!callScript("parse", sdp, scriptOutput))
+ return Result::InternalError;
+
+ if (scriptOutput == "ParseError")
+ return Result::ParseError;
+
+ RefPtr<MediaEndpointSessionConfiguration> configuration = configurationFromJSON(scriptOutput);
+ if (!configuration)
+ return Result::InternalError;
+
+ outConfiguration = configuration;
+ return Result::Success;
+}
+
+SDPProcessor::Result SDPProcessor::generateCandidateLine(const IceCandidate& candidate, String& outCandidateLine) const
+{
+ String candidateLine;
+ if (!callScript("generateCandidateLine", iceCandidateToJSON(candidate), candidateLine))
+ return Result::InternalError;
+
+ outCandidateLine = candidateLine;
+ return Result::Success;
+}
+
+SDPProcessor::ParsingResult SDPProcessor::parseCandidateLine(const String& candidateLine) const
+{
+ String scriptOutput;
+ if (!callScript("parseCandidateLine", candidateLine, scriptOutput))
+ return { Result::InternalError };
+
+ if (scriptOutput == "ParseError")
+ return { Result::ParseError };
+
+ auto candidate = iceCandidateFromJSON(scriptOutput);
+ if (!candidate)
+ return { Result::InternalError };
+ return { WTFMove(candidate.value()) };
+}
+
+bool SDPProcessor::callScript(const String& functionName, const String& argument, String& outResult) const
+{
+ if (!scriptExecutionContext())
+ return false;
+
+ Document* document = downcast<Document>(scriptExecutionContext());
+ if (!document->frame())
+ return false;
+
+ if (!m_isolatedWorld)
+ m_isolatedWorld = DOMWrapperWorld::create(commonVM());
+
+ ScriptController& scriptController = document->frame()->script();
+ JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(*m_isolatedWorld));
+ JSC::VM& vm = globalObject->vm();
+ JSC::JSLockHolder lock(vm);
+ auto scope = DECLARE_CATCH_SCOPE(vm);
+ JSC::ExecState* exec = globalObject->globalExec();
+
+ JSC::JSValue probeFunctionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, "generate"));
+ if (!probeFunctionValue.isFunction()) {
+ URL scriptURL;
+ scriptController.evaluateInWorld(ScriptSourceCode(SDPProcessorScriptResource::scriptString(), scriptURL), *m_isolatedWorld);
+ if (UNLIKELY(scope.exception())) {
+ scope.clearException();
+ return false;
+ }
+ }
+
+ JSC::JSValue functionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, functionName));
+ if (!functionValue.isFunction())
+ return false;
+
+ JSC::JSObject* function = functionValue.toObject(exec);
+ JSC::CallData callData;
+ JSC::CallType callType = function->methodTable()->getCallData(function, callData);
+ if (callType == JSC::CallType::None)
+ return false;
+
+ JSC::MarkedArgumentBuffer argList;
+ argList.append(JSC::jsString(exec, argument));
+
+ JSC::JSValue result = JSC::call(exec, function, callType, callData, globalObject, argList);
+ if (UNLIKELY(scope.exception())) {
+ LOG_ERROR("SDPProcessor script threw in function %s", functionName.ascii().data());
+ scope.clearException();
+ return false;
+ }
+
+ if (!result.isString())
+ return false;
+
+ outResult = asString(result)->value(exec);
+ return true;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/SDPProcessor.h b/Source/WebCore/Modules/mediastream/SDPProcessor.h
new file mode 100644
index 000000000..ca61c9a92
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/SDPProcessor.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "ContextDestructionObserver.h"
+#include "IceCandidate.h"
+#include "MediaEndpointSessionConfiguration.h"
+#include <wtf/RefPtr.h>
+#include <wtf/Variant.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class DOMWrapperWorld;
+class ScriptExecutionContext;
+
+class SDPProcessor : public ContextDestructionObserver {
+public:
+ enum class Result {
+ Success = 1,
+ InternalError = 2,
+ ParseError = 3
+ };
+
+ SDPProcessor(ScriptExecutionContext*);
+
+ Result generate(const MediaEndpointSessionConfiguration&, String& outSdpString) const;
+ Result parse(const String& sdp, RefPtr<MediaEndpointSessionConfiguration>&) const;
+
+ Result generateCandidateLine(const IceCandidate&, String& outCandidateLine) const;
+
+ struct ParsingResult {
+ Variant<IceCandidate, Result> result;
+
+ Result parsingStatus() const { return WTF::holds_alternative<IceCandidate>(result) ? Result::Success : WTF::get<SDPProcessor::Result>(result); }
+ IceCandidate& candidate() { return WTF::get<IceCandidate>(result); }
+ };
+ ParsingResult parseCandidateLine(const String& candidateLine) const;
+
+private:
+ bool callScript(const String& functionName, const String& argument, String& outResult) const;
+
+ mutable RefPtr<DOMWrapperWorld> m_isolatedWorld;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/Modules/mediastream/SourceInfo.cpp b/Source/WebCore/Modules/mediastream/SourceInfo.cpp
deleted file mode 100644
index b116f2fd1..000000000
--- a/Source/WebCore/Modules/mediastream/SourceInfo.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "SourceInfo.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include <wtf/NeverDestroyed.h>
-
-namespace WebCore {
-
-PassRefPtr<SourceInfo> SourceInfo::create(PassRefPtr<TrackSourceInfo> trackSourceInfo)
-{
- return adoptRef(new SourceInfo(trackSourceInfo));
-}
-
-SourceInfo::SourceInfo(PassRefPtr<TrackSourceInfo> trackSourceInfo)
- : m_trackSourceInfo(trackSourceInfo)
-{
-}
-
-const AtomicString& SourceInfo::kind() const
-{
- static NeverDestroyed<AtomicString> audioKind("audio", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> videoKind("video", AtomicString::ConstructFromLiteral);
-
- switch (m_trackSourceInfo->kind()) {
- case TrackSourceInfo::Audio:
- return audioKind;
- case TrackSourceInfo::Video:
- return videoKind;
- }
-
- ASSERT_NOT_REACHED();
- return emptyAtom;
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/Modules/mediastream/SourceInfo.idl b/Source/WebCore/Modules/mediastream/SourceInfo.idl
deleted file mode 100644
index d238f2d06..000000000
--- a/Source/WebCore/Modules/mediastream/SourceInfo.idl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- ImplementationLacksVTable,
- NoInterfaceObject,
- Conditional=MEDIA_STREAM,
-] interface SourceInfo {
- readonly attribute DOMString sourceId;
- readonly attribute DOMString kind;
- readonly attribute DOMString label;
-};
diff --git a/Source/WebCore/Modules/mediastream/UserMediaClient.h b/Source/WebCore/Modules/mediastream/UserMediaClient.h
index b847c7867..f8627acec 100644
--- a/Source/WebCore/Modules/mediastream/UserMediaClient.h
+++ b/Source/WebCore/Modules/mediastream/UserMediaClient.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Ericsson AB. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,15 +29,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef UserMediaClient_h
-#define UserMediaClient_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
-#include <wtf/PassRefPtr.h>
-
namespace WebCore {
+class MediaDevicesEnumerationRequest;
class Page;
class UserMediaRequest;
@@ -44,17 +43,18 @@ class UserMediaClient {
public:
virtual void pageDestroyed() = 0;
- virtual void requestPermission(PassRefPtr<UserMediaRequest>) = 0;
- virtual void cancelRequest(UserMediaRequest*) = 0;
+ virtual void requestUserMediaAccess(UserMediaRequest&) = 0;
+ virtual void cancelUserMediaAccessRequest(UserMediaRequest&) = 0;
+
+ virtual void enumerateMediaDevices(MediaDevicesEnumerationRequest&) = 0;
+ virtual void cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest&) = 0;
protected:
virtual ~UserMediaClient() { }
};
-void provideUserMediaTo(Page*, UserMediaClient*);
+WEBCORE_EXPORT void provideUserMediaTo(Page*, UserMediaClient*);
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // UserMediaClient_h
diff --git a/Source/WebCore/Modules/mediastream/UserMediaController.cpp b/Source/WebCore/Modules/mediastream/UserMediaController.cpp
index d46d4bc39..1991e1fb2 100644
--- a/Source/WebCore/Modules/mediastream/UserMediaController.cpp
+++ b/Source/WebCore/Modules/mediastream/UserMediaController.cpp
@@ -44,14 +44,9 @@ UserMediaController::~UserMediaController()
m_client->pageDestroyed();
}
-PassOwnPtr<UserMediaController> UserMediaController::create(UserMediaClient* client)
-{
- return adoptPtr(new UserMediaController(client));
-}
-
void provideUserMediaTo(Page* page, UserMediaClient* client)
{
- UserMediaController::provideTo(page, UserMediaController::supplementName(), UserMediaController::create(client));
+ UserMediaController::provideTo(page, UserMediaController::supplementName(), std::make_unique<UserMediaController>(client));
}
} // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/UserMediaController.h b/Source/WebCore/Modules/mediastream/UserMediaController.h
index 4d15c981e..707fd8e40 100644
--- a/Source/WebCore/Modules/mediastream/UserMediaController.h
+++ b/Source/WebCore/Modules/mediastream/UserMediaController.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -22,49 +23,56 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef UserMediaController_h
-#define UserMediaController_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
#include "Page.h"
#include "UserMediaClient.h"
#include "UserMediaRequest.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
class UserMediaController : public Supplement<Page> {
public:
+ explicit UserMediaController(UserMediaClient*);
~UserMediaController();
UserMediaClient* client() const { return m_client; }
- void requestPermission(PassRefPtr<UserMediaRequest>);
- void cancelRequest(UserMediaRequest*);
- static PassOwnPtr<UserMediaController> create(UserMediaClient*);
- static const char* supplementName();
- static UserMediaController* from(Page* page) { return static_cast<UserMediaController*>(Supplement<Page>::from(page, supplementName())); }
+ void requestUserMediaAccess(UserMediaRequest&);
+ void cancelUserMediaAccessRequest(UserMediaRequest&);
-protected:
- explicit UserMediaController(UserMediaClient*);
+ void enumerateMediaDevices(MediaDevicesEnumerationRequest&);
+ void cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest&);
+
+ WEBCORE_EXPORT static const char* supplementName();
+ static UserMediaController* from(Page* page) { return static_cast<UserMediaController*>(Supplement<Page>::from(page, supplementName())); }
private:
UserMediaClient* m_client;
};
-inline void UserMediaController::requestPermission(PassRefPtr<UserMediaRequest> request)
+inline void UserMediaController::requestUserMediaAccess(UserMediaRequest& request)
+{
+ m_client->requestUserMediaAccess(request);
+}
+
+inline void UserMediaController::cancelUserMediaAccessRequest(UserMediaRequest& request)
+{
+ m_client->cancelUserMediaAccessRequest(request);
+}
+
+inline void UserMediaController::enumerateMediaDevices(MediaDevicesEnumerationRequest& request)
{
- m_client->requestPermission(request);
+ m_client->enumerateMediaDevices(request);
}
-inline void UserMediaController::cancelRequest(UserMediaRequest* request)
+inline void UserMediaController::cancelMediaDevicesEnumerationRequest(MediaDevicesEnumerationRequest& request)
{
- m_client->cancelRequest(request);
+ m_client->cancelMediaDevicesEnumerationRequest(request);
}
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // UserMediaController_h
diff --git a/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp b/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp
index e438d35a2..5df3e9896 100644
--- a/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp
+++ b/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2011 Ericsson AB. All rights reserved.
* Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
*
* Redistribution and use in source and binary forms, with or without
@@ -32,68 +32,44 @@
*/
#include "config.h"
+#include "UserMediaRequest.h"
#if ENABLE(MEDIA_STREAM)
-#include "UserMediaRequest.h"
-
-#include "Dictionary.h"
#include "Document.h"
+#include "DocumentLoader.h"
#include "ExceptionCode.h"
+#include "JSMediaStream.h"
+#include "JSOverconstrainedError.h"
+#include "MainFrame.h"
#include "MediaConstraintsImpl.h"
-#include "MediaStream.h"
-#include "MediaStreamCenter.h"
-#include "MediaStreamPrivate.h"
-#include "SecurityOrigin.h"
+#include "RealtimeMediaSourceCenter.h"
+#include "Settings.h"
#include "UserMediaController.h"
-#include <wtf/Functional.h>
-#include <wtf/MainThread.h>
namespace WebCore {
-static PassRefPtr<MediaConstraints> parseOptions(const Dictionary& options, const String& mediaType, ExceptionCode& ec)
-{
- RefPtr<MediaConstraints> constraints;
-
- Dictionary constraintsDictionary;
- bool ok = options.get(mediaType, constraintsDictionary);
- if (ok && !constraintsDictionary.isUndefinedOrNull())
- constraints = MediaConstraintsImpl::create(constraintsDictionary, ec);
- else {
- bool mediaRequested = false;
- options.get(mediaType, mediaRequested);
- if (mediaRequested)
- constraints = MediaConstraintsImpl::create();
- }
-
- return constraints.release();
-}
-
-PassRefPtr<UserMediaRequest> UserMediaRequest::create(ScriptExecutionContext* context, UserMediaController* controller, const Dictionary& options, PassRefPtr<NavigatorUserMediaSuccessCallback> successCallback, PassRefPtr<NavigatorUserMediaErrorCallback> errorCallback, ExceptionCode& ec)
+ExceptionOr<void> UserMediaRequest::start(Document& document, Ref<MediaConstraintsImpl>&& audioConstraints, Ref<MediaConstraintsImpl>&& videoConstraints, DOMPromise<IDLInterface<MediaStream>>&& promise)
{
- ASSERT(successCallback);
-
- RefPtr<MediaConstraints> audioConstraints = parseOptions(options, AtomicString("audio", AtomicString::ConstructFromLiteral), ec);
- if (ec)
- return nullptr;
+ auto* userMedia = UserMediaController::from(document.page());
+ if (!userMedia)
+ return Exception { NOT_SUPPORTED_ERR }; // FIXME: Why is it better to return an exception here instead of rejecting the promise as we do just below?
- RefPtr<MediaConstraints> videoConstraints = parseOptions(options, AtomicString("video", AtomicString::ConstructFromLiteral), ec);
- if (ec)
- return nullptr;
-
- if (!audioConstraints && !videoConstraints)
- return nullptr;
+ if (!audioConstraints->isValid() && !videoConstraints->isValid()) {
+ promise.reject(TypeError);
+ return { };
+ }
- return adoptRef(new UserMediaRequest(context, controller, audioConstraints.release(), videoConstraints.release(), successCallback, errorCallback));
+ adoptRef(*new UserMediaRequest(document, *userMedia, WTFMove(audioConstraints), WTFMove(videoConstraints), WTFMove(promise)))->start();
+ return { };
}
-UserMediaRequest::UserMediaRequest(ScriptExecutionContext* context, UserMediaController* controller, PassRefPtr<MediaConstraints> audioConstraints, PassRefPtr<MediaConstraints> videoConstraints, PassRefPtr<NavigatorUserMediaSuccessCallback> successCallback, PassRefPtr<NavigatorUserMediaErrorCallback> errorCallback)
- : ContextDestructionObserver(context)
- , m_audioConstraints(audioConstraints)
- , m_videoConstraints(videoConstraints)
- , m_controller(controller)
- , m_successCallback(successCallback)
- , m_errorCallback(errorCallback)
+UserMediaRequest::UserMediaRequest(Document& document, UserMediaController& controller, Ref<MediaConstraintsImpl>&& audioConstraints, Ref<MediaConstraintsImpl>&& videoConstraints, DOMPromise<IDLInterface<MediaStream>>&& promise)
+ : ContextDestructionObserver(&document)
+ , m_audioConstraints(WTFMove(audioConstraints))
+ , m_videoConstraints(WTFMove(videoConstraints))
+ , m_controller(&controller)
+ , m_promise(WTFMove(promise))
{
}
@@ -101,126 +77,158 @@ UserMediaRequest::~UserMediaRequest()
{
}
-SecurityOrigin* UserMediaRequest::securityOrigin() const
+SecurityOrigin* UserMediaRequest::userMediaDocumentOrigin() const
{
- if (m_scriptExecutionContext)
- return m_scriptExecutionContext->securityOrigin();
-
- return nullptr;
-}
-
-void UserMediaRequest::start()
-{
- // 1 - make sure the system is capable of supporting the audio and video constraints. We don't want to ask for
- // user permission if the constraints can not be suported.
- MediaStreamCenter::shared().validateRequestConstraints(this, m_audioConstraints, m_videoConstraints);
+ if (!m_scriptExecutionContext)
+ return nullptr;
+ return m_scriptExecutionContext->securityOrigin();
}
-
-void UserMediaRequest::constraintsValidated()
+SecurityOrigin* UserMediaRequest::topLevelDocumentOrigin() const
{
- if (m_controller)
- callOnMainThread(bind(&UserMediaRequest::requestPermission, this));
+ if (!m_scriptExecutionContext)
+ return nullptr;
+ return &m_scriptExecutionContext->topOrigin();
}
-void UserMediaRequest::requestPermission()
+static bool isSecure(DocumentLoader& documentLoader)
{
- // 2 - The constraints are valid, ask the user for access to media.
- if (m_controller)
- m_controller->requestPermission(this);
+ auto& response = documentLoader.response();
+ return response.url().protocolIs("https")
+ && response.certificateInfo()
+ && !response.certificateInfo()->containsNonRootSHA1SignedCertificate();
}
-void UserMediaRequest::userMediaAccessGranted()
+static bool canCallGetUserMedia(Document& document, String& errorMessage)
{
- callOnMainThread(bind(&UserMediaRequest::createMediaStream, this));
-}
+ bool requiresSecureConnection = document.settings().mediaCaptureRequiresSecureConnection();
+ if (requiresSecureConnection && !isSecure(*document.loader())) {
+ errorMessage = "Trying to call getUserMedia from an insecure document.";
+ return false;
+ }
-void UserMediaRequest::createMediaStream()
-{
- // 3 - the user granted access, ask platform to create the media stream descriptors.
- MediaStreamCenter::shared().createMediaStream(this, m_audioConstraints, m_videoConstraints);
+ auto& topDocument = document.topDocument();
+ if (&document != &topDocument) {
+ auto& topOrigin = topDocument.topOrigin();
+
+ if (!document.securityOrigin().isSameSchemeHostPort(topOrigin)) {
+ errorMessage = "Trying to call getUserMedia from a document with a different security origin than its top-level frame.";
+ return false;
+ }
+
+ for (auto* ancestorDocument = document.parentDocument(); ancestorDocument != &topDocument; ancestorDocument = ancestorDocument->parentDocument()) {
+ if (requiresSecureConnection && !isSecure(*ancestorDocument->loader())) {
+ errorMessage = "Trying to call getUserMedia from a document with an insecure parent frame.";
+ return false;
+ }
+
+ if (!ancestorDocument->securityOrigin().isSameSchemeHostPort(topOrigin)) {
+ errorMessage = "Trying to call getUserMedia from a document with a different security origin than its top-level frame.";
+ return false;
+ }
+ }
+ }
+
+ return true;
}
-void UserMediaRequest::userMediaAccessDenied()
+void UserMediaRequest::start()
{
- failedToCreateStreamWithPermissionError();
-}
+ if (!m_scriptExecutionContext || !m_controller) {
+ deny(MediaAccessDenialReason::OtherFailure, emptyString());
+ return;
+ }
-void UserMediaRequest::constraintsInvalid(const String& constraintName)
-{
- failedToCreateStreamWithConstraintsError(constraintName);
-}
+ Document& document = downcast<Document>(*m_scriptExecutionContext);
-void UserMediaRequest::didCreateStream(PassRefPtr<MediaStreamPrivate> privateStream)
-{
- if (!m_scriptExecutionContext || !m_successCallback)
+ // 10.2 - 6.3 Optionally, e.g., based on a previously-established user preference, for security reasons,
+ // or due to platform limitations, jump to the step labeled Permission Failure below.
+ String errorMessage;
+ if (!canCallGetUserMedia(document, errorMessage)) {
+ deny(MediaAccessDenialReason::PermissionDenied, emptyString());
+ document.domWindow()->printErrorMessage(errorMessage);
return;
+ }
- callOnMainThread(bind(&UserMediaRequest::callSuccessHandler, this, privateStream));
+ m_controller->requestUserMediaAccess(*this);
}
-void UserMediaRequest::callSuccessHandler(PassRefPtr<MediaStreamPrivate> privateStream)
+void UserMediaRequest::allow(const String& audioDeviceUID, const String& videoDeviceUID)
{
- // 4 - Create the MediaStream and pass it to the success callback.
- ASSERT(m_successCallback);
+ m_allowedAudioDeviceUID = audioDeviceUID;
+ m_allowedVideoDeviceUID = videoDeviceUID;
- RefPtr<MediaStream> stream = MediaStream::create(*m_scriptExecutionContext, privateStream);
+ RefPtr<UserMediaRequest> protectedThis = this;
+ RealtimeMediaSourceCenter::NewMediaStreamHandler callback = [this, protectedThis = WTFMove(protectedThis)](RefPtr<MediaStreamPrivate>&& privateStream) mutable {
+ if (!m_scriptExecutionContext)
+ return;
- Vector<RefPtr<MediaStreamTrack>> tracks = stream->getAudioTracks();
- for (auto iter = tracks.begin(); iter != tracks.end(); ++iter)
- (*iter)->applyConstraints(m_audioConstraints);
+ if (!privateStream) {
+ deny(MediaAccessDenialReason::HardwareError, emptyString());
+ return;
+ }
- tracks = stream->getVideoTracks();
- for (auto iter = tracks.begin(); iter != tracks.end(); ++iter)
- (*iter)->applyConstraints(m_videoConstraints);
-
- m_successCallback->handleEvent(stream.get());
-}
+ auto stream = MediaStream::create(*m_scriptExecutionContext, WTFMove(privateStream));
+ if (stream->getTracks().isEmpty()) {
+ deny(MediaAccessDenialReason::HardwareError, emptyString());
+ return;
+ }
-void UserMediaRequest::failedToCreateStreamWithConstraintsError(const String& constraintName)
-{
- ASSERT(!constraintName.isEmpty());
- if (!m_scriptExecutionContext)
- return;
+ for (auto& track : stream->getAudioTracks())
+ track->source().startProducingData();
- if (!m_errorCallback)
- return;
+ for (auto& track : stream->getVideoTracks())
+ track->source().startProducingData();
+
+ m_promise.resolve(stream);
+ };
- RefPtr<NavigatorUserMediaError> error = NavigatorUserMediaError::create(NavigatorUserMediaError::constraintNotSatisfiedErrorName(), constraintName);
- callOnMainThread(bind(&UserMediaRequest::callErrorHandler, this, error.release()));
+ RealtimeMediaSourceCenter::singleton().createMediaStream(WTFMove(callback), m_allowedAudioDeviceUID, m_allowedVideoDeviceUID, &m_audioConstraints.get(), &m_videoConstraints.get());
}
-void UserMediaRequest::failedToCreateStreamWithPermissionError()
+void UserMediaRequest::deny(MediaAccessDenialReason reason, const String& invalidConstraint)
{
if (!m_scriptExecutionContext)
return;
- if (!m_errorCallback)
- return;
-
- RefPtr<NavigatorUserMediaError> error = NavigatorUserMediaError::create(NavigatorUserMediaError::permissionDeniedErrorName(), emptyString());
- callOnMainThread(bind(&UserMediaRequest::callErrorHandler, this, error.release()));
-}
-
-void UserMediaRequest::callErrorHandler(PassRefPtr<NavigatorUserMediaError> prpError)
-{
- RefPtr<NavigatorUserMediaError> error = prpError;
-
- ASSERT(error);
-
- m_errorCallback->handleEvent(error.get());
+ switch (reason) {
+ case MediaAccessDenialReason::NoConstraints:
+ m_promise.reject(TypeError);
+ break;
+ case MediaAccessDenialReason::UserMediaDisabled:
+ m_promise.reject(SECURITY_ERR);
+ break;
+ case MediaAccessDenialReason::NoCaptureDevices:
+ m_promise.reject(NOT_FOUND_ERR);
+ break;
+ case MediaAccessDenialReason::InvalidConstraint:
+ m_promise.rejectType<IDLInterface<OverconstrainedError>>(OverconstrainedError::create(invalidConstraint, ASCIILiteral("Invalid constraint")).get());
+ break;
+ case MediaAccessDenialReason::HardwareError:
+ m_promise.reject(NotReadableError);
+ break;
+ case MediaAccessDenialReason::OtherFailure:
+ m_promise.reject(ABORT_ERR);
+ break;
+ case MediaAccessDenialReason::PermissionDenied:
+ m_promise.reject(NotAllowedError);
+ break;
+ }
}
void UserMediaRequest::contextDestroyed()
{
- Ref<UserMediaRequest> protect(*this);
-
+ ContextDestructionObserver::contextDestroyed();
+ Ref<UserMediaRequest> protectedThis(*this);
if (m_controller) {
- m_controller->cancelRequest(this);
- m_controller = 0;
+ m_controller->cancelUserMediaAccessRequest(*this);
+ m_controller = nullptr;
}
+}
- ContextDestructionObserver::contextDestroyed();
+Document* UserMediaRequest::document() const
+{
+ return downcast<Document>(m_scriptExecutionContext);
}
} // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/UserMediaRequest.h b/Source/WebCore/Modules/mediastream/UserMediaRequest.h
index 6ad20fe06..316fee154 100644
--- a/Source/WebCore/Modules/mediastream/UserMediaRequest.h
+++ b/Source/WebCore/Modules/mediastream/UserMediaRequest.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
*
* Redistribution and use in source and binary forms, with or without
@@ -30,71 +30,66 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef UserMediaRequest_h
-#define UserMediaRequest_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
#include "ActiveDOMObject.h"
-#include "MediaStreamCreationClient.h"
-#include "MediaStreamSource.h"
-#include "NavigatorUserMediaErrorCallback.h"
-#include "NavigatorUserMediaSuccessCallback.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/text/WTFString.h>
+#include "JSDOMPromise.h"
namespace WebCore {
-class Dictionary;
-class Document;
-class MediaConstraints;
-class MediaStreamPrivate;
-class UserMediaController;
+class MediaConstraintsImpl;
+class MediaStream;
class SecurityOrigin;
+class UserMediaController;
-typedef int ExceptionCode;
-
-class UserMediaRequest : public MediaStreamCreationClient, public ContextDestructionObserver {
+class UserMediaRequest : public RefCounted<UserMediaRequest>, private ContextDestructionObserver {
public:
- static PassRefPtr<UserMediaRequest> create(ScriptExecutionContext*, UserMediaController*, const Dictionary& options, PassRefPtr<NavigatorUserMediaSuccessCallback>, PassRefPtr<NavigatorUserMediaErrorCallback>, ExceptionCode&);
- ~UserMediaRequest();
+ static ExceptionOr<void> start(Document&, Ref<MediaConstraintsImpl>&& audioConstraints, Ref<MediaConstraintsImpl>&& videoConstraints, DOMPromise<IDLInterface<MediaStream>>&&);
- SecurityOrigin* securityOrigin() const;
+ virtual ~UserMediaRequest();
void start();
- void userMediaAccessGranted();
- void userMediaAccessDenied();
-private:
- UserMediaRequest(ScriptExecutionContext*, UserMediaController*, PassRefPtr<MediaConstraints> audioConstraints, PassRefPtr<MediaConstraints> videoConstraints, PassRefPtr<NavigatorUserMediaSuccessCallback>, PassRefPtr<NavigatorUserMediaErrorCallback>);
+ WEBCORE_EXPORT void setAllowedMediaDeviceUIDs(const String& audioDeviceUID, const String& videoDeviceUID);
+ WEBCORE_EXPORT void allow(const String& audioDeviceUID, const String& videoDeviceUID);
+
+ enum MediaAccessDenialReason { NoConstraints, UserMediaDisabled, NoCaptureDevices, InvalidConstraint, HardwareError, PermissionDenied, OtherFailure };
+ WEBCORE_EXPORT void deny(MediaAccessDenialReason, const String& invalidConstraint);
+
+ const Vector<String>& audioDeviceUIDs() const { return m_audioDeviceUIDs; }
+ const Vector<String>& videoDeviceUIDs() const { return m_videoDeviceUIDs; }
+
+ const MediaConstraintsImpl& audioConstraints() const { return m_audioConstraints; }
+ const MediaConstraintsImpl& videoConstraints() const { return m_videoConstraints; }
- // MediaStreamCreationClient
- virtual void constraintsValidated() override final;
- virtual void constraintsInvalid(const String& constraintName) override final;
- virtual void didCreateStream(PassRefPtr<MediaStreamPrivate>) override final;
- virtual void failedToCreateStreamWithConstraintsError(const String& constraintName) override final;
- virtual void failedToCreateStreamWithPermissionError() override final;
+ const String& allowedAudioDeviceUID() const { return m_allowedAudioDeviceUID; }
+ const String& allowedVideoDeviceUID() const { return m_allowedVideoDeviceUID; }
- // ContextDestructionObserver
- virtual void contextDestroyed() override final;
+ WEBCORE_EXPORT SecurityOrigin* userMediaDocumentOrigin() const;
+ WEBCORE_EXPORT SecurityOrigin* topLevelDocumentOrigin() const;
+ WEBCORE_EXPORT Document* document() const;
+
+private:
+ UserMediaRequest(Document&, UserMediaController&, Ref<MediaConstraintsImpl>&& audioConstraints, Ref<MediaConstraintsImpl>&& videoConstraints, DOMPromise<IDLInterface<MediaStream>>&&);
+
+ void contextDestroyed() final;
- void callSuccessHandler(PassRefPtr<MediaStreamPrivate>);
- void callErrorHandler(PassRefPtr<NavigatorUserMediaError>);
- void requestPermission();
- void createMediaStream();
+ Ref<MediaConstraintsImpl> m_audioConstraints;
+ Ref<MediaConstraintsImpl> m_videoConstraints;
- RefPtr<MediaConstraints> m_audioConstraints;
- RefPtr<MediaConstraints> m_videoConstraints;
+ Vector<String> m_videoDeviceUIDs;
+ Vector<String> m_audioDeviceUIDs;
- UserMediaController* m_controller;
+ String m_allowedVideoDeviceUID;
+ String m_allowedAudioDeviceUID;
- RefPtr<NavigatorUserMediaSuccessCallback> m_successCallback;
- RefPtr<NavigatorUserMediaErrorCallback> m_errorCallback;
+ UserMediaController* m_controller;
+ DOMPromise<IDLInterface<MediaStream>> m_promise;
+ RefPtr<UserMediaRequest> m_protector;
};
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // UserMediaRequest_h
diff --git a/Source/WebCore/Modules/mediastream/VideoStreamTrack.cpp b/Source/WebCore/Modules/mediastream/VideoStreamTrack.cpp
deleted file mode 100644
index 2bd432d0e..000000000
--- a/Source/WebCore/Modules/mediastream/VideoStreamTrack.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "VideoStreamTrack.h"
-
-#include "Dictionary.h"
-#include "ScriptExecutionContext.h"
-#include <wtf/NeverDestroyed.h>
-
-namespace WebCore {
-
-RefPtr<VideoStreamTrack> VideoStreamTrack::create(ScriptExecutionContext& context, const Dictionary& videoConstraints)
-{
- return adoptRef(new VideoStreamTrack(context, *MediaStreamTrackPrivate::create(0), &videoConstraints));
-}
-
-RefPtr<VideoStreamTrack> VideoStreamTrack::create(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack)
-{
- return adoptRef(new VideoStreamTrack(context, privateTrack, 0));
-}
-
-RefPtr<VideoStreamTrack> VideoStreamTrack::create(MediaStreamTrack& track)
-{
- return adoptRef(new VideoStreamTrack(track));
-}
-
-VideoStreamTrack::VideoStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack, const Dictionary* videoConstraints)
- : MediaStreamTrack(context, privateTrack, videoConstraints)
-{
-}
-
-VideoStreamTrack::VideoStreamTrack(MediaStreamTrack& track)
- : MediaStreamTrack(track)
-{
-}
-
-const AtomicString& VideoStreamTrack::kind() const
-{
- static NeverDestroyed<AtomicString> videoKind("video", AtomicString::ConstructFromLiteral);
- return videoKind;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/Modules/mediastream/VideoStreamTrack.h b/Source/WebCore/Modules/mediastream/VideoStreamTrack.h
deleted file mode 100644
index 94d0aea2c..000000000
--- a/Source/WebCore/Modules/mediastream/VideoStreamTrack.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef VideoStreamTrack_h
-#define VideoStreamTrack_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamTrack.h"
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class MediaStreamSource;
-class ScriptExecutionContext;
-
-class VideoStreamTrack final : public MediaStreamTrack {
-public:
- static RefPtr<VideoStreamTrack> create(ScriptExecutionContext&, const Dictionary&);
- static RefPtr<VideoStreamTrack> create(ScriptExecutionContext&, MediaStreamTrackPrivate&);
- static RefPtr<VideoStreamTrack> create(MediaStreamTrack&);
-
- virtual ~VideoStreamTrack() { }
-
- virtual const AtomicString& kind() const override;
-
-private:
- VideoStreamTrack(ScriptExecutionContext&, MediaStreamTrackPrivate&, const Dictionary*);
- explicit VideoStreamTrack(MediaStreamTrack&);
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // VideoStreamTrack_h
diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCDataChannelHandler.cpp b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCDataChannelHandler.cpp
new file mode 100644
index 000000000..564b6d1c8
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCDataChannelHandler.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LibWebRTCDataChannelHandler.h"
+
+#if USE(LIBWEBRTC)
+
+#include "RTCDataChannel.h"
+#include <wtf/MainThread.h>
+
+namespace WebCore {
+
+LibWebRTCDataChannelHandler::~LibWebRTCDataChannelHandler()
+{
+ if (m_client)
+ m_channel->UnregisterObserver();
+}
+
+void LibWebRTCDataChannelHandler::setClient(RTCDataChannelHandlerClient* client)
+{
+ m_client = client;
+ if (m_client)
+ m_channel->RegisterObserver(this);
+ else
+ m_channel->UnregisterObserver();
+}
+
+bool LibWebRTCDataChannelHandler::sendStringData(const String& text)
+{
+ return m_channel->Send({rtc::CopyOnWriteBuffer(text.utf8().data(), text.length()), false});
+}
+
+bool LibWebRTCDataChannelHandler::sendRawData(const char* data, size_t length)
+{
+ return m_channel->Send({rtc::CopyOnWriteBuffer(data, length), true});
+}
+
+void LibWebRTCDataChannelHandler::close()
+{
+ m_channel->Close();
+}
+
+void LibWebRTCDataChannelHandler::OnStateChange()
+{
+ RTCDataChannel::ReadyState state;
+ switch (m_channel->state()) {
+ case webrtc::DataChannelInterface::kConnecting:
+ state = RTCDataChannel::ReadyStateConnecting;
+ break;
+ case webrtc::DataChannelInterface::kOpen:
+ state = RTCDataChannel::ReadyStateOpen;
+ break;
+ case webrtc::DataChannelInterface::kClosing:
+ state = RTCDataChannel::ReadyStateClosing;
+ break;
+ case webrtc::DataChannelInterface::kClosed:
+ state = RTCDataChannel::ReadyStateClosed;
+ break;
+ }
+ ASSERT(m_client);
+ callOnMainThread([protectedClient = makeRef(*m_client), state] {
+ protectedClient->didChangeReadyState(state);
+ });
+}
+
+void LibWebRTCDataChannelHandler::OnMessage(const webrtc::DataBuffer& buffer)
+{
+ ASSERT(m_client);
+ std::unique_ptr<webrtc::DataBuffer> protectedBuffer(new webrtc::DataBuffer(buffer));
+ callOnMainThread([protectedClient = makeRef(*m_client), buffer = WTFMove(protectedBuffer)] {
+ // FIXME: Ensure this is correct by adding some tests with non-ASCII characters.
+ const char* data = reinterpret_cast<const char*>(buffer->data.data());
+ if (buffer->binary)
+ protectedClient->didReceiveRawData(data, buffer->size());
+ else
+ protectedClient->didReceiveStringData(String(data, buffer->size()));
+ });
+}
+
+void LibWebRTCDataChannelHandler::OnBufferedAmountChange(uint64_t previousAmount)
+{
+ if (previousAmount <= m_channel->buffered_amount())
+ return;
+ ASSERT(m_client);
+ callOnMainThread([protectedClient = makeRef(*m_client)] {
+ protectedClient->bufferedAmountIsDecreasing();
+ });
+}
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/Modules/mediastream/NavigatorUserMediaError.h b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCDataChannelHandler.h
index ea37871da..7cc3502b7 100644
--- a/Source/WebCore/Modules/mediastream/NavigatorUserMediaError.h
+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCDataChannelHandler.h
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2017 Apple Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,43 +22,40 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef NavigatorUserMediaError_h
-#define NavigatorUserMediaError_h
+#pragma once
-#include "DOMError.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
+#if USE(LIBWEBRTC)
-#if ENABLE(MEDIA_STREAM)
+#include "LibWebRTCMacros.h"
+#include "RTCDataChannelHandler.h"
+#include <webrtc/api/datachannelinterface.h>
namespace WebCore {
-class NavigatorUserMediaError : public DOMError {
-public:
- static PassRefPtr<NavigatorUserMediaError> create(const String& name, const String& constraintName)
- {
- return adoptRef(new NavigatorUserMediaError(name, constraintName));
- }
-
- virtual ~NavigatorUserMediaError() { }
-
- const String& constraintName() const { return m_constraintName; }
+class RTCDataChannelHandlerClient;
- static const AtomicString& permissionDeniedErrorName();
- static const AtomicString& constraintNotSatisfiedErrorName();
+class LibWebRTCDataChannelHandler final : public RTCDataChannelHandler, private webrtc::DataChannelObserver {
+public:
+ explicit LibWebRTCDataChannelHandler(rtc::scoped_refptr<webrtc::DataChannelInterface>&& channel) : m_channel(WTFMove(channel)) { ASSERT(m_channel); }
+ ~LibWebRTCDataChannelHandler();
private:
- NavigatorUserMediaError(const String& name, const String& constraintName)
- : DOMError(name)
- , m_constraintName(constraintName)
- {
- }
-
- String m_constraintName;
+ // RTCDataChannelHandler API
+ void setClient(RTCDataChannelHandlerClient*) final;
+ bool sendStringData(const String&) final;
+ bool sendRawData(const char*, size_t) final;
+ void close() final;
+ size_t bufferedAmount() const final { return static_cast<size_t>(m_channel->buffered_amount()); }
+
+ // webrtc::DataChannelObserver API
+ void OnStateChange();
+ void OnMessage(const webrtc::DataBuffer&);
+ void OnBufferedAmountChange(uint64_t);
+
+ rtc::scoped_refptr<webrtc::DataChannelInterface> m_channel;
+ RTCDataChannelHandlerClient* m_client { nullptr };
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // NavigatorUserMediaError_h
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp
new file mode 100644
index 000000000..e46c31c4e
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) 2017 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LibWebRTCMediaEndpoint.h"
+
+#if USE(LIBWEBRTC)
+
+#include "EventNames.h"
+#include "LibWebRTCDataChannelHandler.h"
+#include "LibWebRTCPeerConnectionBackend.h"
+#include "LibWebRTCProvider.h"
+#include "MediaStreamEvent.h"
+#include "NotImplemented.h"
+#include "PlatformStrategies.h"
+#include "RTCDataChannel.h"
+#include "RTCDataChannelEvent.h"
+#include "RTCIceCandidate.h"
+#include "RTCPeerConnection.h"
+#include "RTCSessionDescription.h"
+#include "RTCTrackEvent.h"
+#include "RealtimeIncomingAudioSource.h"
+#include "RealtimeIncomingVideoSource.h"
+#include <webrtc/api/peerconnectionfactory.h>
+#include <webrtc/base/physicalsocketserver.h>
+#include <webrtc/p2p/base/basicpacketsocketfactory.h>
+#include <webrtc/p2p/client/basicportallocator.h>
+#include <wtf/MainThread.h>
+
+#include "CoreMediaSoftLink.h"
+
+namespace WebCore {
+
+LibWebRTCMediaEndpoint::LibWebRTCMediaEndpoint(LibWebRTCPeerConnectionBackend& peerConnection, LibWebRTCProvider& client)
+ : m_peerConnectionBackend(peerConnection)
+ , m_backend(client.createPeerConnection(*this))
+ , m_createSessionDescriptionObserver(*this)
+ , m_setLocalSessionDescriptionObserver(*this)
+ , m_setRemoteSessionDescriptionObserver(*this)
+{
+ ASSERT(m_backend);
+}
+
+static inline const char* sessionDescriptionType(RTCSessionDescription::SdpType sdpType)
+{
+ switch (sdpType) {
+ case RTCSessionDescription::SdpType::Offer:
+ return "offer";
+ case RTCSessionDescription::SdpType::Pranswer:
+ return "pranswer";
+ case RTCSessionDescription::SdpType::Answer:
+ return "answer";
+ case RTCSessionDescription::SdpType::Rollback:
+ return "rollback";
+ }
+}
+
+static inline RTCSessionDescription::SdpType fromSessionDescriptionType(const webrtc::SessionDescriptionInterface& description)
+{
+ auto type = description.type();
+ if (type == webrtc::SessionDescriptionInterface::kOffer)
+ return RTCSessionDescription::SdpType::Offer;
+ if (type == webrtc::SessionDescriptionInterface::kAnswer)
+ return RTCSessionDescription::SdpType::Answer;
+ ASSERT(type == webrtc::SessionDescriptionInterface::kPrAnswer);
+ return RTCSessionDescription::SdpType::Pranswer;
+}
+
+static inline RefPtr<RTCSessionDescription> fromSessionDescription(const webrtc::SessionDescriptionInterface* description)
+{
+ if (!description)
+ return nullptr;
+
+ std::string sdp;
+ description->ToString(&sdp);
+ String sdpString(sdp.data(), sdp.size());
+
+ return RTCSessionDescription::create(fromSessionDescriptionType(*description), WTFMove(sdpString));
+}
+
+RefPtr<RTCSessionDescription> LibWebRTCMediaEndpoint::localDescription() const
+{
+ // FIXME: We might want to create a new object only if the session actually changed.
+ return fromSessionDescription(m_backend->local_description());
+}
+
+RefPtr<RTCSessionDescription> LibWebRTCMediaEndpoint::remoteDescription() const
+{
+ // FIXME: We might want to create a new object only if the session actually changed.
+ return fromSessionDescription(m_backend->remote_description());
+}
+
+void LibWebRTCMediaEndpoint::doSetLocalDescription(RTCSessionDescription& description)
+{
+ webrtc::SdpParseError error;
+ std::unique_ptr<webrtc::SessionDescriptionInterface> sessionDescription(webrtc::CreateSessionDescription(sessionDescriptionType(description.type()), description.sdp().utf8().data(), &error));
+
+ if (!sessionDescription) {
+ String errorMessage(error.description.data(), error.description.size());
+ m_peerConnectionBackend.setLocalDescriptionFailed(Exception { OperationError, WTFMove(errorMessage) });
+ return;
+ }
+ m_backend->SetLocalDescription(&m_setLocalSessionDescriptionObserver, sessionDescription.release());
+}
+
+void LibWebRTCMediaEndpoint::doSetRemoteDescription(RTCSessionDescription& description)
+{
+ webrtc::SdpParseError error;
+ std::unique_ptr<webrtc::SessionDescriptionInterface> sessionDescription(webrtc::CreateSessionDescription(sessionDescriptionType(description.type()), description.sdp().utf8().data(), &error));
+ if (!sessionDescription) {
+ String errorMessage(error.description.data(), error.description.size());
+ m_peerConnectionBackend.setRemoteDescriptionFailed(Exception { OperationError, WTFMove(errorMessage) });
+ return;
+ }
+ m_backend->SetRemoteDescription(&m_setRemoteSessionDescriptionObserver, sessionDescription.release());
+}
+
+static inline std::string streamId(RTCPeerConnection& connection)
+{
+ auto& senders = connection.getSenders();
+ if (senders.size()) {
+ for (RTCRtpSender& sender : senders) {
+ auto* track = sender.track();
+ if (track) {
+ ASSERT(sender.mediaStreamIds().size() == 1);
+ return std::string(sender.mediaStreamIds().first().utf8().data());
+ }
+ }
+ }
+ return "av_label";
+}
+
+void LibWebRTCMediaEndpoint::doCreateOffer()
+{
+ m_isInitiator = true;
+ auto& senders = m_peerConnectionBackend.connection().getSenders();
+ if (senders.size()) {
+ // FIXME: We only support one stream for the moment.
+ auto stream = LibWebRTCProvider::factory().CreateLocalMediaStream(streamId(m_peerConnectionBackend.connection()));
+ for (RTCRtpSender& sender : senders) {
+ auto* track = sender.track();
+ if (track) {
+ ASSERT(sender.mediaStreamIds().size() == 1);
+ auto& source = track->source();
+ if (source.type() == RealtimeMediaSource::Audio) {
+ auto trackSource = RealtimeOutgoingAudioSource::create(source);
+ auto rtcTrack = LibWebRTCProvider::factory().CreateAudioTrack(track->id().utf8().data(), trackSource.ptr());
+ trackSource->setTrack(rtc::scoped_refptr<webrtc::AudioTrackInterface>(rtcTrack));
+ m_peerConnectionBackend.addAudioSource(WTFMove(trackSource));
+ stream->AddTrack(WTFMove(rtcTrack));
+ } else {
+ auto videoSource = RealtimeOutgoingVideoSource::create(source);
+ auto videoTrack = LibWebRTCProvider::factory().CreateVideoTrack(track->id().utf8().data(), videoSource.ptr());
+ m_peerConnectionBackend.addVideoSource(WTFMove(videoSource));
+ stream->AddTrack(WTFMove(videoTrack));
+ }
+ }
+ }
+ m_backend->AddStream(stream);
+ }
+ m_backend->CreateOffer(&m_createSessionDescriptionObserver, nullptr);
+}
+
+void LibWebRTCMediaEndpoint::doCreateAnswer()
+{
+ m_isInitiator = false;
+
+ auto& senders = m_peerConnectionBackend.connection().getSenders();
+ if (senders.size()) {
+ // FIXME: We only support one stream for the moment.
+ auto stream = LibWebRTCProvider::factory().CreateLocalMediaStream(streamId(m_peerConnectionBackend.connection()));
+ for (RTCRtpSender& sender : senders) {
+ auto* track = sender.track();
+ if (track) {
+ ASSERT(sender.mediaStreamIds().size() == 1);
+ auto& source = track->source();
+ if (source.type() == RealtimeMediaSource::Audio) {
+ auto trackSource = RealtimeOutgoingAudioSource::create(source);
+ auto rtcTrack = LibWebRTCProvider::factory().CreateAudioTrack(track->id().utf8().data(), trackSource.ptr());
+ trackSource->setTrack(rtc::scoped_refptr<webrtc::AudioTrackInterface>(rtcTrack));
+ m_peerConnectionBackend.addAudioSource(WTFMove(trackSource));
+ stream->AddTrack(WTFMove(rtcTrack));
+ } else {
+ auto videoSource = RealtimeOutgoingVideoSource::create(source);
+ auto videoTrack = LibWebRTCProvider::factory().CreateVideoTrack(track->id().utf8().data(), videoSource.ptr());
+ m_peerConnectionBackend.addVideoSource(WTFMove(videoSource));
+ stream->AddTrack(WTFMove(videoTrack));
+ }
+ }
+ }
+ m_backend->AddStream(stream);
+ }
+ m_backend->CreateAnswer(&m_createSessionDescriptionObserver, nullptr);
+}
+
+void LibWebRTCMediaEndpoint::getStats(MediaStreamTrack* track, const DeferredPromise& promise)
+{
+ m_backend->GetStats(StatsCollector::create(*this, promise, track).get());
+}
+
+LibWebRTCMediaEndpoint::StatsCollector::StatsCollector(LibWebRTCMediaEndpoint& endpoint, const DeferredPromise& promise, MediaStreamTrack* track)
+ : m_endpoint(endpoint)
+ , m_promise(promise)
+{
+ if (track)
+ m_id = track->id();
+}
+
+void LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered(const rtc::scoped_refptr<const webrtc::RTCStatsReport>& report)
+{
+ callOnMainThread([protectedThis = rtc::scoped_refptr<LibWebRTCMediaEndpoint::StatsCollector>(this), report] {
+ if (protectedThis->m_endpoint.isStopped())
+ return;
+
+ // FIXME: Fulfill promise with the report
+ UNUSED_PARAM(report);
+
+ protectedThis->m_endpoint.m_peerConnectionBackend.getStatsFailed(protectedThis->m_promise, Exception { TypeError, ASCIILiteral("Stats API is not yet implemented") });
+ });
+}
+
+static PeerConnectionStates::SignalingState signalingState(webrtc::PeerConnectionInterface::SignalingState state)
+{
+ switch (state) {
+ case webrtc::PeerConnectionInterface::kStable:
+ return PeerConnectionStates::SignalingState::Stable;
+ case webrtc::PeerConnectionInterface::kHaveLocalOffer:
+ return PeerConnectionStates::SignalingState::HaveLocalOffer;
+ case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
+ return PeerConnectionStates::SignalingState::HaveLocalPrAnswer;
+ case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
+ return PeerConnectionStates::SignalingState::HaveRemoteOffer;
+ case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
+ return PeerConnectionStates::SignalingState::HaveRemotePrAnswer;
+ case webrtc::PeerConnectionInterface::kClosed:
+ return PeerConnectionStates::SignalingState::Closed;
+ }
+}
+
+void LibWebRTCMediaEndpoint::OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState rtcState)
+{
+ auto state = signalingState(rtcState);
+ callOnMainThread([protectedThis = makeRef(*this), state] {
+ if (protectedThis->isStopped())
+ return;
+ protectedThis->m_peerConnectionBackend.updateSignalingState(state);
+ });
+}
+
+static inline String trackId(webrtc::MediaStreamTrackInterface& videoTrack)
+{
+ return String(videoTrack.id().data(), videoTrack.id().size());
+}
+
+static inline Ref<MediaStreamTrack> createMediaStreamTrack(ScriptExecutionContext& context, Ref<RealtimeMediaSource>&& remoteSource)
+{
+ String trackId = remoteSource->id();
+ return MediaStreamTrack::create(context, MediaStreamTrackPrivate::create(WTFMove(remoteSource), WTFMove(trackId)));
+}
+
+void LibWebRTCMediaEndpoint::addStream(webrtc::MediaStreamInterface& stream)
+{
+ MediaStreamTrackVector tracks;
+ for (auto& videoTrack : stream.GetVideoTracks()) {
+ ASSERT(videoTrack);
+ String id = trackId(*videoTrack);
+ auto remoteSource = RealtimeIncomingVideoSource::create(WTFMove(videoTrack), WTFMove(id));
+ tracks.append(createMediaStreamTrack(*m_peerConnectionBackend.connection().scriptExecutionContext(), WTFMove(remoteSource)));
+ }
+ for (auto& audioTrack : stream.GetAudioTracks()) {
+ ASSERT(audioTrack);
+ String id = trackId(*audioTrack);
+ auto remoteSource = RealtimeIncomingAudioSource::create(WTFMove(audioTrack), WTFMove(id));
+ tracks.append(createMediaStreamTrack(*m_peerConnectionBackend.connection().scriptExecutionContext(), WTFMove(remoteSource)));
+ }
+
+ auto newStream = MediaStream::create(*m_peerConnectionBackend.connection().scriptExecutionContext(), WTFMove(tracks));
+ m_peerConnectionBackend.connection().fireEvent(MediaStreamEvent::create(eventNames().addstreamEvent, false, false, newStream.copyRef()));
+
+ Vector<RefPtr<MediaStream>> streams;
+ streams.append(newStream.copyRef());
+ for (auto& track : newStream->getTracks())
+ m_peerConnectionBackend.connection().fireEvent(RTCTrackEvent::create(eventNames().trackEvent, false, false, nullptr, track.get(), Vector<RefPtr<MediaStream>>(streams), nullptr));
+}
+
+void LibWebRTCMediaEndpoint::OnAddStream(rtc::scoped_refptr<webrtc::MediaStreamInterface> stream)
+{
+ callOnMainThread([protectedThis = makeRef(*this), stream = WTFMove(stream)] {
+ if (protectedThis->isStopped())
+ return;
+ ASSERT(stream);
+ protectedThis->addStream(*stream.get());
+ });
+}
+
+void LibWebRTCMediaEndpoint::OnRemoveStream(rtc::scoped_refptr<webrtc::MediaStreamInterface>)
+{
+ notImplemented();
+}
+
+std::unique_ptr<RTCDataChannelHandler> LibWebRTCMediaEndpoint::createDataChannel(const String& label, const RTCDataChannelInit& options)
+{
+ webrtc::DataChannelInit init;
+ init.ordered = options.ordered;
+ init.maxRetransmitTime = options.maxRetransmitTime;
+ init.maxRetransmits = options.maxRetransmits;
+ init.protocol = options.protocol.utf8().data();
+ init.negotiated = options.negotiated;
+ init.id = options.id;
+
+ return std::make_unique<LibWebRTCDataChannelHandler>(m_backend->CreateDataChannel(label.utf8().data(), &init));
+}
+
+void LibWebRTCMediaEndpoint::addDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface>&& dataChannel)
+{
+ auto protocol = dataChannel->protocol();
+ auto label = dataChannel->label();
+
+ RTCDataChannelInit init;
+ init.ordered = dataChannel->ordered();
+ init.maxRetransmitTime = dataChannel->maxRetransmitTime();
+ init.maxRetransmits = dataChannel->maxRetransmits();
+ init.protocol = String(protocol.data(), protocol.size());
+ init.negotiated = dataChannel->negotiated();
+ init.id = dataChannel->id();
+
+ bool isOpened = dataChannel->state() == webrtc::DataChannelInterface::kOpen;
+
+ auto handler = std::make_unique<LibWebRTCDataChannelHandler>(WTFMove(dataChannel));
+ ASSERT(m_peerConnectionBackend.connection().scriptExecutionContext());
+ auto channel = RTCDataChannel::create(*m_peerConnectionBackend.connection().scriptExecutionContext(), WTFMove(handler), String(label.data(), label.size()), WTFMove(init));
+
+ if (isOpened) {
+ callOnMainThread([channel = channel.copyRef()] {
+ // FIXME: We should be able to write channel->didChangeReadyState(...)
+ RTCDataChannelHandlerClient& client = channel.get();
+ client.didChangeReadyState(RTCDataChannel::ReadyStateOpen);
+ });
+ }
+
+ m_peerConnectionBackend.connection().fireEvent(RTCDataChannelEvent::create(eventNames().datachannelEvent, false, false, WTFMove(channel)));
+}
+
+void LibWebRTCMediaEndpoint::OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel)
+{
+ callOnMainThread([protectedThis = makeRef(*this), dataChannel = WTFMove(dataChannel)] {
+ if (protectedThis->isStopped())
+ return;
+ protectedThis->addDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface>(dataChannel));
+ });
+}
+
+void LibWebRTCMediaEndpoint::stop()
+{
+ ASSERT(m_backend);
+ m_backend->Close();
+ m_backend = nullptr;
+}
+
+void LibWebRTCMediaEndpoint::OnRenegotiationNeeded()
+{
+ callOnMainThread([protectedThis = makeRef(*this)] {
+ if (protectedThis->isStopped())
+ return;
+ protectedThis->m_peerConnectionBackend.markAsNeedingNegotiation();
+ });
+}
+
+static inline PeerConnectionStates::IceConnectionState iceConnectionState(webrtc::PeerConnectionInterface::IceConnectionState state)
+{
+ switch (state) {
+ case webrtc::PeerConnectionInterface::kIceConnectionNew:
+ return PeerConnectionStates::IceConnectionState::New;
+ case webrtc::PeerConnectionInterface::kIceConnectionChecking:
+ return PeerConnectionStates::IceConnectionState::Checking;
+ case webrtc::PeerConnectionInterface::kIceConnectionConnected:
+ return PeerConnectionStates::IceConnectionState::Connected;
+ case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
+ return PeerConnectionStates::IceConnectionState::Completed;
+ case webrtc::PeerConnectionInterface::kIceConnectionFailed:
+ return PeerConnectionStates::IceConnectionState::Failed;
+ case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
+ return PeerConnectionStates::IceConnectionState::Disconnected;
+ case webrtc::PeerConnectionInterface::kIceConnectionClosed:
+ return PeerConnectionStates::IceConnectionState::Closed;
+ case webrtc::PeerConnectionInterface::kIceConnectionMax:
+ ASSERT_NOT_REACHED();
+ return PeerConnectionStates::IceConnectionState::New;
+ }
+}
+
+void LibWebRTCMediaEndpoint::OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState state)
+{
+ auto connectionState = iceConnectionState(state);
+ callOnMainThread([protectedThis = makeRef(*this), connectionState] {
+ if (protectedThis->isStopped())
+ return;
+ if (protectedThis->m_peerConnectionBackend.connection().internalIceConnectionState() != connectionState)
+ protectedThis->m_peerConnectionBackend.connection().updateIceConnectionState(connectionState);
+ });
+}
+
+void LibWebRTCMediaEndpoint::OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState state)
+{
+ if (state == webrtc::PeerConnectionInterface::kIceGatheringComplete) {
+ callOnMainThread([protectedThis = makeRef(*this)] {
+ if (protectedThis->isStopped())
+ return;
+ protectedThis->m_peerConnectionBackend.doneGatheringCandidates();
+ });
+ }
+}
+
+void LibWebRTCMediaEndpoint::OnIceCandidate(const webrtc::IceCandidateInterface *rtcCandidate)
+{
+ ASSERT(rtcCandidate);
+
+ std::string sdp;
+ rtcCandidate->ToString(&sdp);
+ String candidateSDP(sdp.data(), sdp.size());
+
+ auto mid = rtcCandidate->sdp_mid();
+ String candidateMid(mid.data(), mid.size());
+
+ callOnMainThread([protectedThis = makeRef(*this), mid = WTFMove(candidateMid), sdp = WTFMove(candidateSDP)] {
+ if (protectedThis->isStopped())
+ return;
+ protectedThis->m_peerConnectionBackend.fireICECandidateEvent(RTCIceCandidate::create(String(sdp), String(mid), 0));
+ });
+}
+
+void LibWebRTCMediaEndpoint::OnIceCandidatesRemoved(const std::vector<cricket::Candidate>&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void LibWebRTCMediaEndpoint::createSessionDescriptionSucceeded(webrtc::SessionDescriptionInterface* description)
+{
+ std::string sdp;
+ description->ToString(&sdp);
+ String sdpString(sdp.data(), sdp.size());
+
+ callOnMainThread([protectedThis = makeRef(*this), sdp = WTFMove(sdpString)] {
+ if (protectedThis->isStopped())
+ return;
+ if (protectedThis->m_isInitiator)
+ protectedThis->m_peerConnectionBackend.createOfferSucceeded(String(sdp));
+ else
+ protectedThis->m_peerConnectionBackend.createAnswerSucceeded(String(sdp));
+ });
+}
+
+void LibWebRTCMediaEndpoint::createSessionDescriptionFailed(const std::string& errorMessage)
+{
+ String error(errorMessage.data(), errorMessage.size());
+ callOnMainThread([protectedThis = makeRef(*this), error = WTFMove(error)] {
+ if (protectedThis->isStopped())
+ return;
+ if (protectedThis->m_isInitiator)
+ protectedThis->m_peerConnectionBackend.createOfferFailed(Exception { OperationError, String(error) });
+ else
+ protectedThis->m_peerConnectionBackend.createAnswerFailed(Exception { OperationError, String(error) });
+ });
+}
+
+void LibWebRTCMediaEndpoint::setLocalSessionDescriptionSucceeded()
+{
+ callOnMainThread([protectedThis = makeRef(*this)] {
+ if (protectedThis->isStopped())
+ return;
+ protectedThis->m_peerConnectionBackend.setLocalDescriptionSucceeded();
+ });
+}
+
+void LibWebRTCMediaEndpoint::setLocalSessionDescriptionFailed(const std::string& errorMessage)
+{
+ String error(errorMessage.data(), errorMessage.size());
+ callOnMainThread([protectedThis = makeRef(*this), error = WTFMove(error)] {
+ if (protectedThis->isStopped())
+ return;
+ protectedThis->m_peerConnectionBackend.setLocalDescriptionFailed(Exception { OperationError, String(error) });
+ });
+}
+
+void LibWebRTCMediaEndpoint::setRemoteSessionDescriptionSucceeded()
+{
+ callOnMainThread([protectedThis = makeRef(*this)] {
+ if (protectedThis->isStopped())
+ return;
+ protectedThis->m_peerConnectionBackend.setRemoteDescriptionSucceeded();
+ });
+}
+
+void LibWebRTCMediaEndpoint::setRemoteSessionDescriptionFailed(const std::string& errorMessage)
+{
+ String error(errorMessage.data(), errorMessage.size());
+ callOnMainThread([protectedThis = makeRef(*this), error = WTFMove(error)] {
+ if (protectedThis->isStopped())
+ return;
+ protectedThis->m_peerConnectionBackend.setRemoteDescriptionFailed(Exception { OperationError, String(error) });
+ });
+}
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h
new file mode 100644
index 000000000..7b308e0b1
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2017 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(LIBWEBRTC)
+
+#include "LibWebRTCProvider.h"
+#include "PeerConnectionBackend.h"
+#include "RealtimeOutgoingAudioSource.h"
+#include "RealtimeOutgoingVideoSource.h"
+
+#include <webrtc/api/jsep.h>
+#include <webrtc/api/peerconnectionfactory.h>
+#include <webrtc/api/peerconnectioninterface.h>
+#include <webrtc/api/rtcstatscollector.h>
+
+#include <wtf/ThreadSafeRefCounted.h>
+
+namespace webrtc {
+class CreateSessionDescriptionObserver;
+class DataChannelInterface;
+class IceCandidateInterface;
+class MediaStreamInterface;
+class PeerConnectionObserver;
+class SessionDescriptionInterface;
+class SetSessionDescriptionObserver;
+}
+
+namespace WebCore {
+
+class LibWebRTCProvider;
+class LibWebRTCPeerConnectionBackend;
+class MediaStreamTrack;
+class RTCSessionDescription;
+
+class LibWebRTCMediaEndpoint : public ThreadSafeRefCounted<LibWebRTCMediaEndpoint>, private webrtc::PeerConnectionObserver {
+public:
+ static Ref<LibWebRTCMediaEndpoint> create(LibWebRTCPeerConnectionBackend& peerConnection, LibWebRTCProvider& client) { return adoptRef(*new LibWebRTCMediaEndpoint(peerConnection, client)); }
+ virtual ~LibWebRTCMediaEndpoint() { }
+
+ webrtc::PeerConnectionInterface& backend() const { ASSERT(m_backend); return *m_backend.get(); }
+ void doSetLocalDescription(RTCSessionDescription&);
+ void doSetRemoteDescription(RTCSessionDescription&);
+ void doCreateOffer();
+ void doCreateAnswer();
+ void getStats(MediaStreamTrack*, const DeferredPromise&);
+ std::unique_ptr<RTCDataChannelHandler> createDataChannel(const String&, const RTCDataChannelInit&);
+ bool addIceCandidate(webrtc::IceCandidateInterface& candidate) { return m_backend->AddIceCandidate(&candidate); }
+
+ void stop();
+ bool isStopped() const { return !m_backend; }
+
+ RefPtr<RTCSessionDescription> localDescription() const;
+ RefPtr<RTCSessionDescription> remoteDescription() const;
+
+private:
+ LibWebRTCMediaEndpoint(LibWebRTCPeerConnectionBackend&, LibWebRTCProvider&);
+
+ // webrtc::PeerConnectionObserver API
+ void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState) final;
+ void OnAddStream(rtc::scoped_refptr<webrtc::MediaStreamInterface>) final;
+ void OnRemoveStream(rtc::scoped_refptr<webrtc::MediaStreamInterface>) final;
+ void OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface>) final;
+ void OnRenegotiationNeeded() final;
+ void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState) final;
+ void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState) final;
+ void OnIceCandidate(const webrtc::IceCandidateInterface*) final;
+ void OnIceCandidatesRemoved(const std::vector<cricket::Candidate>&) final;
+
+ void createSessionDescriptionSucceeded(webrtc::SessionDescriptionInterface*);
+ void createSessionDescriptionFailed(const std::string&);
+ void setLocalSessionDescriptionSucceeded();
+ void setLocalSessionDescriptionFailed(const std::string&);
+ void setRemoteSessionDescriptionSucceeded();
+ void setRemoteSessionDescriptionFailed(const std::string&);
+ void addStream(webrtc::MediaStreamInterface&);
+ void addDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface>&&);
+
+ int AddRef() const { ref(); return static_cast<int>(refCount()); }
+ int Release() const { deref(); return static_cast<int>(refCount()); }
+
+ class CreateSessionDescriptionObserver final : public webrtc::CreateSessionDescriptionObserver {
+ public:
+ explicit CreateSessionDescriptionObserver(LibWebRTCMediaEndpoint &endpoint) : m_endpoint(endpoint) { }
+
+ void OnSuccess(webrtc::SessionDescriptionInterface* sessionDescription) final { m_endpoint.createSessionDescriptionSucceeded(sessionDescription); }
+ void OnFailure(const std::string& error) final { m_endpoint.createSessionDescriptionFailed(error); }
+
+ int AddRef() const { return m_endpoint.AddRef(); }
+ int Release() const { return m_endpoint.Release(); }
+
+ private:
+ LibWebRTCMediaEndpoint& m_endpoint;
+ };
+
+ class SetLocalSessionDescriptionObserver final : public webrtc::SetSessionDescriptionObserver {
+ public:
+ explicit SetLocalSessionDescriptionObserver(LibWebRTCMediaEndpoint &endpoint) : m_endpoint(endpoint) { }
+
+ void OnSuccess() final { m_endpoint.setLocalSessionDescriptionSucceeded(); }
+ void OnFailure(const std::string& error) final { m_endpoint.setLocalSessionDescriptionFailed(error); }
+
+ int AddRef() const { return m_endpoint.AddRef(); }
+ int Release() const { return m_endpoint.Release(); }
+
+ private:
+ LibWebRTCMediaEndpoint& m_endpoint;
+ };
+
+ class SetRemoteSessionDescriptionObserver final : public webrtc::SetSessionDescriptionObserver {
+ public:
+ explicit SetRemoteSessionDescriptionObserver(LibWebRTCMediaEndpoint &endpoint) : m_endpoint(endpoint) { }
+
+ void OnSuccess() final { m_endpoint.setRemoteSessionDescriptionSucceeded(); }
+ void OnFailure(const std::string& error) final { m_endpoint.setRemoteSessionDescriptionFailed(error); }
+
+ int AddRef() const { return m_endpoint.AddRef(); }
+ int Release() const { return m_endpoint.Release(); }
+
+ private:
+ LibWebRTCMediaEndpoint& m_endpoint;
+ };
+
+ class StatsCollector final : public webrtc::RTCStatsCollectorCallback {
+ public:
+ static rtc::scoped_refptr<StatsCollector> create(LibWebRTCMediaEndpoint& endpoint, const DeferredPromise& promise, MediaStreamTrack* track) { return new StatsCollector(endpoint, promise, track); }
+
+ int AddRef() const { return m_endpoint.AddRef(); }
+ int Release() const { return m_endpoint.Release(); }
+
+ private:
+ StatsCollector(LibWebRTCMediaEndpoint&, const DeferredPromise&, MediaStreamTrack*);
+
+ void OnStatsDelivered(const rtc::scoped_refptr<const webrtc::RTCStatsReport>&) final;
+
+ LibWebRTCMediaEndpoint& m_endpoint;
+ const DeferredPromise& m_promise;
+ String m_id;
+ };
+
+ LibWebRTCPeerConnectionBackend& m_peerConnectionBackend;
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> m_backend;
+
+ CreateSessionDescriptionObserver m_createSessionDescriptionObserver;
+ SetLocalSessionDescriptionObserver m_setLocalSessionDescriptionObserver;
+ SetRemoteSessionDescriptionObserver m_setRemoteSessionDescriptionObserver;
+
+ bool m_isInitiator { false };
+};
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp
new file mode 100644
index 000000000..c8a382c5b
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2017 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LibWebRTCPeerConnectionBackend.h"
+
+#if USE(LIBWEBRTC)
+
+#include "Document.h"
+#include "IceCandidate.h"
+#include "JSRTCStatsReport.h"
+#include "LibWebRTCDataChannelHandler.h"
+#include "LibWebRTCMediaEndpoint.h"
+#include "MediaEndpointConfiguration.h"
+#include "Page.h"
+#include "RTCIceCandidate.h"
+#include "RTCPeerConnection.h"
+#include "RTCRtpReceiver.h"
+#include "RTCSessionDescription.h"
+#include "RealtimeIncomingAudioSource.h"
+#include "RealtimeIncomingVideoSource.h"
+
+namespace WebCore {
+
+static std::unique_ptr<PeerConnectionBackend> createLibWebRTCPeerConnectionBackend(RTCPeerConnection& peerConnection)
+{
+ return std::make_unique<LibWebRTCPeerConnectionBackend>(peerConnection);
+}
+
+CreatePeerConnectionBackend PeerConnectionBackend::create = createLibWebRTCPeerConnectionBackend;
+
+static inline LibWebRTCProvider& libWebRTCProvider(RTCPeerConnection& peerConnection)
+{
+ ASSERT(peerConnection.scriptExecutionContext()->isDocument());
+ auto* page = static_cast<Document*>(peerConnection.scriptExecutionContext())->page();
+ return page->libWebRTCProvider();
+}
+
+LibWebRTCPeerConnectionBackend::LibWebRTCPeerConnectionBackend(RTCPeerConnection& peerConnection)
+ : PeerConnectionBackend(peerConnection)
+ , m_endpoint(LibWebRTCMediaEndpoint::create(*this, libWebRTCProvider(peerConnection)))
+{
+}
+
+LibWebRTCPeerConnectionBackend::~LibWebRTCPeerConnectionBackend()
+{
+}
+
+static webrtc::PeerConnectionInterface::RTCConfiguration configurationFromMediaEndpointConfiguration(MediaEndpointConfiguration&& configuration)
+{
+ webrtc::PeerConnectionInterface::RTCConfiguration rtcConfiguration(webrtc::PeerConnectionInterface::RTCConfigurationType::kAggressive);
+
+ if (configuration.iceTransportPolicy == PeerConnectionStates::IceTransportPolicy::Relay)
+ rtcConfiguration.type = webrtc::PeerConnectionInterface::kRelay;
+
+ if (configuration.bundlePolicy == PeerConnectionStates::BundlePolicy::MaxBundle)
+ rtcConfiguration.bundle_policy = webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle;
+ else if (configuration.bundlePolicy == PeerConnectionStates::BundlePolicy::MaxCompat)
+ rtcConfiguration.bundle_policy = webrtc::PeerConnectionInterface::kBundlePolicyMaxCompat;
+
+ for (auto& server : configuration.iceServers) {
+ webrtc::PeerConnectionInterface::IceServer iceServer;
+ iceServer.username = server.username.utf8().data();
+ iceServer.password = server.credential.utf8().data();
+ for (auto& url : server.urls)
+ iceServer.urls.push_back({ url.string().utf8().data() });
+ rtcConfiguration.servers.push_back(WTFMove(iceServer));
+ }
+
+ return rtcConfiguration;
+}
+
+void LibWebRTCPeerConnectionBackend::setConfiguration(MediaEndpointConfiguration&& configuration)
+{
+ m_endpoint->backend().SetConfiguration(configurationFromMediaEndpointConfiguration(WTFMove(configuration)));
+}
+
+void LibWebRTCPeerConnectionBackend::getStats(MediaStreamTrack* track, Ref<DeferredPromise>&& promise)
+{
+ if (m_endpoint->isStopped())
+ return;
+
+ auto& statsPromise = promise.get();
+ m_statsPromises.add(&statsPromise, WTFMove(promise));
+ m_endpoint->getStats(track, statsPromise);
+}
+
+void LibWebRTCPeerConnectionBackend::getStatsSucceeded(const DeferredPromise& promise, Ref<RTCStatsReport>&& report)
+{
+ auto statsPromise = m_statsPromises.take(&promise);
+ ASSERT(statsPromise);
+ statsPromise.value()->resolve<IDLInterface<RTCStatsReport>>(WTFMove(report));
+}
+
+void LibWebRTCPeerConnectionBackend::getStatsFailed(const DeferredPromise& promise, Exception&& exception)
+{
+ auto statsPromise = m_statsPromises.take(&promise);
+ ASSERT(statsPromise);
+ statsPromise.value()->reject(WTFMove(exception));
+}
+
+void LibWebRTCPeerConnectionBackend::doSetLocalDescription(RTCSessionDescription& description)
+{
+ m_endpoint->doSetLocalDescription(description);
+ if (!m_isLocalDescriptionSet) {
+ if (m_isRemoteDescriptionSet) {
+ while (m_pendingCandidates.size())
+ m_endpoint->addIceCandidate(*m_pendingCandidates.takeLast().release());
+ }
+ m_isLocalDescriptionSet = true;
+ }
+}
+
+void LibWebRTCPeerConnectionBackend::doSetRemoteDescription(RTCSessionDescription& description)
+{
+ m_endpoint->doSetRemoteDescription(description);
+ if (!m_isRemoteDescriptionSet) {
+ if (m_isLocalDescriptionSet) {
+ while (m_pendingCandidates.size())
+ m_endpoint->addIceCandidate(*m_pendingCandidates.takeLast().release());
+ }
+ m_isRemoteDescriptionSet = true;
+ }
+}
+
+void LibWebRTCPeerConnectionBackend::doCreateOffer(RTCOfferOptions&&)
+{
+ m_endpoint->doCreateOffer();
+}
+
+void LibWebRTCPeerConnectionBackend::doCreateAnswer(RTCAnswerOptions&&)
+{
+ if (!m_isRemoteDescriptionSet) {
+ createAnswerFailed(Exception { INVALID_STATE_ERR, "No remote description set" });
+ return;
+ }
+ m_endpoint->doCreateAnswer();
+}
+
+void LibWebRTCPeerConnectionBackend::doStop()
+{
+ m_endpoint->stop();
+}
+
+void LibWebRTCPeerConnectionBackend::doAddIceCandidate(RTCIceCandidate& candidate)
+{
+ if (!m_isRemoteDescriptionSet) {
+ addIceCandidateFailed(Exception { INVALID_STATE_ERR, "No remote description set" });
+ return;
+ }
+
+ webrtc::SdpParseError error;
+ int sdpMLineIndex = candidate.sdpMLineIndex() ? candidate.sdpMLineIndex().value() : 0;
+ std::unique_ptr<webrtc::IceCandidateInterface> rtcCandidate(webrtc::CreateIceCandidate(candidate.sdpMid().utf8().data(), sdpMLineIndex, candidate.candidate().utf8().data(), &error));
+
+ if (!rtcCandidate) {
+ String message(error.description.data(), error.description.size());
+ addIceCandidateFailed(Exception { OperationError, WTFMove(message) });
+ return;
+ }
+
+ // libwebrtc does not like that ice candidates are set before the description.
+ if (!m_isLocalDescriptionSet || !m_isRemoteDescriptionSet)
+ m_pendingCandidates.append(WTFMove(rtcCandidate));
+ else if (!m_endpoint->addIceCandidate(*rtcCandidate.get())) {
+ ASSERT_NOT_REACHED();
+ addIceCandidateFailed(Exception { OperationError, ASCIILiteral("Failed to apply the received candidate") });
+ return;
+ }
+ addIceCandidateSucceeded();
+}
+
+void LibWebRTCPeerConnectionBackend::addAudioSource(Ref<RealtimeOutgoingAudioSource>&& source)
+{
+ m_audioSources.append(WTFMove(source));
+}
+
+void LibWebRTCPeerConnectionBackend::addVideoSource(Ref<RealtimeOutgoingVideoSource>&& source)
+{
+ m_videoSources.append(WTFMove(source));
+}
+
+Ref<RTCRtpReceiver> LibWebRTCPeerConnectionBackend::createReceiver(const String&, const String& trackKind, const String& trackId)
+{
+ // FIXME: We need to create a source that will get fueled once we will receive OnAddStream.
+ // For the moment, we create an empty one.
+ auto remoteTrackPrivate = (trackKind == "audio") ? MediaStreamTrackPrivate::create(RealtimeIncomingAudioSource::create(nullptr, String(trackId))) : MediaStreamTrackPrivate::create(RealtimeIncomingVideoSource::create(nullptr, String(trackId)));
+ auto remoteTrack = MediaStreamTrack::create(*m_peerConnection.scriptExecutionContext(), WTFMove(remoteTrackPrivate));
+
+ return RTCRtpReceiver::create(WTFMove(remoteTrack));
+}
+
+std::unique_ptr<RTCDataChannelHandler> LibWebRTCPeerConnectionBackend::createDataChannelHandler(const String& label, const RTCDataChannelInit& options)
+{
+ return m_endpoint->createDataChannel(label, options);
+}
+
+RefPtr<RTCSessionDescription> LibWebRTCPeerConnectionBackend::localDescription() const
+{
+ return m_endpoint->localDescription();
+}
+
+RefPtr<RTCSessionDescription> LibWebRTCPeerConnectionBackend::remoteDescription() const
+{
+ return m_endpoint->remoteDescription();
+}
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h
new file mode 100644
index 000000000..f5b4c565f
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(LIBWEBRTC)
+
+#include "PeerConnectionBackend.h"
+#include <wtf/HashMap.h>
+
+namespace webrtc {
+class IceCandidateInterface;
+}
+
+namespace WebCore {
+
+class LibWebRTCMediaEndpoint;
+class RTCRtpReceiver;
+class RTCSessionDescription;
+class RTCstatsReport;
+class RealtimeOutgoingAudioSource;
+class RealtimeOutgoingVideoSource;
+
+class LibWebRTCPeerConnectionBackend final : public PeerConnectionBackend {
+public:
+ explicit LibWebRTCPeerConnectionBackend(RTCPeerConnection&);
+ ~LibWebRTCPeerConnectionBackend();
+
+private:
+ void doCreateOffer(RTCOfferOptions&&) final;
+ void doCreateAnswer(RTCAnswerOptions&&) final;
+ void doSetLocalDescription(RTCSessionDescription&) final;
+ void doSetRemoteDescription(RTCSessionDescription&) final;
+ void doAddIceCandidate(RTCIceCandidate&) final;
+ void doStop() final;
+ std::unique_ptr<RTCDataChannelHandler> createDataChannelHandler(const String&, const RTCDataChannelInit&) final;
+ void setConfiguration(MediaEndpointConfiguration&&) final;
+ void getStats(MediaStreamTrack*, Ref<DeferredPromise>&&) final;
+ Ref<RTCRtpReceiver> createReceiver(const String& transceiverMid, const String& trackKind, const String& trackId) final;
+
+ RefPtr<RTCSessionDescription> localDescription() const final;
+ RefPtr<RTCSessionDescription> currentLocalDescription() const final { return localDescription(); }
+ RefPtr<RTCSessionDescription> pendingLocalDescription() const final { return localDescription(); }
+
+ RefPtr<RTCSessionDescription> remoteDescription() const final;
+ RefPtr<RTCSessionDescription> currentRemoteDescription() const final { return remoteDescription(); }
+ RefPtr<RTCSessionDescription> pendingRemoteDescription() const final { return remoteDescription(); }
+
+ // FIXME: API to implement for real
+ Vector<RefPtr<MediaStream>> getRemoteStreams() const final { return { }; }
+ void replaceTrack(RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromise<void>&&) final { }
+
+ void emulatePlatformEvent(const String&) final { }
+
+ friend LibWebRTCMediaEndpoint;
+ RTCPeerConnection& connection() { return m_peerConnection; }
+ void addAudioSource(Ref<RealtimeOutgoingAudioSource>&&);
+ void addVideoSource(Ref<RealtimeOutgoingVideoSource>&&);
+
+ void getStatsSucceeded(const DeferredPromise&, Ref<RTCStatsReport>&&);
+ void getStatsFailed(const DeferredPromise&, Exception&&);
+
+private:
+ Ref<LibWebRTCMediaEndpoint> m_endpoint;
+ bool m_isLocalDescriptionSet { false };
+ bool m_isRemoteDescriptionSet { false };
+
+ Vector<std::unique_ptr<webrtc::IceCandidateInterface>> m_pendingCandidates;
+ Vector<Ref<RealtimeOutgoingAudioSource>> m_audioSources;
+ Vector<Ref<RealtimeOutgoingVideoSource>> m_videoSources;
+ HashMap<const DeferredPromise*, Ref<DeferredPromise>> m_statsPromises;
+};
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/Modules/mediastream/sdp.js b/Source/WebCore/Modules/mediastream/sdp.js
new file mode 100644
index 000000000..ecd256070
--- /dev/null
+++ b/Source/WebCore/Modules/mediastream/sdp.js
@@ -0,0 +1,606 @@
+/*
+ * Copyright (C) 2014-2015 Ericsson AB. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+if (typeof(SDP) == "undefined")
+ var SDP = {};
+
+(function () {
+ var regexps = {
+ "vline": "^v=([\\d]+).*$",
+ "oline": "^o=([\\w\\-@\\.]+) ([\\d]+) ([\\d]+) IN (IP[46]) ([\\d\\.a-f\\:]+).*$",
+ "sline": "^s=(.*)$",
+ "tline": "^t=([\\d]+) ([\\d]+).*$",
+ "cline": "^c=IN (IP[46]) ([\\d\\.a-f\\:]+).*$",
+ "msidsemantic": "^a=msid-semantic: *WMS .*$",
+ "mblock": "^m=(audio|video|application) ([\\d]+) ([A-Z/]+)([\\d ]*)$\\r?\\n",
+ "mode": "^a=(sendrecv|sendonly|recvonly|inactive).*$",
+ "mid": "^a=mid:([!#$%&'*+-.\\w]*).*$",
+ "rtpmap": "^a=rtpmap:${type} ([\\w\\-]+)/([\\d]+)/?([\\d]+)?.*$",
+ "fmtp": "^a=fmtp:${type} ([\\w\\-=; ]+).*$",
+ "param": "([\\w\\-]+)=([\\w\\-]+);?",
+ "nack": "^a=rtcp-fb:${type} nack$",
+ "nackpli": "^a=rtcp-fb:${type} nack pli$",
+ "ccmfir": "^a=rtcp-fb:${type} ccm fir$",
+ "ericscream": "^a=rtcp-fb:${type} ericscream$",
+ "rtcp": "^a=rtcp:([\\d]+)( IN (IP[46]) ([\\d\\.a-f\\:]+))?.*$",
+ "rtcpmux": "^a=rtcp-mux.*$",
+ "cname": "^a=ssrc:(\\d+) cname:([\\w+/\\-@\\.\\{\\}]+).*$",
+ "msid": "^a=(ssrc:\\d+ )?msid:([\\w+/\\-=]+) +([\\w+/\\-=]+).*$",
+ "ufrag": "^a=ice-ufrag:([\\w+/]*).*$",
+ "pwd": "^a=ice-pwd:([\\w+/]*).*$",
+ "candidate": "^a=candidate:(\\d+) (\\d) (UDP|TCP) ([\\d\\.]*) ([\\d\\.a-f\\:]*) (\\d*)" +
+ " typ ([a-z]*)( raddr ([\\d\\.a-f\\:]*) rport (\\d*))?" +
+ "( tcptype (active|passive|so))?.*$",
+ "fingerprint": "^a=fingerprint:(sha-1|sha-256) ([A-Fa-f\\d\:]+).*$",
+ "setup": "^a=setup:(actpass|active|passive).*$",
+ "sctpmap": "^a=sctpmap:${port} ([\\w\\-]+)( [\\d]+)?.*$"
+ };
+
+ var templates = {
+ "sdp":
+ "v=${version}\r\n" +
+ "o=${username} ${sessionId} ${sessionVersion} ${netType} ${addressType} ${address}\r\n" +
+ "s=${sessionName}\r\n" +
+ "t=${startTime} ${stopTime}\r\n" +
+ "${msidsemanticLine}",
+
+ "msidsemantic": "a=msid-semantic:WMS ${mediaStreamIds}\r\n",
+
+ "mblock":
+ "m=${type} ${port} ${protocol} ${fmt}\r\n" +
+ "c=${netType} ${addressType} ${address}\r\n" +
+ "${rtcpLine}" +
+ "${rtcpMuxLine}" +
+ "a=${mode}\r\n" +
+ "${midLine}" +
+ "${rtpMapLines}" +
+ "${fmtpLines}" +
+ "${nackLines}" +
+ "${nackpliLines}" +
+ "${ccmfirLines}" +
+ "${ericScreamLines}" +
+ "${cnameLines}" +
+ "${msidLines}" +
+ "${iceCredentialLines}" +
+ "${candidateLines}" +
+ "${dtlsFingerprintLine}" +
+ "${dtlsSetupLine}" +
+ "${sctpmapLine}",
+
+ "rtcp": "a=rtcp:${port}${[ ]netType}${[ ]addressType}${[ ]address}\r\n",
+ "rtcpMux": "a=rtcp-mux\r\n",
+ "mid": "a=mid:${mid}\r\n",
+
+ "rtpMap": "a=rtpmap:${type} ${encodingName}/${clockRate}${[/]channels}\r\n",
+ "fmtp": "a=fmtp:${type} ${parameters}\r\n",
+ "nack": "a=rtcp-fb:${type} nack\r\n",
+ "nackpli": "a=rtcp-fb:${type} nack pli\r\n",
+ "ccmfir": "a=rtcp-fb:${type} ccm fir\r\n",
+ "ericscream": "a=rtcp-fb:${type} ericscream\r\n",
+
+ "cname": "a=ssrc:${ssrc} cname:${cname}\r\n",
+ "msid": "a=msid:${mediaStreamId} ${mediaStreamTrackId}\r\n",
+
+ "iceCredentials":
+ "a=ice-ufrag:${ufrag}\r\n" +
+ "a=ice-pwd:${password}\r\n",
+
+ "candidate":
+ "a=candidate:${foundation} ${componentId} ${transport} ${priority} ${address} ${port}" +
+ " typ ${type}${[ raddr ]relatedAddress}${[ rport ]relatedPort}${[ tcptype ]tcpType}\r\n",
+
+ "dtlsFingerprint": "a=fingerprint:${fingerprintHashFunction} ${fingerprint}\r\n",
+ "dtlsSetup": "a=setup:${setup}\r\n",
+
+ "sctpmap": "a=sctpmap:${port} ${app}${[ ]streams}\r\n"
+ };
+
+ function match(data, pattern, flags, alt) {
+ var r = new RegExp(pattern, flags);
+ return data.match(r) || alt && alt.match(r) || null;
+ }
+
+ function addDefaults(obj, defaults) {
+ for (var p in defaults) {
+ if (!defaults.hasOwnProperty(p))
+ continue;
+ if (typeof(obj[p]) == "undefined")
+ obj[p] = defaults[p];
+ }
+ }
+
+ function fillTemplate(template, info) {
+ var text = template;
+ for (var p in info) {
+ if (!info.hasOwnProperty(p))
+ continue;
+ var r = new RegExp("\\${(\\[[^\\]]+\\])?" + p + "(\\[[^\\]]+\\])?}");
+ text = text.replace(r, function (_, prefix, suffix) {
+ if (!info[p] && info[p] != 0)
+ return "";
+ prefix = prefix ? prefix.substr(1, prefix.length - 2) : "";
+ suffix = suffix ? suffix.substr(1, suffix.length - 2) : "";
+ return prefix + info[p] + suffix;
+ });
+ }
+ return text;
+ }
+
+ SDP.parse = function (sdpText) {
+ sdpText = new String(sdpText);
+ var sdpObj = {};
+ var parts = sdpText.split(new RegExp(regexps.mblock, "m")) || [sdpText];
+ var sblock = parts.shift();
+ var version = parseInt((match(sblock, regexps.vline, "m") || [])[1]);
+ if (!isNaN(version))
+ sdpObj.version = version;
+ var originator = match(sblock, regexps.oline, "m");;
+ if (originator) {
+ sdpObj.originator = {
+ "username": originator[1],
+ "sessionId": originator[2],
+ "sessionVersion": parseInt(originator[3]),
+ "netType": "IN",
+ "addressType": originator[4],
+ "address": originator[5]
+ };
+ }
+ var sessionName = match(sblock, regexps.sline, "m");
+ if (sessionName)
+ sdpObj.sessionName = sessionName[1];
+ var sessionTime = match(sblock, regexps.tline, "m");
+ if (sessionTime) {
+ sdpObj.startTime = parseInt(sessionTime[1]);
+ sdpObj.stopTime = parseInt(sessionTime[2]);
+ }
+ var hasMediaStreamId = !!match(sblock, regexps.msidsemantic, "m");
+ sdpObj.mediaDescriptions = [];
+
+ for (var i = 0; i < parts.length; i += 5) {
+ var mediaDescription = {
+ "type": parts[i],
+ "port": parseInt(parts[i + 1]),
+ "protocol": parts[i + 2],
+ };
+ var fmt = parts[i + 3].replace(/^[\s\uFEFF\xA0]+/, '')
+ .split(/ +/)
+ .map(function (x) {
+ return parseInt(x);
+ });
+ var mblock = parts[i + 4];
+
+ var connection = match(mblock, regexps.cline, "m", sblock);
+ if (connection) {
+ mediaDescription.netType = "IN";
+ mediaDescription.addressType = connection[1];
+ mediaDescription.address = connection[2];
+ }
+ var mode = match(mblock, regexps.mode, "m", sblock);
+ if (mode)
+ mediaDescription.mode = mode[1];
+
+ var mid = match(mblock, regexps.mid, "m", sblock);
+ if (mid)
+ mediaDescription.mid = mid[1];
+
+ var payloadTypes = [];
+ if (match(mediaDescription.protocol, "(UDP/TLS)?RTP/S?AVPF?")) {
+ mediaDescription.payloads = [];
+ payloadTypes = fmt;
+ }
+ payloadTypes.forEach(function (payloadType) {
+ var payload = { "type": payloadType };
+ var rtpmapLine = fillTemplate(regexps.rtpmap, payload);
+ var rtpmap = match(mblock, rtpmapLine, "m");
+ if (rtpmap) {
+ payload.encodingName = rtpmap[1];
+ payload.clockRate = parseInt(rtpmap[2]);
+ if (mediaDescription.type == "audio")
+ payload.channels = parseInt(rtpmap[3]) || 1;
+ else if (mediaDescription.type == "video") {
+ var nackLine = fillTemplate(regexps.nack, payload);
+ payload.nack = !!match(mblock, nackLine, "m");
+ var nackpliLine = fillTemplate(regexps.nackpli, payload);
+ payload.nackpli = !!match(mblock, nackpliLine, "m");
+ var ccmfirLine = fillTemplate(regexps.ccmfir, payload);
+ payload.ccmfir = !!match(mblock, ccmfirLine, "m");
+ var ericScreamLine = fillTemplate(regexps.ericscream, payload);
+ payload.ericscream = !!match(mblock, ericScreamLine, "m");
+ }
+ } else if (payloadType == 0 || payloadType == 8) {
+ payload.encodingName = payloadType == 8 ? "PCMA" : "PCMU";
+ payload.clockRate = 8000;
+ payload.channels = 1;
+ }
+ var fmtpLine = fillTemplate(regexps.fmtp, payload);
+ var fmtp = match(mblock, fmtpLine, "m");
+ if (fmtp) {
+ payload.parameters = {};
+ fmtp[1].replace(new RegExp(regexps.param, "g"),
+ function(_, key, value) {
+ key = key.replace(/-([a-z])/g, function (_, c) {
+ return c.toUpperCase();
+ });
+ payload.parameters[key] = isNaN(+value) ? value : +value;
+ });
+ }
+ mediaDescription.payloads.push(payload);
+ });
+
+ var rtcp = match(mblock, regexps.rtcp, "m");
+ if (rtcp) {
+ mediaDescription.rtcp = {
+ "netType": "IN",
+ "port": parseInt(rtcp[1])
+ };
+ if (rtcp[2]) {
+ mediaDescription.rtcp.addressType = rtcp[3];
+ mediaDescription.rtcp.address = rtcp[4];
+ }
+ }
+ var rtcpmux = match(mblock, regexps.rtcpmux, "m", sblock);
+ if (rtcpmux) {
+ if (!mediaDescription.rtcp)
+ mediaDescription.rtcp = {};
+ mediaDescription.rtcp.mux = true;
+ }
+
+ var cnameLines = match(mblock, regexps.cname, "mg");
+ if (cnameLines) {
+ mediaDescription.ssrcs = [];
+ cnameLines.forEach(function (line) {
+ var cname = match(line, regexps.cname, "m");
+ mediaDescription.ssrcs.push(parseInt(cname[1]));
+ if (!mediaDescription.cname)
+ mediaDescription.cname = cname[2];
+ });
+ }
+
+ if (hasMediaStreamId) {
+ var msid = match(mblock, regexps.msid, "m");
+ if (msid) {
+ mediaDescription.mediaStreamId = msid[2];
+ mediaDescription.mediaStreamTrackId = msid[3];
+ }
+ }
+
+ var ufrag = match(mblock, regexps.ufrag, "m", sblock);
+ var pwd = match(mblock, regexps.pwd, "m", sblock);
+ if (ufrag && pwd) {
+ mediaDescription.ice = {
+ "ufrag": ufrag[1],
+ "password": pwd[1]
+ };
+ }
+ var candidateLines = match(mblock, regexps.candidate, "mig");
+ if (candidateLines) {
+ if (!mediaDescription.ice)
+ mediaDescription.ice = {};
+ mediaDescription.ice.candidates = [];
+ candidateLines.forEach(function (line) {
+ var candidateLine = match(line, regexps.candidate, "mi");
+ var candidate = {
+ "foundation": candidateLine[1],
+ "componentId": parseInt(candidateLine[2]),
+ "transport": candidateLine[3].toUpperCase(),
+ "priority": parseInt(candidateLine[4]),
+ "address": candidateLine[5],
+ "port": parseInt(candidateLine[6]),
+ "type": candidateLine[7]
+ };
+ if (candidateLine[9])
+ candidate.relatedAddress = candidateLine[9];
+ if (!isNaN(candidateLine[10]))
+ candidate.relatedPort = parseInt(candidateLine[10]);
+ if (candidateLine[12])
+ candidate.tcpType = candidateLine[12];
+ else if (candidate.transport == "TCP") {
+ if (candidate.port == 0 || candidate.port == 9) {
+ candidate.tcpType = "active";
+ candidate.port = 9;
+ } else {
+ return;
+ }
+ }
+ mediaDescription.ice.candidates.push(candidate);
+ });
+ }
+
+ var fingerprint = match(mblock, regexps.fingerprint, "mi", sblock);
+ if (fingerprint) {
+ mediaDescription.dtls = {
+ "fingerprintHashFunction": fingerprint[1].toLowerCase(),
+ "fingerprint": fingerprint[2].toUpperCase()
+ };
+ }
+ var setup = match(mblock, regexps.setup, "m", sblock);
+ if (setup) {
+ if (!mediaDescription.dtls)
+ mediaDescription.dtls = {};
+ mediaDescription.dtls.setup = setup[1];
+ }
+
+ if (mediaDescription.protocol == "DTLS/SCTP") {
+ mediaDescription.sctp = {
+ "port": fmt[0]
+ };
+ var sctpmapLine = fillTemplate(regexps.sctpmap, mediaDescription.sctp);
+ var sctpmap = match(mblock, sctpmapLine, "m");
+ if (sctpmap) {
+ mediaDescription.sctp.app = sctpmap[1];
+ if (sctpmap[2])
+ mediaDescription.sctp.streams = parseInt(sctpmap[2]);
+ }
+ }
+
+ sdpObj.mediaDescriptions.push(mediaDescription);
+ }
+
+ return sdpObj;
+ };
+
+ SDP.generate = function (sdpObj) {
+ sdpObj = JSON.parse(JSON.stringify(sdpObj));
+ addDefaults(sdpObj, {
+ "version": 0,
+ "originator": {},
+ "sessionName": "-",
+ "startTime": 0,
+ "stopTime": 0,
+ "mediaDescriptions": []
+ });
+ addDefaults(sdpObj.originator, {
+ "username": "-",
+ "sessionId": "" + Math.floor((Math.random() + +new Date()) * 1e6),
+ "sessionVersion": 1,
+ "netType": "IN",
+ "addressType": "IP4",
+ "address": "127.0.0.1"
+ });
+ var sdpText = fillTemplate(templates.sdp, sdpObj);
+ sdpText = fillTemplate(sdpText, sdpObj.originator);
+
+ var msidsemanticLine = "";
+ var mediaStreamIds = [];
+ sdpObj.mediaDescriptions.forEach(function (mdesc) {
+ if (mdesc.mediaStreamId && mdesc.mediaStreamTrackId
+ && mediaStreamIds.indexOf(mdesc.mediaStreamId) == -1)
+ mediaStreamIds.push(mdesc.mediaStreamId);
+ });
+ if (mediaStreamIds.length) {
+ var msidsemanticLine = fillTemplate(templates.msidsemantic,
+ { "mediaStreamIds": mediaStreamIds.join(" ") });
+ }
+ sdpText = fillTemplate(sdpText, { "msidsemanticLine": msidsemanticLine });
+
+ sdpObj.mediaDescriptions.forEach(function (mediaDescription) {
+ addDefaults(mediaDescription, {
+ "port": 9,
+ "protocol": "UDP/TLS/RTP/SAVPF",
+ "netType": "IN",
+ "addressType": "IP4",
+ "address": "0.0.0.0",
+ "mode": "sendrecv",
+ "payloads": [],
+ "rtcp": {}
+ });
+ var mblock = fillTemplate(templates.mblock, mediaDescription);
+
+ var midInfo = {"midLine": ""};
+ if (mediaDescription.mid)
+ midInfo.midLine = fillTemplate(templates.mid, mediaDescription);
+ mblock = fillTemplate(mblock, midInfo);
+
+ var payloadInfo = {"rtpMapLines": "", "fmtpLines": "", "nackLines": "",
+ "nackpliLines": "", "ccmfirLines": "", "ericScreamLines": ""};
+ mediaDescription.payloads.forEach(function (payload) {
+ if (payloadInfo.fmt)
+ payloadInfo.fmt += " " + payload.type;
+ else
+ payloadInfo.fmt = payload.type;
+ if (!payload.channels || payload.channels == 1)
+ payload.channels = null;
+ payloadInfo.rtpMapLines += fillTemplate(templates.rtpMap, payload);
+ if (payload.parameters) {
+ var fmtpInfo = { "type": payload.type, "parameters": "" };
+ for (var p in payload.parameters) {
+ var param = p.replace(/([A-Z])([a-z])/g, function (_, a, b) {
+ return "-" + a.toLowerCase() + b;
+ });
+ if (fmtpInfo.parameters)
+ fmtpInfo.parameters += ";";
+ fmtpInfo.parameters += param + "=" + payload.parameters[p];
+ }
+ payloadInfo.fmtpLines += fillTemplate(templates.fmtp, fmtpInfo);
+ }
+ if (payload.nack)
+ payloadInfo.nackLines += fillTemplate(templates.nack, payload);
+ if (payload.nackpli)
+ payloadInfo.nackpliLines += fillTemplate(templates.nackpli, payload);
+ if (payload.ccmfir)
+ payloadInfo.ccmfirLines += fillTemplate(templates.ccmfir, payload);
+ if (payload.ericscream)
+ payloadInfo.ericScreamLines += fillTemplate(templates.ericscream, payload);
+ });
+ mblock = fillTemplate(mblock, payloadInfo);
+
+ var rtcpInfo = {"rtcpLine": "", "rtcpMuxLine": ""};
+ if (mediaDescription.rtcp.port) {
+ addDefaults(mediaDescription.rtcp, {
+ "netType": "IN",
+ "addressType": "IP4",
+ "address": ""
+ });
+ if (!mediaDescription.rtcp.address)
+ mediaDescription.rtcp.netType = mediaDescription.rtcp.addressType = "";
+ rtcpInfo.rtcpLine = fillTemplate(templates.rtcp, mediaDescription.rtcp);
+ }
+ if (mediaDescription.rtcp.mux)
+ rtcpInfo.rtcpMuxLine = templates.rtcpMux;
+ mblock = fillTemplate(mblock, rtcpInfo);
+
+ var srcAttributeLines = { "cnameLines": "", "msidLines": "" };
+ var srcAttributes = {
+ "cname": mediaDescription.cname,
+ "mediaStreamId": mediaDescription.mediaStreamId,
+ "mediaStreamTrackId": mediaDescription.mediaStreamTrackId
+ };
+ if (mediaDescription.cname && mediaDescription.ssrcs) {
+ mediaDescription.ssrcs.forEach(function (ssrc) {
+ srcAttributes.ssrc = ssrc;
+ srcAttributeLines.cnameLines += fillTemplate(templates.cname, srcAttributes);
+ if (mediaDescription.mediaStreamId && mediaDescription.mediaStreamTrackId)
+ srcAttributeLines.msidLines += fillTemplate(templates.msid, srcAttributes);
+ });
+ } else if (mediaDescription.mediaStreamId && mediaDescription.mediaStreamTrackId) {
+ srcAttributes.ssrc = null;
+ srcAttributeLines.msidLines += fillTemplate(templates.msid, srcAttributes);
+ }
+ mblock = fillTemplate(mblock, srcAttributeLines);
+
+ var iceInfo = {"iceCredentialLines": "", "candidateLines": ""};
+ if (mediaDescription.ice) {
+ iceInfo.iceCredentialLines = fillTemplate(templates.iceCredentials,
+ mediaDescription.ice);
+ if (mediaDescription.ice.candidates) {
+ mediaDescription.ice.candidates.forEach(function (candidate) {
+ addDefaults(candidate, {
+ "relatedAddress": null,
+ "relatedPort": null,
+ "tcpType": null
+ });
+ iceInfo.candidateLines += fillTemplate(templates.candidate, candidate);
+ });
+ }
+ }
+ mblock = fillTemplate(mblock, iceInfo);
+
+ var dtlsInfo = { "dtlsFingerprintLine": "", "dtlsSetupLine": "" };
+ if (mediaDescription.dtls) {
+ if (mediaDescription.dtls.fingerprint) {
+ dtlsInfo.dtlsFingerprintLine = fillTemplate(templates.dtlsFingerprint,
+ mediaDescription.dtls);
+ }
+ addDefaults(mediaDescription.dtls, {"setup": "actpass"});
+ dtlsInfo.dtlsSetupLine = fillTemplate(templates.dtlsSetup, mediaDescription.dtls);
+ }
+ mblock = fillTemplate(mblock, dtlsInfo);
+
+ var sctpInfo = {"sctpmapLine": "", "fmt": ""};
+ if (mediaDescription.sctp) {
+ addDefaults(mediaDescription.sctp, {"streams": null});
+ sctpInfo.sctpmapLine = fillTemplate(templates.sctpmap, mediaDescription.sctp);
+ sctpInfo.fmt = mediaDescription.sctp.port;
+ }
+ mblock = fillTemplate(mblock, sctpInfo);
+
+ sdpText += mblock;
+ });
+
+ return sdpText;
+ };
+
+ SDP.generateCandidateLine = function (candidateObj) {
+ addDefaults(candidateObj, {
+ "relatedAddress": null,
+ "relatedPort": null,
+ "tcpType": null
+ });
+
+ return fillTemplate(templates.candidate, candidateObj);
+ };
+
+ var expectedProperties = {
+ "session": [ "version", "originator", "sessionName", "startTime", "stopTime" ],
+ "mline": [ "type", "port", "protocol", "mode", "payloads", "rtcp", "dtls", "ice" ],
+ "mlineSubObjects": {
+ "rtcp": [ "mux" ],
+ "ice": [ "ufrag", "password" ],
+ "dtls": [ "setup", "fingerprintHashFunction", "fingerprint" ]
+ }
+ };
+
+ function hasAllProperties(object, properties) {
+ var missing = properties.filter(function (property) {
+ return !object.hasOwnProperty(property);
+ });
+
+ return !missing.length;
+ }
+
+ SDP.verifyObject = function (sdpObj) {
+ if (!hasAllProperties(sdpObj, expectedProperties.session))
+ return false;
+
+ for (var i = 0; i < sdpObj.mediaDescriptions.length; i++) {
+ var mediaDescription = sdpObj.mediaDescriptions[i];
+
+ if (!hasAllProperties(mediaDescription, expectedProperties.mline))
+ return false;
+
+ for (var p in expectedProperties.mlineSubObjects) {
+ if (!hasAllProperties(mediaDescription[p], expectedProperties.mlineSubObjects[p]))
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+})();
+
+function generate(json) {
+ var object = JSON.parse(json);
+ return SDP.generate(object);
+}
+
+function parse(sdp) {
+ var object = SDP.parse(sdp);
+
+ if (!SDP.verifyObject(object))
+ return "ParseError";
+
+ return JSON.stringify(object);
+}
+
+function generateCandidateLine(json) {
+ var candidate = JSON.parse(json);
+ return SDP.generateCandidateLine(candidate).substr(2);
+}
+
+function parseCandidateLine(candidateLine) {
+ var mdesc = SDP.parse("m=application 0 NONE\r\na=" + candidateLine + "\r\n").mediaDescriptions[0];
+ if (!mdesc.ice)
+ return "ParseError";
+
+ return JSON.stringify(mdesc.ice.candidates[0]);
+}
+
+if (typeof(module) != "undefined" && typeof(exports) != "undefined")
+ module.exports = SDP;