Title: [211253] trunk
Revision
211253
Author
commit-qu...@webkit.org
Date
2017-01-26 20:54:09 -0800 (Thu, 26 Jan 2017)

Log Message

[WebRTC] Add a LibWebRTC mock for testing
https://bugs.webkit.org/show_bug.cgi?id=167429

Patch by Youenn Fablet <youe...@gmail.com> on 2017-01-26
Reviewed by Alex Christensen.

Source/WebCore:

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):

LayoutTests:

* 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.

Modified Paths

Added Paths

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)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to