Make mock libwebrtc tests run with unified plan
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Aug 2019 17:12:52 +0000 (17:12 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Aug 2019 17:12:52 +0000 (17:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200713

Reviewed by Alex Christensen.

Source/ThirdParty/libwebrtc:

* Configurations/libwebrtc.iOS.exp:
* Configurations/libwebrtc.iOSsim.exp:
* Configurations/libwebrtc.mac.exp:

Source/WebCore:

Update mock endpoint to pass mock webrtc tests with unified plan.
This requires implementing support for mock transceivers.
Covered by existing tests.

* testing/Internals.cpp:
(WebCore::Internals::useMockRTCPeerConnectionFactory):
Update assert to mandate unified plan.
* testing/MockLibWebRTCPeerConnection.cpp:
(WebCore::MockLibWebRTCPeerConnection::~MockLibWebRTCPeerConnection):
(WebCore::MockLibWebRTCPeerConnection::GetTransceivers const):
(WebCore::MockLibWebRTCPeerConnection::AddTrack):
(WebCore::MockLibWebRTCPeerConnection::RemoveTrack):
(WebCore::MockLibWebRTCPeerConnection::CreateOffer):
(WebCore::MockLibWebRTCPeerConnection::CreateAnswer):
* testing/MockLibWebRTCPeerConnection.h:
(WebCore::MockRtpSender::MockRtpSender):
(WebCore::MockRtpReceiver::id const):
(WebCore::MockRtpReceiver::GetParameters const):
(WebCore::MockRtpReceiver::SetParameters):
(WebCore::MockRtpReceiver::SetObserver):
(WebCore::MockRtpTransceiver::MockRtpTransceiver):
(WebCore::MockLibWebRTCPeerConnection::MockLibWebRTCPeerConnection):
(WebCore::MockLibWebRTCPeerConnection::gotLocalDescription):

LayoutTests:

Enable unified plan.

* fast/mediastream/RTCPeerConnection-icecandidate-event.html:
* fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html:
* fast/mediastream/RTCPeerConnection-inspect-answer.html:
* fast/mediastream/RTCPeerConnection-inspect-offer.html:
* fast/mediastream/RTCPeerConnection-media-setup-single-dialog.html:
* fast/mediastream/RTCPeerConnection-remotely-assigned-transceiver-mid.html:
* fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html:
* fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html:
* webrtc/libwebrtc/release-while-creating-offer.html:
* webrtc/libwebrtc/release-while-getting-stats.html:
* webrtc/libwebrtc/release-while-setting-local-description.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248718 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/mediastream/RTCPeerConnection-icecandidate-event.html
LayoutTests/fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html
LayoutTests/fast/mediastream/RTCPeerConnection-inspect-answer.html
LayoutTests/fast/mediastream/RTCPeerConnection-inspect-offer.html
LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-single-dialog.html
LayoutTests/fast/mediastream/RTCPeerConnection-remotely-assigned-transceiver-mid.html
LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html
LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html
LayoutTests/webrtc/libwebrtc/release-while-creating-offer.html
LayoutTests/webrtc/libwebrtc/release-while-getting-stats.html
LayoutTests/webrtc/libwebrtc/release-while-setting-local-description.html
Source/ThirdParty/libwebrtc/ChangeLog
Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp
Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp
Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp
Source/WebCore/ChangeLog
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/MockLibWebRTCPeerConnection.cpp
Source/WebCore/testing/MockLibWebRTCPeerConnection.h

index 6a6dc19..5bf35c6 100644 (file)
@@ -1,3 +1,24 @@
+2019-08-15  Youenn Fablet  <youenn@apple.com>
+
+        Make mock libwebrtc tests run with unified plan
+        https://bugs.webkit.org/show_bug.cgi?id=200713
+
+        Reviewed by Alex Christensen.
+
+        Enable unified plan.
+
+        * fast/mediastream/RTCPeerConnection-icecandidate-event.html:
+        * fast/mediastream/RTCPeerConnection-iceconnectionstatechange-event.html:
+        * fast/mediastream/RTCPeerConnection-inspect-answer.html:
+        * fast/mediastream/RTCPeerConnection-inspect-offer.html:
+        * fast/mediastream/RTCPeerConnection-media-setup-single-dialog.html:
+        * fast/mediastream/RTCPeerConnection-remotely-assigned-transceiver-mid.html:
+        * fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html:
+        * fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html:
+        * webrtc/libwebrtc/release-while-creating-offer.html:
+        * webrtc/libwebrtc/release-while-getting-stats.html:
+        * webrtc/libwebrtc/release-while-setting-local-description.html:
+
 2019-08-14  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [WHLSL] Variables shouldn't be able to have void type
index 44e2d3c..48488d5 100644 (file)
@@ -8,9 +8,6 @@
         <script>
             description("Test RTCPeerConnection 'icecandidate' event and gathering done");
 
-            if (window.testRunner)
-                testRunner.setWebRTCUnifiedPlanEnabled(false);
-
             if (window.internals)
                 internals.useMockRTCPeerConnectionFactory("ICECandidates");
 
index ccc2b92..4db0564 100644 (file)
@@ -7,8 +7,6 @@
     <body>
         <script>
             description("Test RTCPeerConnection 'iceconnectionstatechange' event");
-            if (window.testRunner)
-                testRunner.setWebRTCUnifiedPlanEnabled(false);
 
             if (window.internals)
                 internals.useMockRTCPeerConnectionFactory("ICEConnectionState");
index ae13428..04dd6e3 100644 (file)
@@ -6,9 +6,6 @@
     </head>
     <body>
         <script>
-            if (window.testRunner)
-                testRunner.setWebRTCUnifiedPlanEnabled(false);
-
             if (window.internals)
                 internals.useMockRTCPeerConnectionFactory("");
 
index 8e63638..9c3c20c 100644 (file)
@@ -6,9 +6,6 @@
     </head>
     <body>
         <script>
-            if (window.testRunner)
-                testRunner.setWebRTCUnifiedPlanEnabled(false);
-
             if (window.internals)
                 internals.useMockRTCPeerConnectionFactory("");
 
index e829328..4821e46 100644 (file)
@@ -6,9 +6,6 @@
     </head>
     <body>
         <script>
-            if (window.testRunner)
-                testRunner.setWebRTCUnifiedPlanEnabled(false);
-
             if (window.internals)
                 internals.useMockRTCPeerConnectionFactory("");
 
index 0e3b5fd..973e139 100644 (file)
@@ -6,9 +6,6 @@
     </head>
     <body>
         <script>
-            if (window.testRunner)
-                testRunner.setWebRTCUnifiedPlanEnabled(false);
-
             if (window.internals)
                 internals.useMockRTCPeerConnectionFactory("");
 
index cbd516f..229e4b5 100644 (file)
@@ -6,9 +6,6 @@
     </head>
     <body>
         <script>
-            if (window.testRunner)
-                testRunner.setWebRTCUnifiedPlanEnabled(false);
-
             if (window.internals)
                 internals.useMockRTCPeerConnectionFactory("");
 
index 8118301..cac37f0 100644 (file)
@@ -6,9 +6,6 @@
     </head>
     <body>
         <script>
-            if (window.testRunner)
-                testRunner.setWebRTCUnifiedPlanEnabled(false);
-
             if (window.internals)
                 internals.useMockRTCPeerConnectionFactory("");
 
index 518aef7..cc7bed9 100644 (file)
@@ -7,9 +7,6 @@
 <script>
 self.jsTestIsAsync = true;
 
-if (window.testRunner)
-    testRunner.setWebRTCUnifiedPlanEnabled(false);
-
 if (window.internals)
     internals.useMockRTCPeerConnectionFactory("LibWebRTCReleasingWhileCreatingOffer");
 
index 3f120da..a94449e 100644 (file)
@@ -7,9 +7,6 @@
 <script>
 self.jsTestIsAsync = true;
 
-if (window.testRunner)
-    testRunner.setWebRTCUnifiedPlanEnabled(false);
-
 if (window.internals)
     internals.useMockRTCPeerConnectionFactory("LibWebRTCReleasingWhileGettingStats");
 
index fa9c653..62e899e 100644 (file)
@@ -10,9 +10,6 @@ self.jsTestIsAsync = true;
 // Silence unhandled rejection messages.
 window.onunhandledrejection = () => false;
 
-if (window.testRunner)
-    testRunner.setWebRTCUnifiedPlanEnabled(false);
-
 if (window.internals)
     internals.useMockRTCPeerConnectionFactory("LibWebRTCReleasingWhileSettingDescription");
 
index 0814144..085a3f2 100644 (file)
@@ -1,3 +1,14 @@
+2019-08-15  Youenn Fablet  <youenn@apple.com>
+
+        Make mock libwebrtc tests run with unified plan
+        https://bugs.webkit.org/show_bug.cgi?id=200713
+
+        Reviewed by Alex Christensen.
+
+        * Configurations/libwebrtc.iOS.exp:
+        * Configurations/libwebrtc.iOSsim.exp:
+        * Configurations/libwebrtc.mac.exp:
+
 2019-08-14  Keith Rollin  <krollin@apple.com>
 
         Remove support for macOS < 10.13
index 9205296..c0ad1fe 100644 (file)
@@ -253,3 +253,12 @@ __ZN3rtc11CryptStringC1ERKNS_15CryptStringImplE
 __ZN3rtc13SocketAddressC1ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEi
 __ZN3rtc11CryptStringD1Ev
 __ZN3rtc11CryptStringC1ERKS0_
+__ZN6webrtc20RtpReceiverInterface17SetFrameDecryptorEN3rtc13scoped_refptrINS_23FrameDecryptorInterfaceEEE
+__ZN6webrtc23RtpTransceiverInterface19SetCodecPreferencesEN3rtc9ArrayViewINS_18RtpCodecCapabilityELln4711EEE
+__ZNK6webrtc20RtpReceiverInterface10GetSourcesEv
+__ZNK6webrtc20RtpReceiverInterface10stream_idsEv
+__ZNK6webrtc20RtpReceiverInterface17GetFrameDecryptorEv
+__ZNK6webrtc20RtpReceiverInterface7streamsEv
+__ZNK6webrtc23RtpTransceiverInterface15fired_directionEv
+__ZTVN6webrtc20RtpReceiverInterfaceE
+__ZTVN6webrtc23RtpTransceiverInterfaceE
index 6f132cb..4ca6f49 100644 (file)
@@ -254,3 +254,12 @@ __ZN3rtc11CryptStringC1ERKNS_15CryptStringImplE
 __ZN3rtc13SocketAddressC1ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEi
 __ZN3rtc11CryptStringD1Ev
 __ZN3rtc11CryptStringC1ERKS0_
+__ZN6webrtc20RtpReceiverInterface17SetFrameDecryptorEN3rtc13scoped_refptrINS_23FrameDecryptorInterfaceEEE
+__ZN6webrtc23RtpTransceiverInterface19SetCodecPreferencesEN3rtc9ArrayViewINS_18RtpCodecCapabilityELln4711EEE
+__ZNK6webrtc20RtpReceiverInterface10GetSourcesEv
+__ZNK6webrtc20RtpReceiverInterface10stream_idsEv
+__ZNK6webrtc20RtpReceiverInterface17GetFrameDecryptorEv
+__ZNK6webrtc20RtpReceiverInterface7streamsEv
+__ZNK6webrtc23RtpTransceiverInterface15fired_directionEv
+__ZTVN6webrtc20RtpReceiverInterfaceE
+__ZTVN6webrtc23RtpTransceiverInterfaceE
index 6f132cb..4ca6f49 100644 (file)
@@ -254,3 +254,12 @@ __ZN3rtc11CryptStringC1ERKNS_15CryptStringImplE
 __ZN3rtc13SocketAddressC1ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEi
 __ZN3rtc11CryptStringD1Ev
 __ZN3rtc11CryptStringC1ERKS0_
+__ZN6webrtc20RtpReceiverInterface17SetFrameDecryptorEN3rtc13scoped_refptrINS_23FrameDecryptorInterfaceEEE
+__ZN6webrtc23RtpTransceiverInterface19SetCodecPreferencesEN3rtc9ArrayViewINS_18RtpCodecCapabilityELln4711EEE
+__ZNK6webrtc20RtpReceiverInterface10GetSourcesEv
+__ZNK6webrtc20RtpReceiverInterface10stream_idsEv
+__ZNK6webrtc20RtpReceiverInterface17GetFrameDecryptorEv
+__ZNK6webrtc20RtpReceiverInterface7streamsEv
+__ZNK6webrtc23RtpTransceiverInterface15fired_directionEv
+__ZTVN6webrtc20RtpReceiverInterfaceE
+__ZTVN6webrtc23RtpTransceiverInterfaceE
index f24a909..37c9e06 100644 (file)
@@ -1,3 +1,34 @@
+2019-08-15  Youenn Fablet  <youenn@apple.com>
+
+        Make mock libwebrtc tests run with unified plan
+        https://bugs.webkit.org/show_bug.cgi?id=200713
+
+        Reviewed by Alex Christensen.
+
+        Update mock endpoint to pass mock webrtc tests with unified plan.
+        This requires implementing support for mock transceivers.
+        Covered by existing tests.
+
+        * testing/Internals.cpp:
+        (WebCore::Internals::useMockRTCPeerConnectionFactory):
+        Update assert to mandate unified plan.
+        * testing/MockLibWebRTCPeerConnection.cpp:
+        (WebCore::MockLibWebRTCPeerConnection::~MockLibWebRTCPeerConnection):
+        (WebCore::MockLibWebRTCPeerConnection::GetTransceivers const):
+        (WebCore::MockLibWebRTCPeerConnection::AddTrack):
+        (WebCore::MockLibWebRTCPeerConnection::RemoveTrack):
+        (WebCore::MockLibWebRTCPeerConnection::CreateOffer):
+        (WebCore::MockLibWebRTCPeerConnection::CreateAnswer):
+        * testing/MockLibWebRTCPeerConnection.h:
+        (WebCore::MockRtpSender::MockRtpSender):
+        (WebCore::MockRtpReceiver::id const):
+        (WebCore::MockRtpReceiver::GetParameters const):
+        (WebCore::MockRtpReceiver::SetParameters):
+        (WebCore::MockRtpReceiver::SetObserver):
+        (WebCore::MockRtpTransceiver::MockRtpTransceiver):
+        (WebCore::MockLibWebRTCPeerConnection::MockLibWebRTCPeerConnection):
+        (WebCore::MockLibWebRTCPeerConnection::gotLocalDescription):
+
 2019-08-15  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed WinCairo build fix after r248713.
index e178b49..2466bfe 100644 (file)
@@ -1434,9 +1434,7 @@ void Internals::emulateRTCPeerConnectionPlatformEvent(RTCPeerConnection& connect
 
 void Internals::useMockRTCPeerConnectionFactory(const String& testCase)
 {
-    // FIXME: We should upgrade mocks to support unified plan APIs, until then use plan B in tests using mock.
-
-    ASSERT(!RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled());
+    ASSERT(RuntimeEnabledFeatures::sharedFeatures().webRTCUnifiedPlanEnabled());
     if (!LibWebRTCProvider::webRTCAvailable())
         return;
 
index c0c0cbf..8346c23 100644 (file)
@@ -71,8 +71,16 @@ void useMockRTCPeerConnectionFactory(LibWebRTCProvider* provider, const String&
 
 MockLibWebRTCPeerConnection::~MockLibWebRTCPeerConnection()
 {
-    // Free senders in a different thread like an actual peer connection would probably do.
-    Thread::create("MockLibWebRTCPeerConnection thread", [senders = WTFMove(m_senders)] { });
+    // Free senders and receivers in a different thread like an actual peer connection would probably do.
+    Thread::create("MockLibWebRTCPeerConnection thread", [transceivers = WTFMove(m_transceivers)] { });
+}
+
+std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> MockLibWebRTCPeerConnection::GetTransceivers() const
+{
+    std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> transceivers;
+    for (auto transceiver : m_transceivers)
+        transceivers.push_back(transceiver);
+    return transceivers;
 }
 
 class MockLibWebRTCPeerConnectionForIceCandidates : public MockLibWebRTCPeerConnection {
@@ -254,8 +262,12 @@ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> MockLibWebRTC
     if (!streamIds.empty())
         m_streamLabel = streamIds.front();
 
-    m_senders.append(new rtc::RefCountedObject<MockRtpSender>(WTFMove(track)));
-    return rtc::scoped_refptr<webrtc::RtpSenderInterface>(m_senders.last().get());
+    rtc::scoped_refptr<webrtc::RtpSenderInterface> sender = new rtc::RefCountedObject<MockRtpSender>(WTFMove(track));
+    rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver = new rtc::RefCountedObject<MockRtpReceiver>();
+    rtc::scoped_refptr<MockRtpTransceiver> transceiver = new rtc::RefCountedObject<MockRtpTransceiver>(WTFMove(sender), WTFMove(receiver));
+
+    m_transceivers.append(WTFMove(transceiver));
+    return rtc::scoped_refptr<webrtc::RtpSenderInterface>(m_transceivers.last()->sender());
 }
 
 bool MockLibWebRTCPeerConnection::RemoveTrack(webrtc::RtpSenderInterface* sender)
@@ -264,8 +276,8 @@ bool MockLibWebRTCPeerConnection::RemoveTrack(webrtc::RtpSenderInterface* sender
         observer->OnRenegotiationNeeded();
     });
     bool isRemoved = false;
-    return m_senders.removeFirstMatching([&](auto& item) {
-        if (item.get() != sender)
+    return m_transceivers.removeFirstMatching([&](auto& transceiver) {
+        if (transceiver->sender().get() != sender)
             return false;
         isRemoved = true;
         return true;
@@ -281,11 +293,11 @@ void MockLibWebRTCPeerConnection::CreateOffer(webrtc::CreateSessionDescriptionOb
             "o=- 5667094644266930845 " << m_counter++ << " IN IP4 127.0.0.1\r\n"
             "s=-\r\n"
             "t=0 0\r\n";
-        if (m_senders.size()) {
+        if (m_transceivers.size()) {
             unsigned partCounter = 1;
             sdp << "a=msid-semantic:WMS " << m_streamLabel << "\r\n";
-            for (auto& sender : m_senders) {
-                auto track = sender->track();
+            for (auto& transceiver : m_transceivers) {
+                auto track = transceiver->sender()->track();
                 if (track->kind() != "audio")
                     continue;
                 sdp <<
@@ -304,8 +316,8 @@ void MockLibWebRTCPeerConnection::CreateOffer(webrtc::CreateSessionDescriptionOb
                     "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& sender : m_senders) {
-                auto track = sender->track();
+            for (auto& transceiver : m_transceivers) {
+                auto track = transceiver->sender()->track();
                 if (track->kind() != "video")
                     continue;
                 sdp <<
@@ -345,9 +357,9 @@ void MockLibWebRTCPeerConnection::CreateOffer(webrtc::CreateSessionDescriptionOb
             "o=- 5667094644266930846 " << m_counter++ << " IN IP4 127.0.0.1\r\n"
             "s=-\r\n"
             "t=0 0\r\n";
-        if (m_senders.size()) {
-            for (auto& sender : m_senders) {
-                auto track = sender->track();
+        if (m_transceivers.size()) {
+            for (auto& transceiver : m_transceivers) {
+                auto track = transceiver->sender()->track();
                 if (track->kind() != "audio")
                     continue;
                 sdp <<
@@ -365,8 +377,8 @@ void MockLibWebRTCPeerConnection::CreateOffer(webrtc::CreateSessionDescriptionOb
                     "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& sender : m_senders) {
-                auto track = sender->track();
+            for (auto& transceiver : m_transceivers) {
+                auto track = transceiver->sender()->track();
                 if (track->kind() != "video")
                     continue;
                 sdp <<
index 2de663f..313a54b 100644 (file)
@@ -45,52 +45,6 @@ class MockRtpSender;
 void useMockRTCPeerConnectionFactory(LibWebRTCProvider*, const String&);
 void useRealRTCPeerConnectionFactory(LibWebRTCProvider&);
 
-class MockLibWebRTCPeerConnection : public webrtc::PeerConnectionInterface {
-public:
-    ~MockLibWebRTCPeerConnection();
-
-protected:
-    explicit MockLibWebRTCPeerConnection(webrtc::PeerConnectionObserver& observer) : m_observer(observer) { }
-
-private:
-    rtc::scoped_refptr<webrtc::StreamCollectionInterface> local_streams() override { return nullptr; }
-    rtc::scoped_refptr<webrtc::StreamCollectionInterface> remote_streams() override { return nullptr; }
-    const webrtc::SessionDescriptionInterface* local_description() const override { return nullptr; }
-    const webrtc::SessionDescriptionInterface* remote_description() const override { return nullptr; }
-    bool AddIceCandidate(const webrtc::IceCandidateInterface*) override { return true; }
-    SignalingState signaling_state() override { return kStable; }
-    IceConnectionState ice_connection_state() override { return kIceConnectionNew; }
-    IceGatheringState ice_gathering_state() override { return kIceGatheringNew; }
-    void StopRtcEventLog() override { }
-    void Close() override { }
-
-    bool AddStream(webrtc::MediaStreamInterface*) final { return false; }
-    void RemoveStream(webrtc::MediaStreamInterface*) final { }
-
-protected:
-    void SetRemoteDescription(webrtc::SetSessionDescriptionObserver*, webrtc::SessionDescriptionInterface*) final;
-    void CreateAnswer(webrtc::CreateSessionDescriptionObserver*, const webrtc::PeerConnectionInterface::RTCOfferAnswerOptions&) final;
-    rtc::scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(const std::string&, const webrtc::DataChannelInit*) final;
-    webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> AddTrack(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>, const std::vector<std::string>& streams) final;
-    bool RemoveTrack(webrtc::RtpSenderInterface*) final;
-    webrtc::RTCError SetBitrate(const BitrateParameters&) final { return { }; }
-
-
-    void SetLocalDescription(webrtc::SetSessionDescriptionObserver*, webrtc::SessionDescriptionInterface*) override;
-    bool GetStats(webrtc::StatsObserver*, webrtc::MediaStreamTrackInterface*, StatsOutputLevel) override { return false; }
-    void CreateOffer(webrtc::CreateSessionDescriptionObserver*, const webrtc::PeerConnectionInterface::RTCOfferAnswerOptions&) override;
-
-    virtual void gotLocalDescription() { }
-
-    webrtc::PeerConnectionObserver& m_observer;
-    unsigned m_counter { 0 };
-    Vector<rtc::scoped_refptr<MockRtpSender>> m_senders;
-    bool m_isInitiator { true };
-    bool m_isReceivingAudio { false };
-    bool m_isReceivingVideo { false };
-    std::string m_streamLabel;
-};
-
 class MockLibWebRTCSessionDescription: public webrtc::SessionDescriptionInterface {
 public:
     explicit MockLibWebRTCSessionDescription(std::string&& sdp) : m_sdp(WTFMove(sdp)) { }
@@ -213,7 +167,9 @@ private:
 
 class MockRtpSender : public webrtc::RtpSenderInterface {
 public:
-    MockRtpSender(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>&& track) : m_track(WTFMove(track)) { }
+    explicit MockRtpSender(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>&& track) : m_track(WTFMove(track)) { }
+
+private:
     bool SetTrack(webrtc::MediaStreamTrackInterface* track) final
     {
         m_track = track;
@@ -232,7 +188,89 @@ public:
 private:
     rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> m_track;
 };
-    
+
+class MockRtpReceiver : public webrtc::RtpReceiverInterface {
+private:
+    cricket::MediaType media_type() const final { return cricket::MEDIA_TYPE_VIDEO; }
+    std::string id() const { return { }; }
+    webrtc::RtpParameters GetParameters() const { return { }; }
+    bool SetParameters(const webrtc::RtpParameters&) { return true; }
+    void SetObserver(webrtc::RtpReceiverObserverInterface*) { }
+    rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track() const final { return { }; }
+};
+
+class MockRtpTransceiver : public webrtc::RtpTransceiverInterface {
+public:
+    MockRtpTransceiver(rtc::scoped_refptr<webrtc::RtpSenderInterface>&& sender, rtc::scoped_refptr<webrtc::RtpReceiverInterface>&& receiver)
+        : m_sender(WTFMove(sender))
+        , m_receiver(WTFMove(receiver))
+    {
+    }
+
+    rtc::scoped_refptr<webrtc::RtpSenderInterface> sender() const final { return m_sender; }
+
+private:
+    cricket::MediaType media_type() const final { return m_sender->media_type(); }
+    absl::optional<std::string> mid() const final { return { }; }
+    rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver() const final { return m_receiver; }
+    bool stopped() const final { return false; }
+    webrtc::RtpTransceiverDirection direction() const final { return webrtc::RtpTransceiverDirection::kSendRecv; }
+    void SetDirection(webrtc::RtpTransceiverDirection) final { }
+    absl::optional<webrtc::RtpTransceiverDirection> current_direction() const final { return { }; }
+    void Stop() final { }
+
+private:
+    rtc::scoped_refptr<webrtc::RtpSenderInterface> m_sender;
+    rtc::scoped_refptr<webrtc::RtpReceiverInterface> m_receiver;
+};
+
+class MockLibWebRTCPeerConnection : public webrtc::PeerConnectionInterface {
+public:
+    ~MockLibWebRTCPeerConnection();
+
+protected:
+    explicit MockLibWebRTCPeerConnection(webrtc::PeerConnectionObserver& observer) : m_observer(observer) { }
+
+private:
+    rtc::scoped_refptr<webrtc::StreamCollectionInterface> local_streams() override { return nullptr; }
+    rtc::scoped_refptr<webrtc::StreamCollectionInterface> remote_streams() override { return nullptr; }
+    const webrtc::SessionDescriptionInterface* local_description() const override { return nullptr; }
+    const webrtc::SessionDescriptionInterface* remote_description() const override { return nullptr; }
+    bool AddIceCandidate(const webrtc::IceCandidateInterface*) override { return true; }
+    SignalingState signaling_state() override { return kStable; }
+    IceConnectionState ice_connection_state() override { return kIceConnectionNew; }
+    IceGatheringState ice_gathering_state() override { return kIceGatheringNew; }
+    void StopRtcEventLog() override { }
+    void Close() override { }
+
+    bool AddStream(webrtc::MediaStreamInterface*) final { return false; }
+    void RemoveStream(webrtc::MediaStreamInterface*) final { }
+
+    std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> GetTransceivers() const final;
+
+protected:
+    void SetRemoteDescription(webrtc::SetSessionDescriptionObserver*, webrtc::SessionDescriptionInterface*) final;
+    void CreateAnswer(webrtc::CreateSessionDescriptionObserver*, const webrtc::PeerConnectionInterface::RTCOfferAnswerOptions&) final;
+    rtc::scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(const std::string&, const webrtc::DataChannelInit*) final;
+    webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> AddTrack(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>, const std::vector<std::string>& streams) final;
+    bool RemoveTrack(webrtc::RtpSenderInterface*) final;
+    webrtc::RTCError SetBitrate(const BitrateParameters&) final { return { }; }
+
+    void SetLocalDescription(webrtc::SetSessionDescriptionObserver*, webrtc::SessionDescriptionInterface*) override;
+    bool GetStats(webrtc::StatsObserver*, webrtc::MediaStreamTrackInterface*, StatsOutputLevel) override { return false; }
+    void CreateOffer(webrtc::CreateSessionDescriptionObserver*, const webrtc::PeerConnectionInterface::RTCOfferAnswerOptions&) override;
+
+    virtual void gotLocalDescription() { }
+
+    webrtc::PeerConnectionObserver& m_observer;
+    unsigned m_counter { 0 };
+    Vector<rtc::scoped_refptr<MockRtpTransceiver>> m_transceivers;
+    bool m_isInitiator { true };
+    bool m_isReceivingAudio { false };
+    bool m_isReceivingVideo { false };
+    std::string m_streamLabel;
+};
+
 class MockLibWebRTCPeerConnectionFactory : public webrtc::PeerConnectionFactoryInterface {
 public:
     static rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> create(const String& testCase) { return new rtc::RefCountedObject<MockLibWebRTCPeerConnectionFactory>(testCase); }