Diff
Modified: trunk/LayoutTests/ChangeLog (211252 => 211253)
--- trunk/LayoutTests/ChangeLog 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/LayoutTests/ChangeLog 2017-01-27 04:54:09 UTC (rev 211253)
@@ -1,3 +1,27 @@
+2017-01-26 Youenn Fablet <youe...@gmail.com>
+
+ [WebRTC] Add a LibWebRTC mock for testing
+ https://bugs.webkit.org/show_bug.cgi?id=167429
+
+ Reviewed by Alex Christensen.
+
+ * TestExpectations: Marking webrtc new tests as skipped for the moment.
+ * fast/mediastream/RTCPeerConnection-createAnswer.html:
+ * fast/mediastream/RTCPeerConnection-icecandidate-event.html:
+ * fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html:
+ * webrtc/datachannel/basic.html: Added.
+ * webrtc/routines.js: Added.
+ (createConnections):
+ (closeConnections):
+ (onCreateSessionDescriptionError):
+ (gotDescription1):
+ (gotDescription2):
+ (iceCallback1):
+ (iceCallback2):
+ (onAddIceCandidateSuccess):
+ (onAddIceCandidateError):
+ * webrtc/video.html: Added.
+
2017-01-26 Daniel Bates <daba...@apple.com>
[QuickLook] Add test to ensure that RTF documents have a unique origin
Modified: trunk/LayoutTests/TestExpectations (211252 => 211253)
--- trunk/LayoutTests/TestExpectations 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/LayoutTests/TestExpectations 2017-01-27 04:54:09 UTC (rev 211253)
@@ -679,6 +679,9 @@
# Media Sessions is not yet enabled by default: ENABLE(MEDIA_SESSION)
media/session [ Skip ]
+# WebRTC backend not enabled by default.
+webrtc [ Skip ]
+
# Only iOS WK1 has testRunner.setPagePaused.
fast/dom/timer-fire-after-page-pause.html [ Skip ]
Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-createAnswer.html (211252 => 211253)
--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-createAnswer.html 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-createAnswer.html 2017-01-27 04:54:09 UTC (rev 211253)
@@ -67,13 +67,13 @@
{
testPassed('createAnswer request succeeded.');
- sessionDescription = new RTCSessionDescription({type:"offer", sdp:"remote"});
+ sessionDescription = new RTCSessionDescription({type:"offer", sdp:"v=0\r\no=- 5667094644266930845 0 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n"});
shouldNotThrow('pc.setRemoteDescription(sessionDescription, setDescriptionSucceeded, setDescriptionFailed);');
}
- function setDescriptionFailed()
+ function setDescriptionFailed(message)
{
- testFailed('setRemoteDescription failed.');
+ testFailed('setRemoteDescription failed: ' + message);
finishJSTest();
}
@@ -81,7 +81,7 @@
function setDescriptionSucceeded()
{
testPassed('setRemoteDescription succeeded.');
- shouldThrow('pc.createAnswer(requestSucceeded2, requestFailed2, {});');
+ pc.createAnswer(requestSucceeded2, requestFailed2, {});
}
pc = new RTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});
Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-icecandidate-event.html (211252 => 211253)
--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-icecandidate-event.html 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-icecandidate-event.html 2017-01-27 04:54:09 UTC (rev 211253)
@@ -10,6 +10,9 @@
description("Test RTCPeerConnection 'icecandidate' event and gathering done");
+ if (window.internals)
+ internals.useMockRTCPeerConnectionFactory("ICECandidates");
+
if (window.testRunner)
testRunner.setUserMediaPermission(true);
else {
Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html (211252 => 211253)
--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html 2017-01-27 04:54:09 UTC (rev 211253)
@@ -8,6 +8,9 @@
<script>
description("Test RTCPeerConnection 'iceconnectionstatechange' event");
+ if (window.internals)
+ internals.useMockRTCPeerConnectionFactory("ICEConnectionState");
+
let expectedState;
let expectedStates = [
"checking",
Added: trunk/LayoutTests/fast/mediastream/getUserMedia-webaudio-expected.txt (0 => 211253)
--- trunk/LayoutTests/fast/mediastream/getUserMedia-webaudio-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getUserMedia-webaudio-expected.txt 2017-01-27 04:54:09 UTC (rev 211253)
@@ -0,0 +1,3 @@
+
+PASS Plugging in getUserMedia audio stream into Web Audio
+
Added: trunk/LayoutTests/fast/mediastream/getUserMedia-webaudio.html (0 => 211253)
--- trunk/LayoutTests/fast/mediastream/getUserMedia-webaudio.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getUserMedia-webaudio.html 2017-01-27 04:54:09 UTC (rev 211253)
@@ -0,0 +1,47 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Testing getUserMedia plugged in Web Audio</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script>
+if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+
+var finishTest, errorTest;
+promise_test((test) => {
+ return navigator.mediaDevices.getUserMedia({ audio: true}).then((stream) => {
+ return new Promise((resolve, reject) => {
+ finishTest = resolve;
+ errorTest = reject;
+ var audioContext = new webkitAudioContext();
+ var script = audioContext.createScriptProcessor(2048, 1, 1);
+ script._onaudioprocess_ = (event) => {
+ var sum = 0.0;
+ var squaredSum = 0.0;
+ event.inputBuffer.getChannelData(0).forEach((value) => {
+ sum += value;
+ squaredSum += value * value;
+ });
+ if (Math.abs(sum) > 5)
+ errorTest("sum is not below 1");
+ // Mock source should send some bips with sufficient energy to finish the test
+ if (squaredSum > 30) {
+ source.disconnect(script);
+ script.disconnect(audioContext.destination);
+ finishTest();
+ }
+ };
+ let source = audioContext.createMediaStreamSource(stream);
+
+ source.connect(script);
+ script.connect(audioContext.destination);
+ });
+ });
+}, "Plugging in getUserMedia audio stream into Web Audio");
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/webrtc/datachannel/basic.html (0 => 211253)
--- trunk/LayoutTests/webrtc/datachannel/basic.html (rev 0)
+++ trunk/LayoutTests/webrtc/datachannel/basic.html 2017-01-27 04:54:09 UTC (rev 211253)
@@ -0,0 +1,93 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Testing basic data channel from offerer to receiver</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script src =""
+ <script>
+if (window.internals)
+ internals.useMockRTCPeerConnectionFactory("TwoRealPeerConnections");
+
+var localChannel;
+var remoteChannel;
+
+function startTest() {
+ createConnections((localConnection) => {
+ localChannel = localConnection.createDataChannel('sendDataChannel');
+ localChannel._onopen_ = () => { sendMessages(localChannel) };
+ }, (remoteConnection) => {
+ remoteConnection._ondatachannel_ = (event) => {
+ remoteChannel = event.channel;
+ remoteChannel._onmessage_ = receiveMessages;
+ };
+ });
+}
+
+function closeDataChannels() {
+ localChannel.close();
+ remoteChannel.close();
+ closeConnections();
+}
+
+function receiveMessages(event) {
+ if (++counter === 1)
+ assert_equals(event.data, "one");
+ else if (counter === 2)
+ assert_equals(event.data, "two");
+ else if (counter === 3)
+ assert_equals(event.data, "three");
+ else if (counter === 4) {
+ assert_equals(event.data, "four");
+ closeDataChannels();
+ finishTest();
+ } else
+ assert_unreached();
+}
+
+function sendMessages(channel)
+{
+ channel.send("one");
+ channel.send("two");
+ channel.send("three");
+ channel.send("four");
+}
+
+var finishTest;
+promise_test((test) => {
+ counter = 0;
+ return new Promise((resolve, reject) => {
+ finishTest = resolve;
+ createConnections((localConnection) => {
+ localChannel = localConnection.createDataChannel('sendDataChannel');
+ localChannel._onopen_ = () => { sendMessages(localChannel) };
+ }, (remoteConnection) => {
+ remoteConnection._ondatachannel_ = (event) => {
+ remoteChannel = event.channel;
+ remoteChannel._onmessage_ = receiveMessages;
+ };
+ });
+ });
+}, "Basic data channel exchange from offerer to receiver");
+
+promise_test((test) => {
+ counter = 0;
+ return new Promise((resolve, reject) => {
+ finishTest = resolve;
+ createConnections((localConnection) => {
+ localChannel = localConnection.createDataChannel('sendDataChannel');
+ localChannel._onmessage_ = receiveMessages;
+ }, (remoteConnection) => {
+ remoteConnection._ondatachannel_ = (event) => {
+ remoteChannel = event.channel;
+ remoteChannel._onopen_ = () => { sendMessages(remoteChannel) };
+ };
+ });
+ });
+}, "Basic data channel exchange from receiver to offerer");
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/webrtc/routines.js (0 => 211253)
--- trunk/LayoutTests/webrtc/routines.js (rev 0)
+++ trunk/LayoutTests/webrtc/routines.js 2017-01-27 04:54:09 UTC (rev 211253)
@@ -0,0 +1,62 @@
+// Test inspired from https://webrtc.github.io/samples/
+var localConnection;
+var remoteConnection;
+
+function createConnections(setupLocalConnection, setupRemoteConnection) {
+ localConnection = new RTCPeerConnection();
+ localConnection._onicecandidate_ = iceCallback1;
+ setupLocalConnection(localConnection);
+
+ remoteConnection = new RTCPeerConnection();
+ remoteConnection._onicecandidate_ = iceCallback2;
+ setupRemoteConnection(remoteConnection);
+
+ localConnection.createOffer().then(gotDescription1, onCreateSessionDescriptionError);
+
+ return [localConnection, remoteConnection]
+}
+
+function closeConnections()
+{
+ localConnection.close();
+ remoteConnection.close();
+}
+
+function onCreateSessionDescriptionError(error)
+{
+ assert_unreached();
+}
+
+function gotDescription1(desc)
+{
+ localConnection.setLocalDescription(desc);
+ remoteConnection.setRemoteDescription(desc);
+ remoteConnection.createAnswer().then(gotDescription2, onCreateSessionDescriptionError);
+}
+
+function gotDescription2(desc)
+{
+ remoteConnection.setLocalDescription(desc);
+ localConnection.setRemoteDescription(desc);
+}
+
+function iceCallback1(event)
+{
+ if (event.candidate)
+ remoteConnection.addIceCandidate(event.candidate).then(onAddIceCandidateSuccess, onAddIceCandidateError);
+}
+
+function iceCallback2(event)
+{
+ if (event.candidate)
+ localConnection.addIceCandidate(event.candidate).then(onAddIceCandidateSuccess, onAddIceCandidateError);
+}
+
+function onAddIceCandidateSuccess()
+{
+}
+
+function onAddIceCandidateError(error)
+{
+ assert_unreached();
+}
Added: trunk/LayoutTests/webrtc/video.html (0 => 211253)
--- trunk/LayoutTests/webrtc/video.html (rev 0)
+++ trunk/LayoutTests/webrtc/video.html 2017-01-27 04:54:09 UTC (rev 211253)
@@ -0,0 +1,80 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Testing basic data channel from offerer to receiver</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <video id="video" autoplay=""></video>
+ <canvas id="canvas" width="640" height="480"></canvas>
+ <script src =""
+ <script>
+if (window.internals)
+ internals.useMockRTCPeerConnectionFactory("TwoRealPeerConnections");
+
+if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+
+video = document.getElementById("video");
+canvas = document.getElementById("canvas");
+// FIXME: We should use tracks
+
+function testImage()
+{
+ try {
+ canvas.width = video.videoWidth;
+ canvas.height = video.videoHeight;
+ canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
+
+ imageData = canvas.getContext('2d').getImageData(10, 325, 250, 1);
+ data = ""
+
+ var index = 20;
+ assert_true(data[index] < 100);
+ assert_true(data[index + 1] < 100);
+ assert_true(data[index + 2] < 100);
+
+ index = 80;
+ assert_true(data[index] > 200);
+ assert_true(data[index + 1] > 200);
+ assert_true(data[index + 2] > 200);
+
+ index += 80;
+ assert_true(data[index] > 200);
+ assert_true(data[index + 1] > 200);
+ assert_true(data[index + 2] < 100);
+
+ finishTest();
+ } catch(e) {
+ errorTest(e);
+ }
+}
+
+function testStream(stream)
+{
+ video.srcObject = stream;
+ // Video may play with black frames
+ video._onplay_ = setTimeout(() => {
+ testImage();
+ }, 1000);
+}
+
+var finishTest, errorTest;
+promise_test((test) => {
+ return navigator.mediaDevices.getUserMedia({ video: true}).then((stream) => {
+ return new Promise((resolve, reject) => {
+ finishTest = resolve;
+ errorTest = reject;
+ createConnections((firstConnection) => {
+ firstConnection.addStream(stream);
+ }, (secondConnection) => {
+ secondConnection._onaddstream_ = (streamEvent) => { testStream(streamEvent.stream); };
+ });
+ });
+ });
+}, "Basic video exchange");
+ </script>
+ </body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (211252 => 211253)
--- trunk/Source/WebCore/ChangeLog 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/Source/WebCore/ChangeLog 2017-01-27 04:54:09 UTC (rev 211253)
@@ -1,3 +1,64 @@
+2017-01-26 Youenn Fablet <youe...@gmail.com>
+
+ [WebRTC] Add a LibWebRTC mock for testing
+ https://bugs.webkit.org/show_bug.cgi?id=167429
+
+ Reviewed by Alex Christensen.
+
+ Covered by updated tests although feature is behind a flag, off by default.
+ MockLibWebRTCPeerConnection will allow us testing the code above the WebRTC implementation above LibWebRTC,
+ without reyling on it and controlling the way that the peer connections will behave.
+ Adding support for mock factory to create real peer connections in case where we want to do full testing through the local loopback.
+
+ Tests: fast/mediastream/getUserMedia-webaudio.html
+ webrtc/datachannel/basic.html
+ webrtc/video.html
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * testing/Internals.cpp:
+ (WebCore::Internals::Internals):
+ (WebCore::Internals::useMockRTCPeerConnectionFactory):
+ * testing/Internals.h:
+ * testing/Internals.idl:
+ * testing/MockLibWebRTCPeerConnection.cpp: Added.
+ (WebCore::useMockRTCPeerConnectionFactory):
+ (WebCore::MockLibWebRTCPeerConnectionForIceCandidates::MockLibWebRTCPeerConnectionForIceCandidates):
+ (WebCore::MockLibWebRTCPeerConnectionForIceCandidates::gotLocalDescription):
+ (WebCore::MockLibWebRTCPeerConnectionForIceConnectionState::MockLibWebRTCPeerConnectionForIceConnectionState):
+ (WebCore::MockLibWebRTCPeerConnectionForIceConnectionState::gotLocalDescription):
+ (WebCore::MockLibWebRTCPeerConnectionFactory::MockLibWebRTCPeerConnectionFactory):
+ (WebCore::MockLibWebRTCPeerConnectionFactory::CreatePeerConnection):
+ (WebCore::MockLibWebRTCPeerConnectionFactory::CreateLocalMediaStream):
+ (WebCore::MockLibWebRTCPeerConnection::SetLocalDescription):
+ (WebCore::MockLibWebRTCPeerConnection::SetRemoteDescription):
+ (WebCore::MockLibWebRTCPeerConnection::CreateDataChannel):
+ (WebCore::MockLibWebRTCPeerConnection::AddStream):
+ (WebCore::MockLibWebRTCPeerConnection::RemoveStream):
+ (WebCore::MockLibWebRTCPeerConnection::CreateOffer):
+ (WebCore::MockLibWebRTCPeerConnection::CreateAnswer):
+ * testing/MockLibWebRTCPeerConnection.h: Added.
+ (WebCore::MockLibWebRTCPeerConnection::~MockLibWebRTCPeerConnection):
+ (WebCore::MockLibWebRTCPeerConnection::MockLibWebRTCPeerConnection):
+ (WebCore::MockLibWebRTCPeerConnection::local_streams):
+ (WebCore::MockLibWebRTCPeerConnection::remote_streams):
+ (WebCore::MockLibWebRTCPeerConnection::CreateDtmfSender):
+ (WebCore::MockLibWebRTCPeerConnection::GetStats):
+ (WebCore::MockLibWebRTCPeerConnection::local_description):
+ (WebCore::MockLibWebRTCPeerConnection::remote_description):
+ (WebCore::MockLibWebRTCPeerConnection::AddIceCandidate):
+ (WebCore::MockLibWebRTCPeerConnection::RegisterUMAObserver):
+ (WebCore::MockLibWebRTCPeerConnection::signaling_state):
+ (WebCore::MockLibWebRTCPeerConnection::ice_connection_state):
+ (WebCore::MockLibWebRTCPeerConnection::ice_gathering_state):
+ (WebCore::MockLibWebRTCPeerConnection::StopRtcEventLog):
+ (WebCore::MockLibWebRTCPeerConnection::Close):
+ (WebCore::MockLibWebRTCPeerConnection::gotLocalDescription):
+ (WebCore::MockLibWebRTCIceCandidate::MockLibWebRTCIceCandidate):
+ (WebCore::MockLibWebRTCAudioTrack::MockLibWebRTCAudioTrack):
+ (WebCore::MockLibWebRTCVideoTrack::MockLibWebRTCVideoTrack):
+ (WebCore::MockLibWebRTCDataChannel::MockLibWebRTCDataChannel):
+ (WebCore::MockLibWebRTCPeerConnectionFactory::create):
+
2017-01-26 Jeremy Jones <jere...@apple.com>
Page should be able to request pointer lock without user gesture if it relinquished it without a user gesture
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (211252 => 211253)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-01-27 04:54:09 UTC (rev 211253)
@@ -1544,6 +1544,8 @@
4157474A1E3869AD00E914D8 /* LibWebRTCUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 415747461E38699E00E914D8 /* LibWebRTCUtils.h */; settings = {ATTRIBUTES = (Private, ); }; };
4157AF8012F1FB0400A8C6F5 /* MediaControlsApple.h in Headers */ = {isa = PBXBuildFile; fileRef = 4157AF7E12F1FB0400A8C6F5 /* MediaControlsApple.h */; };
4157AF8112F1FB0400A8C6F5 /* MediaControlsApple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4157AF7F12F1FB0400A8C6F5 /* MediaControlsApple.cpp */; };
+ 4157EBFA1E3AB67900AC9FE9 /* MockLibWebRTCPeerConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4157EBF91E3AB06800AC9FE9 /* MockLibWebRTCPeerConnection.cpp */; };
+ 4157EBFB1E3AB67F00AC9FE9 /* MockLibWebRTCPeerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 4157EBF81E3AB06800AC9FE9 /* MockLibWebRTCPeerConnection.h */; };
41614A781DA6423B004AD06F /* HTTPHeaderValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41614A761DA64236004AD06F /* HTTPHeaderValues.cpp */; };
41614A791DA64241004AD06F /* HTTPHeaderValues.h in Headers */ = {isa = PBXBuildFile; fileRef = 41614A771DA64236004AD06F /* HTTPHeaderValues.h */; };
4162A450101145AE00DFF3ED /* DedicatedWorkerGlobalScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4162A44D101145AE00DFF3ED /* DedicatedWorkerGlobalScope.cpp */; };
@@ -8725,6 +8727,8 @@
415747461E38699E00E914D8 /* LibWebRTCUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCUtils.h; path = libwebrtc/LibWebRTCUtils.h; sourceTree = "<group>"; };
4157AF7E12F1FB0400A8C6F5 /* MediaControlsApple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaControlsApple.h; sourceTree = "<group>"; };
4157AF7F12F1FB0400A8C6F5 /* MediaControlsApple.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaControlsApple.cpp; sourceTree = "<group>"; };
+ 4157EBF81E3AB06800AC9FE9 /* MockLibWebRTCPeerConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockLibWebRTCPeerConnection.h; sourceTree = "<group>"; };
+ 4157EBF91E3AB06800AC9FE9 /* MockLibWebRTCPeerConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockLibWebRTCPeerConnection.cpp; sourceTree = "<group>"; };
41614A761DA64236004AD06F /* HTTPHeaderValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPHeaderValues.cpp; sourceTree = "<group>"; };
41614A771DA64236004AD06F /* HTTPHeaderValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPHeaderValues.h; sourceTree = "<group>"; };
4162A44D101145AE00DFF3ED /* DedicatedWorkerGlobalScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DedicatedWorkerGlobalScope.cpp; sourceTree = "<group>"; };
@@ -16693,6 +16697,8 @@
51058AD81D679257009A538C /* MockGamepad.h */,
51058AD91D679257009A538C /* MockGamepadProvider.cpp */,
51058ADA1D679257009A538C /* MockGamepadProvider.h */,
+ 4157EBF81E3AB06800AC9FE9 /* MockLibWebRTCPeerConnection.h */,
+ 4157EBF91E3AB06800AC9FE9 /* MockLibWebRTCPeerConnection.cpp */,
2D6F3E8A1C1ECB1C0061DBD4 /* MockPageOverlay.cpp */,
2D6F3E8B1C1ECB1C0061DBD4 /* MockPageOverlay.h */,
2D6F3E8C1C1ECB1C0061DBD4 /* MockPageOverlay.idl */,
@@ -24911,6 +24917,7 @@
AA5F3B8D16CC33D100455EB0 /* PlatformSpeechSynthesizerMock.h in Headers */,
A1763F3F1E205234001D58DE /* WebArchiveDumpSupport.h in Headers */,
41815C1F138319830057AAA4 /* WebCoreTestSupport.h in Headers */,
+ 4157EBFB1E3AB67F00AC9FE9 /* MockLibWebRTCPeerConnection.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -28834,6 +28841,7 @@
51714EB01CF665CE004723C4 /* JSGCObservation.cpp in Sources */,
417DA71D13735DFA007C57FB /* JSInternals.cpp in Sources */,
A740B5A714C935AF00A77FA4 /* JSInternalSettings.cpp in Sources */,
+ 4157EBFA1E3AB67900AC9FE9 /* MockLibWebRTCPeerConnection.cpp in Sources */,
53ED3FDE167A88E7006762E6 /* JSInternalSettingsGenerated.cpp in Sources */,
A740B59714C935AF00A77FA4 /* JSMallocStatistics.cpp in Sources */,
CDF4B7331E03D14900E235A2 /* JSMediaKeysRequirement.cpp in Sources */,
Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCUtils.cpp (211252 => 211253)
--- trunk/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCUtils.cpp 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCUtils.cpp 2017-01-27 04:54:09 UTC (rev 211253)
@@ -31,6 +31,7 @@
#if USE(LIBWEBRTC)
+#include <webrtc/api/peerconnectionfactoryproxy.h>
#include <webrtc/api/peerconnectionfactory.h>
#include <webrtc/base/physicalsocketserver.h>
#include <webrtc/p2p/client/basicportallocator.h>
@@ -74,6 +75,12 @@
threads.networkThread->Post(RTC_FROM_HERE, &threads, 1, new ThreadMessageData(WTFMove(callback)));
}
+void callOnWebRTCSignalingThread(Function<void()>&& callback)
+{
+ PeerConnectionFactoryAndThreads& threads = staticFactoryAndThreads();
+ threads.signalingThread->Post(RTC_FROM_HERE, &threads, 1, new ThreadMessageData(WTFMove(callback)));
+}
+
static void initializePeerConnectionFactoryAndThreads()
{
auto& factoryAndThreads = staticFactoryAndThreads();
@@ -106,6 +113,14 @@
return *staticFactoryAndThreads().factory;
}
+void setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&& factory)
+{
+ if (!staticFactoryAndThreads().factory)
+ initializePeerConnectionFactoryAndThreads();
+
+ staticFactoryAndThreads().factory = webrtc::PeerConnectionFactoryProxy::Create(staticFactoryAndThreads().signalingThread.get(), WTFMove(factory));
+}
+
static rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(webrtc::PeerConnectionObserver& observer, std::unique_ptr<cricket::BasicPortAllocator>&& portAllocator)
{
ASSERT(staticFactoryAndThreads().factory);
Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCUtils.h (211252 => 211253)
--- trunk/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCUtils.h 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCUtils.h 2017-01-27 04:54:09 UTC (rev 211253)
@@ -52,6 +52,10 @@
WEBCORE_EXPORT void callOnWebRTCNetworkThread(Function<void()>&&);
+// Used for mock testing
+WEBCORE_EXPORT void setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&&);
+WEBCORE_EXPORT void callOnWebRTCSignalingThread(Function<void()>&&);
+
} // namespace WebCore
#endif // USE(LIBWEBRTC)
Modified: trunk/Source/WebCore/testing/Internals.cpp (211252 => 211253)
--- trunk/Source/WebCore/testing/Internals.cpp 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/Source/WebCore/testing/Internals.cpp 2017-01-27 04:54:09 UTC (rev 211253)
@@ -85,6 +85,8 @@
#include "IntRect.h"
#include "InternalSettings.h"
#include "Language.h"
+#include "LibWebRTCProvider.h"
+#include "LibWebRTCUtils.h"
#include "MainFrame.h"
#include "MallocStatistics.h"
#include "MediaPlayer.h"
@@ -92,6 +94,7 @@
#include "MemoryCache.h"
#include "MemoryInfo.h"
#include "MemoryPressureHandler.h"
+#include "MockLibWebRTCPeerConnection.h"
#include "MockPageOverlay.h"
#include "MockPageOverlayClient.h"
#include "Page.h"
@@ -450,6 +453,7 @@
#if ENABLE(WEB_RTC)
enableMockMediaEndpoint();
+ useMockRTCPeerConnectionFactory(String());
#endif
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
@@ -1091,8 +1095,19 @@
connection.emulatePlatformEvent(action);
}
+void Internals::useMockRTCPeerConnectionFactory(const String& testCase)
+{
+#if USE(LIBWEBRTC)
+ Document* document = contextDocument();
+ LibWebRTCProvider* provider = (document && document->page()) ? &document->page()->libWebRTCProvider() : nullptr;
+ WebCore::useMockRTCPeerConnectionFactory(provider, testCase);
+#else
+ UNUSED_PARAM(testCase);
#endif
+}
+#endif
+
#if ENABLE(MEDIA_STREAM)
void Internals::setMockMediaCaptureDevicesEnabled(bool enabled)
Modified: trunk/Source/WebCore/testing/Internals.h (211252 => 211253)
--- trunk/Source/WebCore/testing/Internals.h 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/Source/WebCore/testing/Internals.h 2017-01-27 04:54:09 UTC (rev 211253)
@@ -390,6 +390,7 @@
void enableMockMediaEndpoint();
void enableMockRTCPeerConnectionHandler();
void emulateRTCPeerConnectionPlatformEvent(RTCPeerConnection&, const String& action);
+ void useMockRTCPeerConnectionFactory(const String&);
#endif
String getImageSourceURL(Element&);
Modified: trunk/Source/WebCore/testing/Internals.idl (211252 => 211253)
--- trunk/Source/WebCore/testing/Internals.idl 2017-01-27 04:29:16 UTC (rev 211252)
+++ trunk/Source/WebCore/testing/Internals.idl 2017-01-27 04:54:09 UTC (rev 211253)
@@ -435,6 +435,7 @@
[Conditional=WIRELESS_PLAYBACK_TARGET, MayThrowException] void setMockMediaPlaybackTargetPickerState(DOMString deviceName, DOMString deviceState);
[Conditional=MEDIA_STREAM] void setMockMediaCaptureDevicesEnabled(boolean enabled);
[Conditional=WEB_RTC] void emulateRTCPeerConnectionPlatformEvent(RTCPeerConnection connection, DOMString action);
+ [Conditional=WEB_RTC] void useMockRTCPeerConnectionFactory(DOMString testCase);
[Conditional=VIDEO] void simulateSystemSleep();
[Conditional=VIDEO] void simulateSystemWake();
Added: trunk/Source/WebCore/testing/MockLibWebRTCPeerConnection.cpp (0 => 211253)
--- trunk/Source/WebCore/testing/MockLibWebRTCPeerConnection.cpp (rev 0)
+++ trunk/Source/WebCore/testing/MockLibWebRTCPeerConnection.cpp 2017-01-27 04:54:09 UTC (rev 211253)
@@ -0,0 +1,324 @@
+/*
+ * 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 "MockLibWebRTCPeerConnection.h"
+
+#if USE(LIBWEBRTC)
+
+#include "LibWebRTCProvider.h"
+#include "LibWebRTCUtils.h"
+#include <sstream>
+#include <webrtc/api/mediastream.h>
+#include <wtf/Function.h>
+
+namespace WebCore {
+
+void useMockRTCPeerConnectionFactory(LibWebRTCProvider* provider, const String& testCase)
+{
+ setPeerConnectionFactory(MockLibWebRTCPeerConnectionFactory::create(provider, String(testCase)));
+}
+
+class MockLibWebRTCPeerConnectionForIceCandidates : public MockLibWebRTCPeerConnection {
+public:
+ explicit MockLibWebRTCPeerConnectionForIceCandidates(webrtc::PeerConnectionObserver& observer) : MockLibWebRTCPeerConnection(observer) { }
+ virtual ~MockLibWebRTCPeerConnectionForIceCandidates() = default;
+private:
+ void gotLocalDescription() final;
+};
+
+void MockLibWebRTCPeerConnectionForIceCandidates::gotLocalDescription()
+{
+ // Let's gather candidates
+ callOnWebRTCSignalingThread([this]() {
+ MockLibWebRTCIceCandidate candidate("2013266431 1 udp 2013266432 192.168.0.100 38838 typ host generation 0", "1");
+ m_observer.OnIceCandidate(&candidate);
+ });
+ callOnWebRTCSignalingThread([this]() {
+ MockLibWebRTCIceCandidate candidate("1019216383 1 tcp 1019216384 192.168.0.100 9 typ host tcptype passive generation 0", "1");
+ m_observer.OnIceCandidate(&candidate);
+ });
+ callOnWebRTCSignalingThread([this]() {
+ MockLibWebRTCIceCandidate candidate("1677722111 1 tcp 1677722112 172.18.0.1 47989 typ srflx raddr 192.168.0.100 rport 47989 generation 0", "1");
+ m_observer.OnIceCandidate(&candidate);
+ });
+ callOnWebRTCSignalingThread([this]() {
+ m_observer.OnIceGatheringChange(webrtc::PeerConnectionInterface::kIceGatheringComplete);
+ });
+}
+
+
+class MockLibWebRTCPeerConnectionForIceConnectionState : public MockLibWebRTCPeerConnection {
+public:
+ explicit MockLibWebRTCPeerConnectionForIceConnectionState(webrtc::PeerConnectionObserver& observer) : MockLibWebRTCPeerConnection(observer) { }
+ virtual ~MockLibWebRTCPeerConnectionForIceConnectionState() = default;
+
+private:
+ void gotLocalDescription() final;
+};
+
+void MockLibWebRTCPeerConnectionForIceConnectionState::gotLocalDescription()
+{
+ m_observer.OnIceConnectionChange(kIceConnectionChecking);
+ m_observer.OnIceConnectionChange(kIceConnectionConnected);
+ m_observer.OnIceConnectionChange(kIceConnectionCompleted);
+ m_observer.OnIceConnectionChange(kIceConnectionFailed);
+ m_observer.OnIceConnectionChange(kIceConnectionDisconnected);
+ m_observer.OnIceConnectionChange(kIceConnectionNew);
+}
+
+MockLibWebRTCPeerConnectionFactory::MockLibWebRTCPeerConnectionFactory(LibWebRTCProvider* provider, String&& testCase)
+ : m_provider(provider)
+ , m_testCase(WTFMove(testCase))
+{
+ if (m_testCase == "TwoRealPeerConnections" && m_provider)
+ m_numberOfRealPeerConnections = 2;
+}
+
+rtc::scoped_refptr<webrtc::PeerConnectionInterface> MockLibWebRTCPeerConnectionFactory::CreatePeerConnection(const webrtc::PeerConnectionInterface::RTCConfiguration&, std::unique_ptr<cricket::PortAllocator>, std::unique_ptr<rtc::RTCCertificateGeneratorInterface>, webrtc::PeerConnectionObserver* observer)
+{
+ if (m_numberOfRealPeerConnections) {
+ ASSERT(m_provider);
+ auto connection = m_provider->createPeerConnection(*observer);
+ if (!--m_numberOfRealPeerConnections)
+ m_provider = nullptr;
+ return connection;
+ }
+
+ if (m_testCase == "ICECandidates")
+ return new rtc::RefCountedObject<MockLibWebRTCPeerConnectionForIceCandidates>(*observer);
+
+ if (m_testCase == "ICEConnectionState")
+ return new rtc::RefCountedObject<MockLibWebRTCPeerConnectionForIceConnectionState>(*observer);
+
+ return new rtc::RefCountedObject<MockLibWebRTCPeerConnection>(*observer);
+}
+
+rtc::scoped_refptr<webrtc::MediaStreamInterface> MockLibWebRTCPeerConnectionFactory::CreateLocalMediaStream(const std::string& label)
+{
+ return new rtc::RefCountedObject<webrtc::MediaStream>(label);
+}
+
+void MockLibWebRTCPeerConnection::SetLocalDescription(webrtc::SetSessionDescriptionObserver* observer, webrtc::SessionDescriptionInterface*)
+{
+ callOnWebRTCSignalingThread([this, observer] {
+ observer->OnSuccess();
+ gotLocalDescription();
+ });
+}
+
+void MockLibWebRTCPeerConnection::SetRemoteDescription(webrtc::SetSessionDescriptionObserver* observer, webrtc::SessionDescriptionInterface* sessionDescription)
+{
+ callOnWebRTCSignalingThread([observer] {
+ observer->OnSuccess();
+ });
+ ASSERT(sessionDescription);
+ if (sessionDescription->type() == "offer") {
+ std::string sdp;
+ sessionDescription->ToString(&sdp);
+
+ m_isInitiator = false;
+ m_isReceivingAudio = sdp.find("m=audio") != std::string::npos;
+ m_isReceivingVideo = sdp.find("m=video") != std::string::npos;
+ }
+}
+
+rtc::scoped_refptr<webrtc::DataChannelInterface> MockLibWebRTCPeerConnection::CreateDataChannel(const std::string& label, const webrtc::DataChannelInit* init)
+{
+ webrtc::DataChannelInit parameters;
+ if (init)
+ parameters = *init;
+ return new rtc::RefCountedObject<MockLibWebRTCDataChannel>(std::string(label), parameters.ordered, parameters.reliable, parameters.id);
+}
+
+bool MockLibWebRTCPeerConnection::AddStream(webrtc::MediaStreamInterface* stream)
+{
+ m_stream = stream;
+ return true;
+}
+
+void MockLibWebRTCPeerConnection::RemoveStream(webrtc::MediaStreamInterface*)
+{
+ m_stream = nullptr;
+}
+
+void MockLibWebRTCPeerConnection::CreateOffer(webrtc::CreateSessionDescriptionObserver* observer, const webrtc::MediaConstraintsInterface*)
+{
+ callOnWebRTCSignalingThread([this, observer] {
+ std::ostringstream sdp;
+ sdp <<
+ "v=0\r\n"
+ "o=- 5667094644266930845 " << m_counter++ << " IN IP4 127.0.0.1\r\n"
+ "s=-\r\n"
+ "t=0 0\r\n";
+ if (m_stream) {
+ unsigned partCounter = 1;
+ sdp << "a=msid-semantic:WMS " << m_stream->label() << "\r\n";
+ for (auto& audioTrack : m_stream->GetAudioTracks()) {
+ sdp <<
+ "m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=sendrecv\r\n"
+ "a=mid:part" << partCounter++ << "\r\n"
+ "a=rtpmap:111 OPUS/48000/2\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=ssrc:3409173717 cname:/chKzCS9K6KOgL0n\r\n"
+ "a=msid:" << m_stream->label() << " " << audioTrack->id() << "\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:actpass\r\n";
+ }
+ for (auto& videoTrack : m_stream->GetVideoTracks()) {
+ sdp <<
+ "m=video 9 UDP/TLS/RTP/SAVPF 103 100 120\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=sendrecv\r\n"
+ "a=mid:part" << partCounter++ << "\r\n"
+ "a=rtpmap:103 H264/90000\r\n"
+ "a=rtpmap:100 VP8/90000\r\n"
+ "a=rtpmap:120 RTX/90000\r\n"
+ "a=fmtp:103 packetization-mode=1\r\n"
+ "a=fmtp:120 apt=100;rtx-time=200\r\n"
+ "a=rtcp-fb:100 nack\r\n"
+ "a=rtcp-fb:103 nack pli\r\n"
+ "a=rtcp-fb:100 nack pli\r\n"
+ "a=rtcp-fb:103 ccm fir\r\n"
+ "a=rtcp-fb:100 ccm fir\r\n"
+ "a=ssrc:3409173718 cname:/chKzCS9K6KOgL0n\r\n"
+ "a=msid:" << m_stream->label() << " " << videoTrack->id() << "\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:actpass\r\n";
+ }
+ }
+ MockLibWebRTCSessionDescription description(sdp.str());
+ observer->OnSuccess(&description);
+ });
+}
+
+void MockLibWebRTCPeerConnection::CreateAnswer(webrtc::CreateSessionDescriptionObserver* observer, const webrtc::MediaConstraintsInterface*)
+{
+ callOnWebRTCSignalingThread([this, observer] {
+ std::ostringstream sdp;
+ sdp <<
+ "v=0\r\n"
+ "o=- 5667094644266930846 " << m_counter++ << " IN IP4 127.0.0.1\r\n"
+ "s=-\r\n"
+ "t=0 0\r\n";
+ if (m_stream) {
+ for (auto& audioTrack : m_stream->GetAudioTracks()) {
+ ASSERT_UNUSED(audioTrack, !!audioTrack);
+ sdp <<
+ "m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=recvonly\r\n"
+ "a=mid:part1\r\n"
+ "a=rtpmap:111 OPUS/48000/2\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=ssrc:3409173717 cname:/chKzCS9K6KOgL0m\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:active\r\n";
+ }
+ for (auto& videoTrack : m_stream->GetVideoTracks()) {
+ ASSERT_UNUSED(videoTrack, !!videoTrack);
+ sdp <<
+ "m=video 9 UDP/TLS/RTP/SAVPF 103 100 120\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=recvonly\r\n"
+ "a=mid:part2\r\n"
+ "a=rtpmap:103 H264/90000\r\n"
+ "a=rtpmap:100 VP8/90000\r\n"
+ "a=rtpmap:120 RTX/90000\r\n"
+ "a=fmtp:103 packetization-mode=1\r\n"
+ "a=fmtp:120 apt=100;rtx-time=200\r\n"
+ "a=rtcp-fb:100 nack\r\n"
+ "a=rtcp-fb:103 nack pli\r\n"
+ "a=rtcp-fb:100 nack pli\r\n"
+ "a=rtcp-fb:103 ccm fir\r\n"
+ "a=rtcp-fb:100 ccm fir\r\n"
+ "a=ssrc:3409173718 cname:/chKzCS9K6KOgL0n\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:active\r\n";
+ }
+ } else if (!m_isInitiator) {
+ if (m_isReceivingAudio) {
+ sdp <<
+ "m=audio 9 UDP/TLS/RTP/SAVPF 111 8 0\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=recvonly\r\n"
+ "a=mid:part1\r\n"
+ "a=rtpmap:111 OPUS/48000/2\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=ssrc:3409173717 cname:/chKzCS9K6KOgL0m\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:active\r\n";
+ }
+ if (m_isReceivingVideo) {
+ sdp <<
+ "m=video 9 UDP/TLS/RTP/SAVPF 103 100 120\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=recvonly\r\n"
+ "a=mid:part2\r\n"
+ "a=rtpmap:103 H264/90000\r\n"
+ "a=rtpmap:100 VP8/90000\r\n"
+ "a=rtpmap:120 RTX/90000\r\n"
+ "a=fmtp:103 packetization-mode=1\r\n"
+ "a=fmtp:120 apt=100;rtx-time=200\r\n"
+ "a=rtcp-fb:100 nack\r\n"
+ "a=rtcp-fb:103 nack pli\r\n"
+ "a=rtcp-fb:100 nack pli\r\n"
+ "a=rtcp-fb:103 ccm fir\r\n"
+ "a=rtcp-fb:100 ccm fir\r\n"
+ "a=ssrc:3409173718 cname:/chKzCS9K6KOgL0n\r\n"
+ "a=ice-ufrag:e/B1\r\n"
+ "a=ice-pwd:Yotk3Im3mnyi+1Q38p51MDub\r\n"
+ "a=fingerprint:sha-256 8B:87:09:8A:5D:C2:F3:33:EF:C5:B1:F6:84:3A:3D:D6:A3:E2:9C:17:4C:E7:46:3B:1B:CE:84:98:DD:8E:AF:7B\r\n"
+ "a=setup:active\r\n";
+ }
+ }
+ MockLibWebRTCSessionDescription description(sdp.str());
+ observer->OnSuccess(&description);
+ });
+}
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
Added: trunk/Source/WebCore/testing/MockLibWebRTCPeerConnection.h (0 => 211253)
--- trunk/Source/WebCore/testing/MockLibWebRTCPeerConnection.h (rev 0)
+++ trunk/Source/WebCore/testing/MockLibWebRTCPeerConnection.h 2017-01-27 04:54:09 UTC (rev 211253)
@@ -0,0 +1,229 @@
+/*
+ * 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 "LibWebRTCMacros.h"
+#include <webrtc/api/mediastreaminterface.h>
+#include <webrtc/api/peerconnectioninterface.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class LibWebRTCProvider;
+
+void useMockRTCPeerConnectionFactory(LibWebRTCProvider*, const String&);
+
+class MockLibWebRTCPeerConnection : public webrtc::PeerConnectionInterface {
+public:
+ virtual ~MockLibWebRTCPeerConnection() { }
+
+protected:
+ explicit MockLibWebRTCPeerConnection(webrtc::PeerConnectionObserver& observer) : m_observer(observer) { }
+
+private:
+ rtc::scoped_refptr<webrtc::StreamCollectionInterface> local_streams() { return nullptr; }
+ rtc::scoped_refptr<webrtc::StreamCollectionInterface> remote_streams() { return nullptr; }
+ rtc::scoped_refptr<webrtc::DtmfSenderInterface> CreateDtmfSender(webrtc::AudioTrackInterface*) { return nullptr; }
+ bool GetStats(webrtc::StatsObserver*, webrtc::MediaStreamTrackInterface*, StatsOutputLevel) { return false; }
+ const webrtc::SessionDescriptionInterface* local_description() const { return nullptr; }
+ const webrtc::SessionDescriptionInterface* remote_description() const { return nullptr; }
+ bool AddIceCandidate(const webrtc::IceCandidateInterface*) { return true; }
+ void RegisterUMAObserver(webrtc::UMAObserver*) { }
+ SignalingState signaling_state() { return kStable; }
+ IceConnectionState ice_connection_state() { return kIceConnectionNew; }
+ IceGatheringState ice_gathering_state() { return kIceGatheringNew; }
+ void StopRtcEventLog() { }
+ void Close() { }
+
+protected:
+ void SetLocalDescription(webrtc::SetSessionDescriptionObserver*, webrtc::SessionDescriptionInterface*) final;
+ void SetRemoteDescription(webrtc::SetSessionDescriptionObserver*, webrtc::SessionDescriptionInterface*) final;
+ void CreateOffer(webrtc::CreateSessionDescriptionObserver*, const webrtc::MediaConstraintsInterface*) final;
+ void CreateAnswer(webrtc::CreateSessionDescriptionObserver*, const webrtc::MediaConstraintsInterface*) final;
+ rtc::scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(const std::string&, const webrtc::DataChannelInit*) final;
+ bool AddStream(webrtc::MediaStreamInterface*) final;
+ void RemoveStream(webrtc::MediaStreamInterface*) final;
+
+ virtual void gotLocalDescription() { }
+
+ webrtc::PeerConnectionObserver& m_observer;
+ unsigned m_counter { 0 };
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> m_stream;
+ bool m_isInitiator { true };
+ bool m_isReceivingAudio { false };
+ bool m_isReceivingVideo { false };
+};
+
+class MockLibWebRTCSessionDescription: public webrtc::SessionDescriptionInterface {
+public:
+ explicit MockLibWebRTCSessionDescription(std::string&& sdp) : m_sdp(WTFMove(sdp)) { }
+
+private:
+ bool ToString(std::string* out) const final { *out = m_sdp; return true; }
+
+ cricket::SessionDescription* description() final { return nullptr; }
+ const cricket::SessionDescription* description() const final { return nullptr; }
+ std::string session_id() const final { return ""; }
+ std::string session_version() const final { return ""; }
+ std::string type() const final { return ""; }
+ bool AddCandidate(const webrtc::IceCandidateInterface*) final { return true; }
+ size_t number_of_mediasections() const final { return 0; }
+ const webrtc::IceCandidateCollection* candidates(size_t) const final { return nullptr; }
+
+ std::string m_sdp;
+};
+
+class MockLibWebRTCIceCandidate : public webrtc::IceCandidateInterface {
+public:
+ MockLibWebRTCIceCandidate(const char* sdp, const char* sdpMid)
+ : m_sdp(sdp)
+ , m_sdpMid(sdpMid) { }
+
+private:
+ std::string sdp_mid() const final { return m_sdpMid; }
+ int sdp_mline_index() const final { return 0; }
+ const cricket::Candidate& candidate() const final { return m_candidate; }
+ bool ToString(std::string* out) const final { *out = m_sdp; return true; }
+
+protected:
+ const char* m_sdp;
+ const char* m_sdpMid;
+ cricket::Candidate m_candidate;
+};
+
+class MockLibWebRTCAudioTrack : public webrtc::AudioTrackInterface {
+public:
+ explicit MockLibWebRTCAudioTrack(const std::string& id, webrtc::AudioSourceInterface* source)
+ : m_id(id)
+ , m_source(source) { }
+
+private:
+ webrtc::AudioSourceInterface* GetSource() const final { return m_source; }
+ void AddSink(webrtc::AudioTrackSinkInterface*) final { }
+ void RemoveSink(webrtc::AudioTrackSinkInterface*) final { }
+ void RegisterObserver(webrtc::ObserverInterface*) final { }
+ void UnregisterObserver(webrtc::ObserverInterface*) final { }
+
+ std::string kind() const final { return "audio"; }
+ std::string id() const final { return m_id; }
+ bool enabled() const final { return m_enabled; }
+ TrackState state() const final { return kLive; }
+ bool set_enabled(bool enabled) final { m_enabled = enabled; return true; }
+
+ bool m_enabled;
+ std::string m_id;
+ webrtc::AudioSourceInterface* m_source { nullptr };
+};
+
+class MockLibWebRTCVideoTrack : public webrtc::VideoTrackInterface {
+public:
+ explicit MockLibWebRTCVideoTrack(const std::string& id, webrtc::VideoTrackSourceInterface* source)
+ : m_id(id)
+ , m_source(source) { }
+
+private:
+ webrtc::VideoTrackSourceInterface* GetSource() const final { return m_source; }
+ void RegisterObserver(webrtc::ObserverInterface*) final { }
+ void UnregisterObserver(webrtc::ObserverInterface*) final { }
+
+ std::string kind() const final { return "video"; }
+ std::string id() const final { return m_id; }
+ bool enabled() const final { return m_enabled; }
+ TrackState state() const final { return kLive; }
+ bool set_enabled(bool enabled) final { m_enabled = enabled; return true; }
+
+ bool m_enabled;
+ std::string m_id;
+ webrtc::VideoTrackSourceInterface* m_source { nullptr };
+};
+
+class MockLibWebRTCDataChannel : public webrtc::DataChannelInterface {
+public:
+ MockLibWebRTCDataChannel(std::string&& label, bool ordered, bool reliable, int id)
+ : m_label(WTFMove(label))
+ , m_ordered(ordered)
+ , m_reliable(reliable)
+ , m_id(id) { }
+
+private:
+ void RegisterObserver(webrtc::DataChannelObserver*) final { }
+ void UnregisterObserver() final { }
+ std::string label() const final { return m_label; }
+ bool reliable() const final { return m_reliable; }
+ bool ordered() const final { return m_ordered; }
+
+ int id() const final { return m_id; }
+ DataState state() const final { return kConnecting; }
+ uint64_t buffered_amount() const final { return 0; }
+ void Close() final { }
+ bool Send(const webrtc::DataBuffer&) final { return true; }
+
+ std::string m_label;
+ bool m_ordered { true };
+ bool m_reliable { false };
+ int m_id { -1 };
+};
+
+class MockLibWebRTCPeerConnectionFactory : public webrtc::PeerConnectionFactoryInterface {
+public:
+ static rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> create(LibWebRTCProvider* provider, String&& testCase) { return new rtc::RefCountedObject<MockLibWebRTCPeerConnectionFactory>(provider, WTFMove(testCase)); }
+
+protected:
+ MockLibWebRTCPeerConnectionFactory(LibWebRTCProvider*, String&&);
+
+private:
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(const webrtc::PeerConnectionInterface::RTCConfiguration&, const webrtc::MediaConstraintsInterface*, std::unique_ptr<cricket::PortAllocator>, std::unique_ptr<rtc::RTCCertificateGeneratorInterface>, webrtc::PeerConnectionObserver*) final { return nullptr; }
+
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(const webrtc::PeerConnectionInterface::RTCConfiguration&, std::unique_ptr<cricket::PortAllocator>, std::unique_ptr<rtc::RTCCertificateGeneratorInterface>, webrtc::PeerConnectionObserver*) final;
+
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> CreateLocalMediaStream(const std::string&) final;
+
+ void SetOptions(const Options&) final { }
+ rtc::scoped_refptr<webrtc::AudioSourceInterface> CreateAudioSource(const cricket::AudioOptions&) final { return nullptr; }
+ rtc::scoped_refptr<webrtc::AudioSourceInterface> CreateAudioSource(const webrtc::MediaConstraintsInterface*) final { return nullptr; }
+
+ rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> CreateVideoSource(cricket::VideoCapturer*) final { return nullptr; }
+ rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> CreateVideoSource(cricket::VideoCapturer*, const webrtc::MediaConstraintsInterface*) final { return nullptr; }
+
+ rtc::scoped_refptr<webrtc::VideoTrackInterface> CreateVideoTrack(const std::string& id, webrtc::VideoTrackSourceInterface* source) final { return new rtc::RefCountedObject<MockLibWebRTCVideoTrack>(id, source); }
+ rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateAudioTrack(const std::string& id, webrtc::AudioSourceInterface* source) final { return new rtc::RefCountedObject<MockLibWebRTCAudioTrack>(id, source); }
+ bool StartAecDump(rtc::PlatformFile, int64_t) final { return false; }
+ void StopAecDump() final { }
+
+ bool StartRtcEventLog(rtc::PlatformFile, int64_t) final { return false; }
+ bool StartRtcEventLog(rtc::PlatformFile) final { return false; }
+ void StopRtcEventLog() final { }
+
+private:
+ LibWebRTCProvider* m_provider { nullptr };
+ String m_testCase;
+ unsigned m_numberOfRealPeerConnections { 0 };
+};
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)