blob: bf2d77078fec1b56311abf5c38c135e8694074be [file] [log] [blame]
deadbeef1dcb1642017-03-29 21:08:16 -07001/*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Harald Alvestrandf8f7b702022-05-05 13:21:19 +000011// Integration tests for PeerConnection.
12// These tests exercise a full stack over a simulated network.
13//
14// NOTE: If your test takes a while (guideline: more than 5 seconds),
15// do NOT add it here, but instead add it to the file
16// slow_peer_connection_integrationtest.cc
17
Harald Alvestrand39993842021-02-17 09:05:31 +000018#include <stdint.h>
deadbeef1dcb1642017-03-29 21:08:16 -070019
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -070020#include <algorithm>
deadbeef1dcb1642017-03-29 21:08:16 -070021#include <memory>
Harald Alvestrand39993842021-02-17 09:05:31 +000022#include <string>
23#include <tuple>
deadbeef1dcb1642017-03-29 21:08:16 -070024#include <utility>
25#include <vector>
26
Steve Anton64b626b2019-01-28 17:25:26 -080027#include "absl/algorithm/container.h"
Philipp Hanckea09b9212022-06-22 07:41:22 +020028#include "absl/memory/memory.h"
Harald Alvestrandf8f7b702022-05-05 13:21:19 +000029#include "absl/strings/string_view.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000030#include "absl/types/optional.h"
31#include "api/async_resolver_factory.h"
32#include "api/candidate.h"
33#include "api/crypto/crypto_options.h"
34#include "api/dtmf_sender_interface.h"
35#include "api/ice_transport_interface.h"
36#include "api/jsep.h"
Steve Anton10542f22019-01-11 09:11:00 -080037#include "api/media_stream_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000038#include "api/media_types.h"
Steve Anton10542f22019-01-11 09:11:00 -080039#include "api/peer_connection_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000040#include "api/rtc_error.h"
41#include "api/rtc_event_log/rtc_event.h"
42#include "api/rtc_event_log/rtc_event_log.h"
43#include "api/rtc_event_log_output.h"
44#include "api/rtp_parameters.h"
Steve Anton10542f22019-01-11 09:11:00 -080045#include "api/rtp_receiver_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000046#include "api/rtp_sender_interface.h"
47#include "api/rtp_transceiver_direction.h"
48#include "api/rtp_transceiver_interface.h"
49#include "api/scoped_refptr.h"
50#include "api/stats/rtc_stats.h"
51#include "api/stats/rtc_stats_report.h"
52#include "api/stats/rtcstats_objects.h"
Jonas Oreland65455162022-06-08 11:25:46 +020053#include "api/test/mock_encoder_selector.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000054#include "api/transport/rtp/rtp_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080055#include "api/uma_metrics.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000056#include "api/units/time_delta.h"
57#include "api/video/video_rotation.h"
58#include "logging/rtc_event_log/fake_rtc_event_log.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070059#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000060#include "media/base/codec.h"
61#include "media/base/media_constants.h"
62#include "media/base/stream_params.h"
Steve Anton10542f22019-01-11 09:11:00 -080063#include "p2p/base/mock_async_resolver.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000064#include "p2p/base/port.h"
65#include "p2p/base/port_allocator.h"
Steve Anton10542f22019-01-11 09:11:00 -080066#include "p2p/base/port_interface.h"
67#include "p2p/base/test_stun_server.h"
68#include "p2p/base/test_turn_customizer.h"
69#include "p2p/base/test_turn_server.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000070#include "p2p/base/transport_description.h"
71#include "p2p/base/transport_info.h"
Steve Anton10542f22019-01-11 09:11:00 -080072#include "pc/media_session.h"
73#include "pc/peer_connection.h"
74#include "pc/peer_connection_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080075#include "pc/session_description.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000076#include "pc/test/fake_periodic_video_source.h"
77#include "pc/test/integration_test_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080078#include "pc/test/mock_peer_connection_observers.h"
Jonas Olssonb75d9e92019-02-22 10:33:29 +010079#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070080#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080081#include "rtc_base/fake_network.h"
82#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020083#include "rtc_base/gunit.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000084#include "rtc_base/helpers.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000085#include "rtc_base/logging.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000086#include "rtc_base/socket_address.h"
87#include "rtc_base/ssl_certificate.h"
88#include "rtc_base/ssl_fingerprint.h"
89#include "rtc_base/ssl_identity.h"
90#include "rtc_base/ssl_stream_adapter.h"
Danil Chapovalov2aaef452022-08-12 15:55:11 +020091#include "rtc_base/task_queue_for_test.h"
Steve Anton10542f22019-01-11 09:11:00 -080092#include "rtc_base/test_certificate_verifier.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000093#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080094#include "rtc_base/time_utils.h"
95#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020096#include "system_wrappers/include/metrics.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000097#include "test/gmock.h"
98#include "test/gtest.h"
deadbeef1dcb1642017-03-29 21:08:16 -070099
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +0100100namespace webrtc {
Harald Alvestrand39993842021-02-17 09:05:31 +0000101
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +0100102namespace {
103
Seth Hampson2f0d7022018-02-20 11:54:42 -0800104class PeerConnectionIntegrationTest
105 : public PeerConnectionIntegrationBaseTest,
Evan Shrubsole7619b7c2022-03-01 10:42:44 +0100106 public ::testing::WithParamInterface<
107 std::tuple<SdpSemantics, std::string>> {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800108 protected:
109 PeerConnectionIntegrationTest()
Evan Shrubsole7619b7c2022-03-01 10:42:44 +0100110 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam()),
111 std::get<1>(GetParam())) {}
Seth Hampson2f0d7022018-02-20 11:54:42 -0800112};
113
Yves Gerey100fe632020-01-17 19:15:53 +0100114// Fake clock must be set before threads are started to prevent race on
115// Set/GetClockForTesting().
116// To achieve that, multiple inheritance is used as a mixin pattern
117// where order of construction is finely controlled.
118// This also ensures peerconnection is closed before switching back to non-fake
119// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
120class FakeClockForTest : public rtc::ScopedFakeClock {
121 protected:
122 FakeClockForTest() {
123 // Some things use a time of "0" as a special value, so we need to start out
124 // the fake clock at a nonzero time.
125 // TODO(deadbeef): Fix this.
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100126 AdvanceTime(webrtc::TimeDelta::Seconds(1));
Yves Gerey100fe632020-01-17 19:15:53 +0100127 }
128
129 // Explicit handle.
130 ScopedFakeClock& FakeClock() { return *this; }
131};
132
133// Ensure FakeClockForTest is constructed first (see class for rationale).
134class PeerConnectionIntegrationTestWithFakeClock
135 : public FakeClockForTest,
136 public PeerConnectionIntegrationTest {};
137
Seth Hampson2f0d7022018-02-20 11:54:42 -0800138class PeerConnectionIntegrationTestPlanB
139 : public PeerConnectionIntegrationBaseTest {
140 protected:
141 PeerConnectionIntegrationTestPlanB()
Florent Castelli15a38de2022-04-06 00:38:21 +0200142 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
Seth Hampson2f0d7022018-02-20 11:54:42 -0800143};
144
145class PeerConnectionIntegrationTestUnifiedPlan
146 : public PeerConnectionIntegrationBaseTest {
147 protected:
148 PeerConnectionIntegrationTestUnifiedPlan()
149 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
150};
151
deadbeef1dcb1642017-03-29 21:08:16 -0700152// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
153// includes testing that the callback is invoked if an observer is connected
154// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800155TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700156 RtpReceiverObserverOnFirstPacketReceived) {
157 ASSERT_TRUE(CreatePeerConnectionWrappers());
158 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800159 caller()->AddAudioVideoTracks();
160 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700161 // Start offer/answer exchange and wait for it to complete.
162 caller()->CreateAndSetAndSignalOffer();
163 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
164 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200165 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
166 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700167 // Wait for all "first packet received" callbacks to be fired.
168 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800169 absl::c_all_of(caller()->rtp_receiver_observers(),
170 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
171 return o->first_packet_received();
172 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700173 kMaxWaitForFramesMs);
174 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800175 absl::c_all_of(callee()->rtp_receiver_observers(),
176 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
177 return o->first_packet_received();
178 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700179 kMaxWaitForFramesMs);
180 // If new observers are set after the first packet was already received, the
181 // callback should still be invoked.
182 caller()->ResetRtpReceiverObservers();
183 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200184 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
185 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700186 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800187 absl::c_all_of(caller()->rtp_receiver_observers(),
188 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
189 return o->first_packet_received();
190 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700191 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800192 absl::c_all_of(callee()->rtp_receiver_observers(),
193 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
194 return o->first_packet_received();
195 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700196}
197
198class DummyDtmfObserver : public DtmfSenderObserverInterface {
199 public:
200 DummyDtmfObserver() : completed_(false) {}
201
202 // Implements DtmfSenderObserverInterface.
203 void OnToneChange(const std::string& tone) override {
204 tones_.push_back(tone);
205 if (tone.empty()) {
206 completed_ = true;
207 }
208 }
209
210 const std::vector<std::string>& tones() const { return tones_; }
211 bool completed() const { return completed_; }
212
213 private:
214 bool completed_;
215 std::vector<std::string> tones_;
216};
217
Artem Titov880fa812021-07-30 22:30:23 +0200218// Assumes `sender` already has an audio track added and the offer/answer
deadbeef1dcb1642017-03-29 21:08:16 -0700219// exchange is done.
Harald Alvestrand39993842021-02-17 09:05:31 +0000220void TestDtmfFromSenderToReceiver(PeerConnectionIntegrationWrapper* sender,
221 PeerConnectionIntegrationWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -0800222 // We should be able to get a DTMF sender from the local sender.
223 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
224 sender->pc()->GetSenders().at(0)->GetDtmfSender();
225 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -0700226 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -0700227 dtmf_sender->RegisterObserver(&observer);
228
229 // Test the DtmfSender object just created.
230 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
231 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
232
233 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
234 std::vector<std::string> tones = {"1", "a", ""};
235 EXPECT_EQ(tones, observer.tones());
236 dtmf_sender->UnregisterObserver();
237 // TODO(deadbeef): Verify the tones were actually received end-to-end.
238}
239
240// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
241// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800242TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -0700243 ASSERT_TRUE(CreatePeerConnectionWrappers());
244 ConnectFakeSignaling();
245 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -0800246 caller()->AddAudioTrack();
247 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700248 caller()->CreateAndSetAndSignalOffer();
249 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -0700250 // DTLS must finish before the DTMF sender can be used reliably.
251 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -0700252 TestDtmfFromSenderToReceiver(caller(), callee());
253 TestDtmfFromSenderToReceiver(callee(), caller());
254}
255
256// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
257// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800258TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -0700259 ASSERT_TRUE(CreatePeerConnectionWrappers());
260 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +0100261
deadbeef1dcb1642017-03-29 21:08:16 -0700262 // Do normal offer/answer and wait for some frames to be received in each
263 // direction.
Steve Anton15324772018-01-16 10:26:49 -0800264 caller()->AddAudioVideoTracks();
265 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700266 caller()->CreateAndSetAndSignalOffer();
267 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800268 MediaExpectations media_expectations;
269 media_expectations.ExpectBidirectionalAudioAndVideo();
270 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700271}
272
Harald Alvestrandca327932022-04-04 15:37:31 +0000273#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06 +0000274// Uses SDES instead of DTLS for key agreement.
275TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
276 PeerConnectionInterface::RTCConfiguration sdes_config;
277 sdes_config.enable_dtls_srtp.emplace(false);
278 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
279 ConnectFakeSignaling();
280
281 // Do normal offer/answer and wait for some frames to be received in each
282 // direction.
283 caller()->AddAudioVideoTracks();
284 callee()->AddAudioVideoTracks();
285 caller()->CreateAndSetAndSignalOffer();
286 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
287 MediaExpectations media_expectations;
288 media_expectations.ExpectBidirectionalAudioAndVideo();
289 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Harald Alvestrand50b95522021-11-18 10:01:06 +0000290}
Harald Alvestrandca327932022-04-04 15:37:31 +0000291#endif
Harald Alvestrand50b95522021-11-18 10:01:06 +0000292
Artem Titov880fa812021-07-30 22:30:23 +0200293// Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions`
Steve Anton9a44b2d2019-07-12 12:58:30 -0700294// option to offer encrypted versions of all header extensions alongside the
295// unencrypted versions.
296TEST_P(PeerConnectionIntegrationTest,
297 EndToEndCallWithEncryptedRtpHeaderExtensions) {
298 CryptoOptions crypto_options;
299 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
300 PeerConnectionInterface::RTCConfiguration config;
301 config.crypto_options = crypto_options;
302 // Note: This allows offering >14 RTP header extensions.
303 config.offer_extmap_allow_mixed = true;
304 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
305 ConnectFakeSignaling();
306
307 // Do normal offer/answer and wait for some frames to be received in each
308 // direction.
309 caller()->AddAudioVideoTracks();
310 callee()->AddAudioVideoTracks();
311 caller()->CreateAndSetAndSignalOffer();
312 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
313 MediaExpectations media_expectations;
314 media_expectations.ExpectBidirectionalAudioAndVideo();
315 ASSERT_TRUE(ExpectNewFrames(media_expectations));
316}
317
deadbeef1dcb1642017-03-29 21:08:16 -0700318// This test sets up a call between two parties with a source resolution of
319// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800320TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700321 Send1280By720ResolutionAndReceive16To9AspectRatio) {
322 ASSERT_TRUE(CreatePeerConnectionWrappers());
323 ConnectFakeSignaling();
324
Niels Möller5c7efe72018-05-11 10:34:46 +0200325 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
326 webrtc::FakePeriodicVideoSource::Config config;
327 config.width = 1280;
328 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +0200329 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200330 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
331 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -0700332
333 // Do normal offer/answer and wait for at least one frame to be received in
334 // each direction.
335 caller()->CreateAndSetAndSignalOffer();
336 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
337 callee()->min_video_frames_received_per_track() > 0,
338 kMaxWaitForFramesMs);
339
340 // Check rendered aspect ratio.
341 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
342 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
343 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
344 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
345}
346
347// This test sets up an one-way call, with media only from caller to
348// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800349TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -0700350 ASSERT_TRUE(CreatePeerConnectionWrappers());
351 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800352 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700353 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800354 MediaExpectations media_expectations;
355 media_expectations.CalleeExpectsSomeAudioAndVideo();
356 media_expectations.CallerExpectsNoAudio();
357 media_expectations.CallerExpectsNoVideo();
358 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700359}
360
Johannes Kron3e983682020-03-29 22:17:00 +0200361// Tests that send only works without the caller having a decoder factory and
362// the callee having an encoder factory.
363TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
364 ASSERT_TRUE(
365 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
366 ConnectFakeSignaling();
367 // Add one-directional video, from caller to callee.
368 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
369 caller()->CreateLocalVideoTrack();
370 caller()->AddTrack(caller_track);
371 PeerConnectionInterface::RTCOfferAnswerOptions options;
372 options.offer_to_receive_video = 0;
373 caller()->SetOfferAnswerOptions(options);
374 caller()->CreateAndSetAndSignalOffer();
375 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
376 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
377
378 // Expect video to be received in one direction.
379 MediaExpectations media_expectations;
380 media_expectations.CallerExpectsNoVideo();
381 media_expectations.CalleeExpectsSomeVideo();
382
383 EXPECT_TRUE(ExpectNewFrames(media_expectations));
384}
385
386// Tests that receive only works without the caller having an encoder factory
387// and the callee having a decoder factory.
388TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
389 ASSERT_TRUE(
390 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
391 ConnectFakeSignaling();
392 // Add one-directional video, from callee to caller.
393 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
394 callee()->CreateLocalVideoTrack();
395 callee()->AddTrack(callee_track);
396 PeerConnectionInterface::RTCOfferAnswerOptions options;
397 options.offer_to_receive_video = 1;
398 caller()->SetOfferAnswerOptions(options);
399 caller()->CreateAndSetAndSignalOffer();
400 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
401 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
402
403 // Expect video to be received in one direction.
404 MediaExpectations media_expectations;
405 media_expectations.CallerExpectsSomeVideo();
406 media_expectations.CalleeExpectsNoVideo();
407
408 EXPECT_TRUE(ExpectNewFrames(media_expectations));
409}
410
411TEST_P(PeerConnectionIntegrationTest,
412 EndToEndCallAddReceiveVideoToSendOnlyCall) {
413 ASSERT_TRUE(CreatePeerConnectionWrappers());
414 ConnectFakeSignaling();
415 // Add one-directional video, from caller to callee.
416 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
417 caller()->CreateLocalVideoTrack();
418 caller()->AddTrack(caller_track);
419 caller()->CreateAndSetAndSignalOffer();
420 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
421
422 // Add receive video.
423 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
424 callee()->CreateLocalVideoTrack();
425 callee()->AddTrack(callee_track);
426 caller()->CreateAndSetAndSignalOffer();
427 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
428
429 // Ensure that video frames are received end-to-end.
430 MediaExpectations media_expectations;
431 media_expectations.ExpectBidirectionalVideo();
432 ASSERT_TRUE(ExpectNewFrames(media_expectations));
433}
434
435TEST_P(PeerConnectionIntegrationTest,
436 EndToEndCallAddSendVideoToReceiveOnlyCall) {
437 ASSERT_TRUE(CreatePeerConnectionWrappers());
438 ConnectFakeSignaling();
439 // Add one-directional video, from callee to caller.
440 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
441 callee()->CreateLocalVideoTrack();
442 callee()->AddTrack(callee_track);
443 caller()->CreateAndSetAndSignalOffer();
444 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
445
446 // Add send video.
447 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
448 caller()->CreateLocalVideoTrack();
449 caller()->AddTrack(caller_track);
450 caller()->CreateAndSetAndSignalOffer();
451 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
452
453 // Expect video to be received in one direction.
454 MediaExpectations media_expectations;
455 media_expectations.ExpectBidirectionalVideo();
456 ASSERT_TRUE(ExpectNewFrames(media_expectations));
457}
458
459TEST_P(PeerConnectionIntegrationTest,
460 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
461 ASSERT_TRUE(CreatePeerConnectionWrappers());
462 ConnectFakeSignaling();
463 // Add send video, from caller to callee.
464 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
465 caller()->CreateLocalVideoTrack();
466 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
467 caller()->AddTrack(caller_track);
468 // Add receive video, from callee to caller.
469 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
470 callee()->CreateLocalVideoTrack();
471
472 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
473 callee()->AddTrack(callee_track);
474 caller()->CreateAndSetAndSignalOffer();
475 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
476
477 // Remove receive video (i.e., callee sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000478 callee()->pc()->RemoveTrackOrError(callee_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200479
480 caller()->CreateAndSetAndSignalOffer();
481 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
482
483 // Expect one-directional video.
484 MediaExpectations media_expectations;
485 media_expectations.CallerExpectsNoVideo();
486 media_expectations.CalleeExpectsSomeVideo();
487
488 ASSERT_TRUE(ExpectNewFrames(media_expectations));
489}
490
491TEST_P(PeerConnectionIntegrationTest,
492 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
493 ASSERT_TRUE(CreatePeerConnectionWrappers());
494 ConnectFakeSignaling();
495 // Add send video, from caller to callee.
496 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
497 caller()->CreateLocalVideoTrack();
498 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
499 caller()->AddTrack(caller_track);
500 // Add receive video, from callee to caller.
501 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
502 callee()->CreateLocalVideoTrack();
503
504 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
505 callee()->AddTrack(callee_track);
506 caller()->CreateAndSetAndSignalOffer();
507 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
508
509 // Remove send video (i.e., caller sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000510 caller()->pc()->RemoveTrackOrError(caller_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200511
512 caller()->CreateAndSetAndSignalOffer();
513 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
514
515 // Expect one-directional video.
516 MediaExpectations media_expectations;
517 media_expectations.CalleeExpectsNoVideo();
518 media_expectations.CallerExpectsSomeVideo();
519
520 ASSERT_TRUE(ExpectNewFrames(media_expectations));
521}
522
deadbeef1dcb1642017-03-29 21:08:16 -0700523// This test sets up a audio call initially, with the callee rejecting video
524// initially. Then later the callee decides to upgrade to audio/video, and
525// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800526TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -0700527 ASSERT_TRUE(CreatePeerConnectionWrappers());
528 ConnectFakeSignaling();
529 // Initially, offer an audio/video stream from the caller, but refuse to
530 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -0800531 caller()->AddAudioVideoTracks();
532 callee()->AddAudioTrack();
Florent Castelli15a38de2022-04-06 00:38:21 +0200533 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800534 PeerConnectionInterface::RTCOfferAnswerOptions options;
535 options.offer_to_receive_video = 0;
536 callee()->SetOfferAnswerOptions(options);
537 } else {
538 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200539 callee()
540 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
541 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800542 });
543 }
deadbeef1dcb1642017-03-29 21:08:16 -0700544 // Do offer/answer and make sure audio is still received end-to-end.
545 caller()->CreateAndSetAndSignalOffer();
546 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800547 {
548 MediaExpectations media_expectations;
549 media_expectations.ExpectBidirectionalAudio();
550 media_expectations.ExpectNoVideo();
551 ASSERT_TRUE(ExpectNewFrames(media_expectations));
552 }
deadbeef1dcb1642017-03-29 21:08:16 -0700553 // Sanity check that the callee's description has a rejected video section.
554 ASSERT_NE(nullptr, callee()->pc()->local_description());
555 const ContentInfo* callee_video_content =
556 GetFirstVideoContent(callee()->pc()->local_description()->description());
557 ASSERT_NE(nullptr, callee_video_content);
558 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800559
deadbeef1dcb1642017-03-29 21:08:16 -0700560 // Now negotiate with video and ensure negotiation succeeds, with video
561 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -0800562 callee()->AddVideoTrack();
Florent Castelli15a38de2022-04-06 00:38:21 +0200563 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800564 PeerConnectionInterface::RTCOfferAnswerOptions options;
565 options.offer_to_receive_video = 1;
566 callee()->SetOfferAnswerOptions(options);
567 } else {
568 callee()->SetRemoteOfferHandler(nullptr);
569 caller()->SetRemoteOfferHandler([this] {
570 // The caller creates a new transceiver to receive video on when receiving
571 // the offer, but by default it is send only.
572 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200573 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800574 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +0200575 transceivers[1]->receiver()->media_type());
Niels Möllerafb246b2022-04-20 14:26:50 +0200576 transceivers[1]->sender()->SetTrack(
577 caller()->CreateLocalVideoTrack().get());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200578 transceivers[1]->SetDirectionWithError(
579 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800580 });
581 }
deadbeef1dcb1642017-03-29 21:08:16 -0700582 callee()->CreateAndSetAndSignalOffer();
583 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800584 {
585 // Expect additional audio frames to be received after the upgrade.
586 MediaExpectations media_expectations;
587 media_expectations.ExpectBidirectionalAudioAndVideo();
588 ASSERT_TRUE(ExpectNewFrames(media_expectations));
589 }
deadbeef1dcb1642017-03-29 21:08:16 -0700590}
591
deadbeef4389b4d2017-09-07 09:07:36 -0700592// Simpler than the above test; just add an audio track to an established
593// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800594TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -0700595 ASSERT_TRUE(CreatePeerConnectionWrappers());
596 ConnectFakeSignaling();
597 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -0800598 caller()->AddVideoTrack();
599 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700600 caller()->CreateAndSetAndSignalOffer();
601 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
602 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -0800603 caller()->AddAudioTrack();
604 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700605 caller()->CreateAndSetAndSignalOffer();
606 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
607 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800608 MediaExpectations media_expectations;
609 media_expectations.ExpectBidirectionalAudioAndVideo();
610 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -0700611}
612
deadbeef1dcb1642017-03-29 21:08:16 -0700613// This test sets up a non-bundled call and negotiates bundling at the same
614// time as starting an ICE restart. When bundling is in effect in the restart,
615// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800616TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -0700617 ASSERT_TRUE(CreatePeerConnectionWrappers());
618 ConnectFakeSignaling();
619
Steve Anton15324772018-01-16 10:26:49 -0800620 caller()->AddAudioVideoTracks();
621 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700622 // Remove the bundle group from the SDP received by the callee.
623 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
624 desc->RemoveGroupByName("BUNDLE");
625 });
626 caller()->CreateAndSetAndSignalOffer();
627 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800628 {
629 MediaExpectations media_expectations;
630 media_expectations.ExpectBidirectionalAudioAndVideo();
631 ASSERT_TRUE(ExpectNewFrames(media_expectations));
632 }
deadbeef1dcb1642017-03-29 21:08:16 -0700633 // Now stop removing the BUNDLE group, and trigger an ICE restart.
634 callee()->SetReceivedSdpMunger(nullptr);
635 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
636 caller()->CreateAndSetAndSignalOffer();
637 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
638
639 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800640 {
641 MediaExpectations media_expectations;
642 media_expectations.ExpectBidirectionalAudioAndVideo();
643 ASSERT_TRUE(ExpectNewFrames(media_expectations));
644 }
deadbeef1dcb1642017-03-29 21:08:16 -0700645}
646
647// Test CVO (Coordination of Video Orientation). If a video source is rotated
648// and both peers support the CVO RTP header extension, the actual video frames
649// don't need to be encoded in different resolutions, since the rotation is
650// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800651TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700652 ASSERT_TRUE(CreatePeerConnectionWrappers());
653 ConnectFakeSignaling();
654 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800655 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700656 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800657 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700658 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
659
660 // Wait for video frames to be received by both sides.
661 caller()->CreateAndSetAndSignalOffer();
662 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
663 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
664 callee()->min_video_frames_received_per_track() > 0,
665 kMaxWaitForFramesMs);
666
667 // Ensure that the aspect ratio is unmodified.
668 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
669 // not just assumed.
670 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
671 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
672 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
673 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
674 // Ensure that the CVO bits were surfaced to the renderer.
675 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
676 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
677}
678
679// Test that when the CVO extension isn't supported, video is rotated the
680// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800681TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700682 ASSERT_TRUE(CreatePeerConnectionWrappers());
683 ConnectFakeSignaling();
684 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800685 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700686 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800687 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700688 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
689
690 // Remove the CVO extension from the offered SDP.
691 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
692 cricket::VideoContentDescription* video =
693 GetFirstVideoContentDescription(desc);
694 video->ClearRtpHeaderExtensions();
695 });
696 // Wait for video frames to be received by both sides.
697 caller()->CreateAndSetAndSignalOffer();
698 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
699 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
700 callee()->min_video_frames_received_per_track() > 0,
701 kMaxWaitForFramesMs);
702
703 // Expect that the aspect ratio is inversed to account for the 90/270 degree
704 // rotation.
705 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
706 // not just assumed.
707 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
708 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
709 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
710 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
711 // Expect that each endpoint is unaware of the rotation of the other endpoint.
712 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
713 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
714}
715
deadbeef1dcb1642017-03-29 21:08:16 -0700716// Test that if the answerer rejects the audio m= section, no audio is sent or
717// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800718TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700719 ASSERT_TRUE(CreatePeerConnectionWrappers());
720 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800721 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200722 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800723 // Only add video track for callee, and set offer_to_receive_audio to 0, so
724 // it will reject the audio m= section completely.
725 PeerConnectionInterface::RTCOfferAnswerOptions options;
726 options.offer_to_receive_audio = 0;
727 callee()->SetOfferAnswerOptions(options);
728 } else {
729 // Stopping the audio RtpTransceiver will cause the media section to be
730 // rejected in the answer.
731 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200732 callee()
733 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
734 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800735 });
736 }
Steve Anton15324772018-01-16 10:26:49 -0800737 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700738 // Do offer/answer and wait for successful end-to-end video frames.
739 caller()->CreateAndSetAndSignalOffer();
740 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800741 MediaExpectations media_expectations;
742 media_expectations.ExpectBidirectionalVideo();
743 media_expectations.ExpectNoAudio();
744 ASSERT_TRUE(ExpectNewFrames(media_expectations));
745
deadbeef1dcb1642017-03-29 21:08:16 -0700746 // Sanity check that the callee's description has a rejected audio section.
747 ASSERT_NE(nullptr, callee()->pc()->local_description());
748 const ContentInfo* callee_audio_content =
749 GetFirstAudioContent(callee()->pc()->local_description()->description());
750 ASSERT_NE(nullptr, callee_audio_content);
751 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800752 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200753 // The caller's transceiver should have stopped after receiving the answer,
754 // and thus no longer listed in transceivers.
755 EXPECT_EQ(nullptr,
756 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800757 }
deadbeef1dcb1642017-03-29 21:08:16 -0700758}
759
760// Test that if the answerer rejects the video m= section, no video is sent or
761// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800762TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700763 ASSERT_TRUE(CreatePeerConnectionWrappers());
764 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800765 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200766 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800767 // Only add audio track for callee, and set offer_to_receive_video to 0, so
768 // it will reject the video m= section completely.
769 PeerConnectionInterface::RTCOfferAnswerOptions options;
770 options.offer_to_receive_video = 0;
771 callee()->SetOfferAnswerOptions(options);
772 } else {
773 // Stopping the video RtpTransceiver will cause the media section to be
774 // rejected in the answer.
775 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200776 callee()
777 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
778 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800779 });
780 }
Steve Anton15324772018-01-16 10:26:49 -0800781 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700782 // Do offer/answer and wait for successful end-to-end audio frames.
783 caller()->CreateAndSetAndSignalOffer();
784 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800785 MediaExpectations media_expectations;
786 media_expectations.ExpectBidirectionalAudio();
787 media_expectations.ExpectNoVideo();
788 ASSERT_TRUE(ExpectNewFrames(media_expectations));
789
deadbeef1dcb1642017-03-29 21:08:16 -0700790 // Sanity check that the callee's description has a rejected video section.
791 ASSERT_NE(nullptr, callee()->pc()->local_description());
792 const ContentInfo* callee_video_content =
793 GetFirstVideoContent(callee()->pc()->local_description()->description());
794 ASSERT_NE(nullptr, callee_video_content);
795 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800796 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200797 // The caller's transceiver should have stopped after receiving the answer,
798 // and thus is no longer present.
799 EXPECT_EQ(nullptr,
800 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800801 }
deadbeef1dcb1642017-03-29 21:08:16 -0700802}
803
804// Test that if the answerer rejects both audio and video m= sections, nothing
805// bad happens.
806// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
807// test anything but the fact that negotiation succeeds, which doesn't mean
808// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800809TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -0700810 ASSERT_TRUE(CreatePeerConnectionWrappers());
811 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800812 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200813 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800814 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
815 // will reject both audio and video m= sections.
816 PeerConnectionInterface::RTCOfferAnswerOptions options;
817 options.offer_to_receive_audio = 0;
818 options.offer_to_receive_video = 0;
819 callee()->SetOfferAnswerOptions(options);
820 } else {
821 callee()->SetRemoteOfferHandler([this] {
822 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +0100823 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200824 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800825 }
826 });
827 }
deadbeef1dcb1642017-03-29 21:08:16 -0700828 // Do offer/answer and wait for stable signaling state.
829 caller()->CreateAndSetAndSignalOffer();
830 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800831
deadbeef1dcb1642017-03-29 21:08:16 -0700832 // Sanity check that the callee's description has rejected m= sections.
833 ASSERT_NE(nullptr, callee()->pc()->local_description());
834 const ContentInfo* callee_audio_content =
835 GetFirstAudioContent(callee()->pc()->local_description()->description());
836 ASSERT_NE(nullptr, callee_audio_content);
837 EXPECT_TRUE(callee_audio_content->rejected);
838 const ContentInfo* callee_video_content =
839 GetFirstVideoContent(callee()->pc()->local_description()->description());
840 ASSERT_NE(nullptr, callee_video_content);
841 EXPECT_TRUE(callee_video_content->rejected);
842}
843
844// This test sets up an audio and video call between two parties. After the
845// call runs for a while, the caller sends an updated offer with video being
846// rejected. Once the re-negotiation is done, the video flow should stop and
847// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800848TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700849 ASSERT_TRUE(CreatePeerConnectionWrappers());
850 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800851 caller()->AddAudioVideoTracks();
852 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700853 caller()->CreateAndSetAndSignalOffer();
854 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800855 {
856 MediaExpectations media_expectations;
857 media_expectations.ExpectBidirectionalAudioAndVideo();
858 ASSERT_TRUE(ExpectNewFrames(media_expectations));
859 }
deadbeef1dcb1642017-03-29 21:08:16 -0700860 // Renegotiate, rejecting the video m= section.
Florent Castelli15a38de2022-04-06 00:38:21 +0200861 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800862 caller()->SetGeneratedSdpMunger(
863 [](cricket::SessionDescription* description) {
864 for (cricket::ContentInfo& content : description->contents()) {
865 if (cricket::IsVideoContent(&content)) {
866 content.rejected = true;
867 }
868 }
869 });
870 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200871 caller()
872 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
873 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800874 }
deadbeef1dcb1642017-03-29 21:08:16 -0700875 caller()->CreateAndSetAndSignalOffer();
876 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
877
878 // Sanity check that the caller's description has a rejected video section.
879 ASSERT_NE(nullptr, caller()->pc()->local_description());
880 const ContentInfo* caller_video_content =
881 GetFirstVideoContent(caller()->pc()->local_description()->description());
882 ASSERT_NE(nullptr, caller_video_content);
883 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -0700884 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800885 {
886 MediaExpectations media_expectations;
887 media_expectations.ExpectBidirectionalAudio();
888 media_expectations.ExpectNoVideo();
889 ASSERT_TRUE(ExpectNewFrames(media_expectations));
890 }
deadbeef1dcb1642017-03-29 21:08:16 -0700891}
892
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700893// Do one offer/answer with audio, another that disables it (rejecting the m=
894// section), and another that re-enables it. Regression test for:
895// bugs.webrtc.org/6023
896TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
897 ASSERT_TRUE(CreatePeerConnectionWrappers());
898 ConnectFakeSignaling();
899
900 // Add audio track, do normal offer/answer.
901 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
902 caller()->CreateLocalAudioTrack();
903 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
904 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
905 caller()->CreateAndSetAndSignalOffer();
906 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
907
908 // Remove audio track, and set offer_to_receive_audio to false to cause the
909 // m= section to be completely disabled, not just "recvonly".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000910 caller()->pc()->RemoveTrackOrError(sender);
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700911 PeerConnectionInterface::RTCOfferAnswerOptions options;
912 options.offer_to_receive_audio = 0;
913 caller()->SetOfferAnswerOptions(options);
914 caller()->CreateAndSetAndSignalOffer();
915 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
916
917 // Add the audio track again, expecting negotiation to succeed and frames to
918 // flow.
919 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
920 options.offer_to_receive_audio = 1;
921 caller()->SetOfferAnswerOptions(options);
922 caller()->CreateAndSetAndSignalOffer();
923 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
924
925 MediaExpectations media_expectations;
926 media_expectations.CalleeExpectsSomeAudio();
927 EXPECT_TRUE(ExpectNewFrames(media_expectations));
928}
929
deadbeef1dcb1642017-03-29 21:08:16 -0700930// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
931// is needed to support legacy endpoints.
932// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
933// add a test for an end-to-end test without MID signaling either (basically,
934// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800935TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -0700936 ASSERT_TRUE(CreatePeerConnectionWrappers());
937 ConnectFakeSignaling();
938 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -0800939 caller()->AddAudioVideoTracks();
940 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -0700941 // Remove SSRCs and MSIDs from the received offer SDP.
942 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -0700943 caller()->CreateAndSetAndSignalOffer();
944 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800945 MediaExpectations media_expectations;
946 media_expectations.ExpectBidirectionalAudioAndVideo();
947 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700948}
949
Seth Hampson5897a6e2018-04-03 11:16:33 -0700950// Basic end-to-end test, without SSRC signaling. This means that the track
951// was created properly and frames are delivered when the MSIDs are communicated
952// with a=msid lines and no a=ssrc lines.
953TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
954 EndToEndCallWithoutSsrcSignaling) {
955 const char kStreamId[] = "streamId";
956 ASSERT_TRUE(CreatePeerConnectionWrappers());
957 ConnectFakeSignaling();
958 // Add just audio tracks.
959 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
960 callee()->AddAudioTrack();
961
962 // Remove SSRCs from the received offer SDP.
963 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
964 caller()->CreateAndSetAndSignalOffer();
965 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
966 MediaExpectations media_expectations;
967 media_expectations.ExpectBidirectionalAudio();
968 ASSERT_TRUE(ExpectNewFrames(media_expectations));
969}
970
Johannes Kron3e983682020-03-29 22:17:00 +0200971TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
972 EndToEndCallAddReceiveVideoToSendOnlyCall) {
973 ASSERT_TRUE(CreatePeerConnectionWrappers());
974 ConnectFakeSignaling();
975 // Add one-directional video, from caller to callee.
976 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
977 caller()->CreateLocalVideoTrack();
978
979 RtpTransceiverInit video_transceiver_init;
980 video_transceiver_init.stream_ids = {"video1"};
981 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
982 auto video_sender =
983 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
984 caller()->CreateAndSetAndSignalOffer();
985 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
986
987 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +0200988 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +0200989
990 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
991 callee()->CreateLocalVideoTrack();
992
993 callee()->AddTrack(callee_track);
994 caller()->CreateAndSetAndSignalOffer();
995 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
996 // Ensure that video frames are received end-to-end.
997 MediaExpectations media_expectations;
998 media_expectations.ExpectBidirectionalVideo();
999 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1000}
1001
Steve Antondf527fd2018-04-27 15:52:03 -07001002// Tests that video flows between multiple video tracks when SSRCs are not
1003// signaled. This exercises the MID RTP header extension which is needed to
1004// demux the incoming video tracks.
1005TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1006 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
1007 ASSERT_TRUE(CreatePeerConnectionWrappers());
1008 ConnectFakeSignaling();
1009 caller()->AddVideoTrack();
1010 caller()->AddVideoTrack();
1011 callee()->AddVideoTrack();
1012 callee()->AddVideoTrack();
1013
1014 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1015 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1016 caller()->CreateAndSetAndSignalOffer();
1017 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1018 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1019 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1020
1021 // Expect video to be received in both directions on both tracks.
1022 MediaExpectations media_expectations;
1023 media_expectations.ExpectBidirectionalVideo();
1024 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1025}
1026
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07001027// Used for the test below.
1028void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
1029 RemoveSsrcsAndKeepMsids(desc);
1030 desc->RemoveGroupByName("BUNDLE");
1031 for (ContentInfo& content : desc->contents()) {
1032 cricket::MediaContentDescription* media = content.media_description();
1033 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1034 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1035 [](const RtpExtension& extension) {
1036 return extension.uri ==
1037 RtpExtension::kMidUri;
1038 }),
1039 extensions.end());
1040 media->set_rtp_header_extensions(extensions);
1041 }
1042}
1043
1044// Tests that video flows between multiple video tracks when BUNDLE is not used,
1045// SSRCs are not signaled and the MID RTP header extension is not used. This
1046// relies on demuxing by payload type, which normally doesn't work if you have
1047// multiple media sections using the same payload type, but which should work as
1048// long as the media sections aren't bundled.
1049// Regression test for: http://crbug.com/webrtc/12023
1050TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1051 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
1052 ASSERT_TRUE(CreatePeerConnectionWrappers());
1053 ConnectFakeSignaling();
1054 caller()->AddVideoTrack();
1055 caller()->AddVideoTrack();
1056 callee()->AddVideoTrack();
1057 callee()->AddVideoTrack();
1058 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1059 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1060 caller()->CreateAndSetAndSignalOffer();
1061 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1062 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1063 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1064 // Make sure we are not bundled.
1065 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
1066 caller()->pc()->GetSenders()[1]->dtls_transport());
1067
1068 // Expect video to be received in both directions on both tracks.
1069 MediaExpectations media_expectations;
1070 media_expectations.ExpectBidirectionalVideo();
1071 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1072}
1073
1074// Used for the test below.
1075void ModifyPayloadTypesAndRemoveMidExtension(
1076 cricket::SessionDescription* desc) {
1077 int pt = 96;
1078 for (ContentInfo& content : desc->contents()) {
1079 cricket::MediaContentDescription* media = content.media_description();
1080 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1081 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1082 [](const RtpExtension& extension) {
1083 return extension.uri ==
1084 RtpExtension::kMidUri;
1085 }),
1086 extensions.end());
1087 media->set_rtp_header_extensions(extensions);
1088 cricket::VideoContentDescription* video = media->as_video();
1089 ASSERT_TRUE(video != nullptr);
1090 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
1091 video->set_codecs(codecs);
1092 }
1093}
1094
1095// Tests that two video tracks can be demultiplexed by payload type alone, by
1096// using different payload types for the same codec in different m= sections.
1097// This practice is discouraged but historically has been supported.
1098// Regression test for: http://crbug.com/webrtc/12029
1099TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1100 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
1101 ASSERT_TRUE(CreatePeerConnectionWrappers());
1102 ConnectFakeSignaling();
1103 caller()->AddVideoTrack();
1104 caller()->AddVideoTrack();
1105 callee()->AddVideoTrack();
1106 callee()->AddVideoTrack();
1107 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1108 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1109 // We can't remove SSRCs from the generated SDP because then no send streams
1110 // would be created.
1111 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1112 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1113 caller()->CreateAndSetAndSignalOffer();
1114 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1115 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1116 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1117 // Make sure we are bundled.
1118 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
1119 caller()->pc()->GetSenders()[1]->dtls_transport());
1120
1121 // Expect video to be received in both directions on both tracks.
1122 MediaExpectations media_expectations;
1123 media_expectations.ExpectBidirectionalVideo();
1124 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1125}
1126
Henrik Boström5b147782018-12-04 11:25:05 +01001127TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
1128 ASSERT_TRUE(CreatePeerConnectionWrappers());
1129 ConnectFakeSignaling();
1130 caller()->AddAudioTrack();
1131 caller()->AddVideoTrack();
1132 caller()->CreateAndSetAndSignalOffer();
1133 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1134 auto callee_receivers = callee()->pc()->GetReceivers();
1135 ASSERT_EQ(2u, callee_receivers.size());
1136 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
1137 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
1138}
1139
1140TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
1141 ASSERT_TRUE(CreatePeerConnectionWrappers());
1142 ConnectFakeSignaling();
1143 caller()->AddAudioTrack();
1144 caller()->AddVideoTrack();
1145 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1146 caller()->CreateAndSetAndSignalOffer();
1147 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1148 auto callee_receivers = callee()->pc()->GetReceivers();
1149 ASSERT_EQ(2u, callee_receivers.size());
1150 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
1151 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
1152 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
1153 callee_receivers[1]->stream_ids()[0]);
1154 EXPECT_EQ(callee_receivers[0]->streams()[0],
1155 callee_receivers[1]->streams()[0]);
1156}
1157
deadbeef1dcb1642017-03-29 21:08:16 -07001158// Test that if two video tracks are sent (from caller to callee, in this test),
1159// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001160TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07001161 ASSERT_TRUE(CreatePeerConnectionWrappers());
1162 ConnectFakeSignaling();
1163 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08001164 caller()->AddAudioVideoTracks();
1165 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001166 caller()->CreateAndSetAndSignalOffer();
1167 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08001168 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001169
1170 MediaExpectations media_expectations;
1171 media_expectations.CalleeExpectsSomeAudioAndVideo();
1172 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001173}
1174
1175static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
1176 bool first = true;
1177 for (cricket::ContentInfo& content : desc->contents()) {
1178 if (first) {
1179 first = false;
1180 continue;
1181 }
1182 content.bundle_only = true;
1183 }
1184 first = true;
1185 for (cricket::TransportInfo& transport : desc->transport_infos()) {
1186 if (first) {
1187 first = false;
1188 continue;
1189 }
1190 transport.description.ice_ufrag.clear();
1191 transport.description.ice_pwd.clear();
1192 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
1193 transport.description.identity_fingerprint.reset(nullptr);
1194 }
1195}
1196
1197// Test that if applying a true "max bundle" offer, which uses ports of 0,
1198// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
1199// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
1200// successfully and media flows.
1201// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
1202// TODO(deadbeef): Won't need this test once we start generating actual
1203// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001204TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001205 EndToEndCallWithSpecCompliantMaxBundleOffer) {
1206 ASSERT_TRUE(CreatePeerConnectionWrappers());
1207 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001208 caller()->AddAudioVideoTracks();
1209 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001210 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
1211 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
1212 // but the first m= section.
1213 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
1214 caller()->CreateAndSetAndSignalOffer();
1215 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001216 MediaExpectations media_expectations;
1217 media_expectations.ExpectBidirectionalAudioAndVideo();
1218 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001219}
1220
1221// Test that we can receive the audio output level from a remote audio track.
1222// TODO(deadbeef): Use a fake audio source and verify that the output level is
1223// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001224TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001225 ASSERT_TRUE(CreatePeerConnectionWrappers());
1226 ConnectFakeSignaling();
1227 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001228 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001229 caller()->CreateAndSetAndSignalOffer();
1230 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1231
1232 // Get the audio output level stats. Note that the level is not available
1233 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07001234 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001235 kMaxWaitForFramesMs);
1236}
1237
1238// Test that an audio input level is reported.
1239// TODO(deadbeef): Use a fake audio source and verify that the input level is
1240// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001241TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001242 ASSERT_TRUE(CreatePeerConnectionWrappers());
1243 ConnectFakeSignaling();
1244 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001245 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001246 caller()->CreateAndSetAndSignalOffer();
1247 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1248
1249 // Get the audio input level stats. The level should be available very
1250 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07001251 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001252 kMaxWaitForStatsMs);
1253}
1254
1255// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001256TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001257 ASSERT_TRUE(CreatePeerConnectionWrappers());
1258 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001259 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001260 // Do offer/answer, wait for the callee to receive some frames.
1261 caller()->CreateAndSetAndSignalOffer();
1262 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001263
1264 MediaExpectations media_expectations;
1265 media_expectations.CalleeExpectsSomeAudioAndVideo();
1266 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001267
1268 // Get a handle to the remote tracks created, so they can be used as GetStats
1269 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01001270 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08001271 // We received frames, so we definitely should have nonzero "received bytes"
1272 // stats at this point.
Niels Möllerafb246b2022-04-20 14:26:50 +02001273 EXPECT_GT(
1274 callee()->OldGetStatsForTrack(receiver->track().get())->BytesReceived(),
1275 0);
Steve Anton15324772018-01-16 10:26:49 -08001276 }
deadbeef1dcb1642017-03-29 21:08:16 -07001277}
1278
1279// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001280TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001281 ASSERT_TRUE(CreatePeerConnectionWrappers());
1282 ConnectFakeSignaling();
1283 auto audio_track = caller()->CreateLocalAudioTrack();
1284 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08001285 caller()->AddTrack(audio_track);
1286 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07001287 // Do offer/answer, wait for the callee to receive some frames.
1288 caller()->CreateAndSetAndSignalOffer();
1289 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001290 MediaExpectations media_expectations;
1291 media_expectations.CalleeExpectsSomeAudioAndVideo();
1292 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001293
1294 // The callee received frames, so we definitely should have nonzero "sent
1295 // bytes" stats at this point.
Niels Möllerafb246b2022-04-20 14:26:50 +02001296 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track.get())->BytesSent(), 0);
1297 EXPECT_GT(caller()->OldGetStatsForTrack(video_track.get())->BytesSent(), 0);
deadbeefd8ad7882017-04-18 16:01:17 -07001298}
1299
Steve Antona41959e2018-11-28 11:15:33 -08001300// Test that the track ID is associated with all local and remote SSRC stats
1301// using the old GetStats() and more than 1 audio and more than 1 video track.
1302// This is a regression test for crbug.com/906988
1303TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1304 OldGetStatsAssociatesTrackIdForManyMediaSections) {
1305 ASSERT_TRUE(CreatePeerConnectionWrappers());
1306 ConnectFakeSignaling();
1307 auto audio_sender_1 = caller()->AddAudioTrack();
1308 auto video_sender_1 = caller()->AddVideoTrack();
1309 auto audio_sender_2 = caller()->AddAudioTrack();
1310 auto video_sender_2 = caller()->AddVideoTrack();
1311 caller()->CreateAndSetAndSignalOffer();
1312 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1313
1314 MediaExpectations media_expectations;
1315 media_expectations.CalleeExpectsSomeAudioAndVideo();
1316 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1317
1318 std::vector<std::string> track_ids = {
1319 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1320 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1321
1322 auto caller_stats = caller()->OldGetStats();
1323 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1324 auto callee_stats = callee()->OldGetStats();
1325 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1326}
1327
Steve Antonffa6ce42018-11-30 09:26:08 -08001328// Test that the new GetStats() returns stats for all outgoing/incoming streams
Henrik Boström323e9df2022-12-24 10:33:39 +01001329// with the correct track identifiers if there are more than one audio and more
1330// than one video senders/receivers.
Steve Antonffa6ce42018-11-30 09:26:08 -08001331TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
1332 ASSERT_TRUE(CreatePeerConnectionWrappers());
1333 ConnectFakeSignaling();
1334 auto audio_sender_1 = caller()->AddAudioTrack();
1335 auto video_sender_1 = caller()->AddVideoTrack();
1336 auto audio_sender_2 = caller()->AddAudioTrack();
1337 auto video_sender_2 = caller()->AddVideoTrack();
1338 caller()->CreateAndSetAndSignalOffer();
1339 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1340
1341 MediaExpectations media_expectations;
1342 media_expectations.CalleeExpectsSomeAudioAndVideo();
1343 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1344
1345 std::vector<std::string> track_ids = {
1346 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1347 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1348
1349 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
1350 caller()->NewGetStats();
1351 ASSERT_TRUE(caller_report);
1352 auto outbound_stream_stats =
1353 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02001354 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08001355 std::vector<std::string> outbound_track_ids;
1356 for (const auto& stat : outbound_stream_stats) {
1357 ASSERT_TRUE(stat->bytes_sent.is_defined());
1358 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001359 if (*stat->kind == "video") {
1360 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
1361 EXPECT_GT(*stat->key_frames_encoded, 0u);
1362 ASSERT_TRUE(stat->frames_encoded.is_defined());
1363 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
1364 }
Henrik Boström323e9df2022-12-24 10:33:39 +01001365 ASSERT_TRUE(stat->media_source_id.is_defined());
1366 const RTCMediaSourceStats* media_source =
1367 static_cast<const RTCMediaSourceStats*>(
1368 caller_report->Get(*stat->media_source_id));
1369 ASSERT_TRUE(media_source);
1370 outbound_track_ids.push_back(*media_source->track_identifier);
Steve Antonffa6ce42018-11-30 09:26:08 -08001371 }
1372 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
1373
1374 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
1375 callee()->NewGetStats();
1376 ASSERT_TRUE(callee_report);
1377 auto inbound_stream_stats =
1378 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1379 ASSERT_EQ(4u, inbound_stream_stats.size());
1380 std::vector<std::string> inbound_track_ids;
1381 for (const auto& stat : inbound_stream_stats) {
1382 ASSERT_TRUE(stat->bytes_received.is_defined());
1383 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001384 if (*stat->kind == "video") {
1385 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
1386 EXPECT_GT(*stat->key_frames_decoded, 0u);
1387 ASSERT_TRUE(stat->frames_decoded.is_defined());
1388 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
1389 }
Henrik Boström323e9df2022-12-24 10:33:39 +01001390 inbound_track_ids.push_back(*stat->track_identifier);
Steve Antonffa6ce42018-11-30 09:26:08 -08001391 }
1392 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
1393}
1394
1395// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07001396// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
1397// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001398TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07001399 GetStatsForUnsignaledStreamWithNewStatsApi) {
1400 ASSERT_TRUE(CreatePeerConnectionWrappers());
1401 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001402 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07001403 // Remove SSRCs and MSIDs from the received offer SDP.
1404 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1405 caller()->CreateAndSetAndSignalOffer();
1406 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001407 MediaExpectations media_expectations;
1408 media_expectations.CalleeExpectsSomeAudio(1);
1409 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07001410
1411 // We received a frame, so we should have nonzero "bytes received" stats for
1412 // the unsignaled stream, if stats are working for it.
1413 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1414 callee()->NewGetStats();
1415 ASSERT_NE(nullptr, report);
1416 auto inbound_stream_stats =
1417 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1418 ASSERT_EQ(1U, inbound_stream_stats.size());
1419 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
1420 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07001421 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
1422}
1423
Taylor Brandstettera4653442018-06-19 09:44:26 -07001424// Same as above but for the legacy stats implementation.
1425TEST_P(PeerConnectionIntegrationTest,
1426 GetStatsForUnsignaledStreamWithOldStatsApi) {
1427 ASSERT_TRUE(CreatePeerConnectionWrappers());
1428 ConnectFakeSignaling();
1429 caller()->AddAudioTrack();
1430 // Remove SSRCs and MSIDs from the received offer SDP.
1431 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1432 caller()->CreateAndSetAndSignalOffer();
1433 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1434
1435 // Note that, since the old stats implementation associates SSRCs with tracks
1436 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
1437 // associated track ID. So we can't use the track "selector" argument.
1438 //
1439 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
1440 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001441 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07001442 kDefaultTimeout);
1443}
1444
zhihuangf8164932017-05-19 13:09:47 -07001445// Test that we can successfully get the media related stats (audio level
1446// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001447TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07001448 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
1449 ASSERT_TRUE(CreatePeerConnectionWrappers());
1450 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001451 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07001452 // Remove SSRCs and MSIDs from the received offer SDP.
1453 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1454 caller()->CreateAndSetAndSignalOffer();
1455 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001456 MediaExpectations media_expectations;
1457 media_expectations.CalleeExpectsSomeAudio(1);
1458 media_expectations.CalleeExpectsSomeVideo(1);
1459 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07001460
1461 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1462 callee()->NewGetStats();
1463 ASSERT_NE(nullptr, report);
1464
Henrik Boström323e9df2022-12-24 10:33:39 +01001465 auto inbound_rtps =
1466 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1467 auto index = FindFirstMediaStatsIndexByKind("audio", inbound_rtps);
1468 ASSERT_GE(index, 0);
1469 EXPECT_TRUE(inbound_rtps[index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07001470}
1471
deadbeef4e2deab2017-09-20 13:56:21 -07001472// Helper for test below.
1473void ModifySsrcs(cricket::SessionDescription* desc) {
1474 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07001475 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08001476 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07001477 for (uint32_t& ssrc : stream.ssrcs) {
1478 ssrc = rtc::CreateRandomId();
1479 }
1480 }
1481 }
1482}
1483
Henrik Boström15166b22022-10-19 11:06:58 +02001484// Test that the "DEPRECATED_RTCMediaStreamTrackStats" object is updated
1485// correctly when SSRCs are unsignaled, and the SSRC of the received (audio)
1486// stream changes. This should result in two "RTCInboundRTPStreamStats", but
1487// only one "DEPRECATED_RTCMediaStreamTrackStats", whose counters go up
1488// continuously rather than being reset to 0 once the SSRC change occurs.
deadbeef4e2deab2017-09-20 13:56:21 -07001489//
1490// Regression test for this bug:
1491// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
1492//
1493// The bug causes the track stats to only represent one of the two streams:
1494// whichever one has the higher SSRC. So with this bug, there was a 50% chance
1495// that the track stat counters would reset to 0 when the new stream is
1496// received, and a 50% chance that they'll stop updating (while
1497// "concealed_samples" continues increasing, due to silence being generated for
1498// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001499TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08001500 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07001501 ASSERT_TRUE(CreatePeerConnectionWrappers());
1502 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001503 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07001504 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
1505 // that doesn't signal SSRCs (from the callee's perspective).
1506 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1507 caller()->CreateAndSetAndSignalOffer();
1508 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1509 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001510 {
1511 MediaExpectations media_expectations;
1512 media_expectations.CalleeExpectsSomeAudio(50);
1513 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1514 }
deadbeef4e2deab2017-09-20 13:56:21 -07001515 // Some audio frames were received, so we should have nonzero "samples
1516 // received" for the track.
1517 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1518 callee()->NewGetStats();
1519 ASSERT_NE(nullptr, report);
Henrik Boström15166b22022-10-19 11:06:58 +02001520 auto track_stats =
1521 report->GetStatsOfType<webrtc::DEPRECATED_RTCMediaStreamTrackStats>();
deadbeef4e2deab2017-09-20 13:56:21 -07001522 ASSERT_EQ(1U, track_stats.size());
1523 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1524 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
1525 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
1526
1527 // Create a new offer and munge it to cause the caller to use a new SSRC.
1528 caller()->SetGeneratedSdpMunger(ModifySsrcs);
1529 caller()->CreateAndSetAndSignalOffer();
1530 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1531 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
1532 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001533 {
1534 MediaExpectations media_expectations;
1535 media_expectations.CalleeExpectsSomeAudio(25);
1536 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1537 }
deadbeef4e2deab2017-09-20 13:56:21 -07001538
1539 report = callee()->NewGetStats();
1540 ASSERT_NE(nullptr, report);
Henrik Boström15166b22022-10-19 11:06:58 +02001541 track_stats =
1542 report->GetStatsOfType<webrtc::DEPRECATED_RTCMediaStreamTrackStats>();
deadbeef4e2deab2017-09-20 13:56:21 -07001543 ASSERT_EQ(1U, track_stats.size());
1544 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1545 // The "total samples received" stat should only be greater than it was
1546 // before.
1547 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
1548 // Right now, the new SSRC will cause the counters to reset to 0.
1549 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
1550
1551 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08001552 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07001553 // good sign that we're seeing stats from the old stream that's no longer
1554 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08001555 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07001556 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
1557 EXPECT_LT(*track_stats[0]->concealed_samples,
1558 *track_stats[0]->total_samples_received *
1559 kAcceptableConcealedSamplesPercentage);
1560
1561 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
1562 // sanity check that the SSRC really changed.
1563 // TODO(deadbeef): This isn't working right now, because we're not returning
1564 // *any* stats for the inactive stream. Uncomment when the bug is completely
1565 // fixed.
1566 // auto inbound_stream_stats =
1567 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1568 // ASSERT_EQ(2U, inbound_stream_stats.size());
1569}
1570
deadbeef1dcb1642017-03-29 21:08:16 -07001571// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001572TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001573 PeerConnectionFactory::Options dtls_10_options;
1574 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1575 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1576 dtls_10_options));
1577 ConnectFakeSignaling();
1578 // Do normal offer/answer and wait for some frames to be received in each
1579 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001580 caller()->AddAudioVideoTracks();
1581 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001582 caller()->CreateAndSetAndSignalOffer();
1583 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001584 MediaExpectations media_expectations;
1585 media_expectations.ExpectBidirectionalAudioAndVideo();
1586 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001587}
1588
1589// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001590TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001591 PeerConnectionFactory::Options dtls_10_options;
1592 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1593 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1594 dtls_10_options));
1595 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001596 caller()->AddAudioVideoTracks();
1597 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001598 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001599 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001600 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001601 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001602 kDefaultTimeout);
1603 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001604 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001605 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001606 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1607 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1608 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001609}
1610
1611// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001612TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001613 PeerConnectionFactory::Options dtls_12_options;
1614 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1615 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
1616 dtls_12_options));
1617 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001618 caller()->AddAudioVideoTracks();
1619 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001620 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001621 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001622 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001623 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001624 kDefaultTimeout);
1625 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001626 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001627 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001628 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1629 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1630 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001631}
1632
1633// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
1634// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001635TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001636 PeerConnectionFactory::Options caller_options;
1637 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1638 PeerConnectionFactory::Options callee_options;
1639 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1640 ASSERT_TRUE(
1641 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1642 ConnectFakeSignaling();
1643 // Do normal offer/answer and wait for some frames to be received in each
1644 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001645 caller()->AddAudioVideoTracks();
1646 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001647 caller()->CreateAndSetAndSignalOffer();
1648 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001649 MediaExpectations media_expectations;
1650 media_expectations.ExpectBidirectionalAudioAndVideo();
1651 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001652}
1653
1654// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
1655// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001656TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07001657 PeerConnectionFactory::Options caller_options;
1658 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1659 PeerConnectionFactory::Options callee_options;
1660 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1661 ASSERT_TRUE(
1662 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1663 ConnectFakeSignaling();
1664 // Do normal offer/answer and wait for some frames to be received in each
1665 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001666 caller()->AddAudioVideoTracks();
1667 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001668 caller()->CreateAndSetAndSignalOffer();
1669 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001670 MediaExpectations media_expectations;
1671 media_expectations.ExpectBidirectionalAudioAndVideo();
1672 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001673}
1674
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001675// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
1676// works as expected; the cipher should only be used if enabled by both sides.
1677TEST_P(PeerConnectionIntegrationTest,
1678 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
1679 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001680 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001681 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001682 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1683 false;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001684 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001685 TestNegotiatedCipherSuite(caller_options, callee_options,
1686 expected_cipher_suite);
1687}
1688
1689TEST_P(PeerConnectionIntegrationTest,
1690 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
1691 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001692 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1693 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001694 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001695 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001696 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001697 TestNegotiatedCipherSuite(caller_options, callee_options,
1698 expected_cipher_suite);
1699}
1700
1701TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
1702 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001703 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001704 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001705 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001706 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_32;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001707 TestNegotiatedCipherSuite(caller_options, callee_options,
1708 expected_cipher_suite);
1709}
1710
deadbeef1dcb1642017-03-29 21:08:16 -07001711// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001712TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001713 bool local_gcm_enabled = false;
1714 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001715 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07001716 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
1717 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001718 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001719}
1720
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001721// Test that a GCM cipher is used if both ends support it and non-GCM is
1722// disabled.
1723TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001724 bool local_gcm_enabled = true;
1725 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001726 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07001727 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
1728 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001729 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001730}
1731
deadbeef7914b8c2017-04-21 03:23:33 -07001732// Verify that media can be transmitted end-to-end when GCM crypto suites are
1733// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
1734// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
1735// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001736TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07001737 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001738 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001739 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07001740 ASSERT_TRUE(
1741 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
1742 ConnectFakeSignaling();
1743 // Do normal offer/answer and wait for some frames to be received in each
1744 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001745 caller()->AddAudioVideoTracks();
1746 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07001747 caller()->CreateAndSetAndSignalOffer();
1748 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001749 MediaExpectations media_expectations;
1750 media_expectations.ExpectBidirectionalAudioAndVideo();
1751 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07001752}
1753
deadbeef1dcb1642017-03-29 21:08:16 -07001754// Test that the ICE connection and gathering states eventually reach
1755// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08001756TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07001757 ASSERT_TRUE(CreatePeerConnectionWrappers());
1758 ConnectFakeSignaling();
1759 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001760 caller()->AddAudioVideoTracks();
1761 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001762 caller()->CreateAndSetAndSignalOffer();
1763 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1764 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1765 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
1766 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1767 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
1768 // After the best candidate pair is selected and all candidates are signaled,
1769 // the ICE connection state should reach "complete".
1770 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
1771 // answerer/"callee" by default) only reaches "connected". When this is
1772 // fixed, this test should be updated.
1773 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1774 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00001775 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1776 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001777}
1778
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001779constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1780 cricket::PORTALLOCATOR_DISABLE_RELAY |
1781 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001782
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001783// Use a mock resolver to resolve the hostname back to the original IP on both
1784// sides and check that the ICE connection connects.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001785TEST_P(PeerConnectionIntegrationTest,
Harald Alvestrand099ff622022-06-02 13:24:32 +00001786 IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001787 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001788 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001789 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001790 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001791 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1792 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001793
1794 // This also verifies that the injected AsyncResolverFactory is used by
1795 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001796 EXPECT_CALL(*caller_resolver_factory, Create())
1797 .WillOnce(Return(&caller_async_resolver));
1798 webrtc::PeerConnectionDependencies caller_deps(nullptr);
1799 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1800
1801 EXPECT_CALL(*callee_resolver_factory, Create())
1802 .WillOnce(Return(&callee_async_resolver));
1803 webrtc::PeerConnectionDependencies callee_deps(nullptr);
1804 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1805
1806 PeerConnectionInterface::RTCConfiguration config;
1807 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1808 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1809
1810 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1811 config, std::move(caller_deps), config, std::move(callee_deps)));
1812
1813 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1814 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1815
1816 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07001817 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001818 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07001819 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001820 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001821
1822 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001823
1824 ConnectFakeSignaling();
1825 caller()->AddAudioVideoTracks();
1826 callee()->AddAudioVideoTracks();
1827 caller()->CreateAndSetAndSignalOffer();
1828 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1829 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1830 caller()->ice_connection_state(), kDefaultTimeout);
1831 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1832 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08001833
Ying Wangef3998f2019-12-09 13:06:53 +01001834 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1835 "WebRTC.PeerConnection.CandidatePairType_UDP",
1836 webrtc::kIceCandidatePairHostNameHostName));
Harald Alvestrand4f7486a2022-06-02 11:35:49 +00001837 DestroyPeerConnections();
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001838}
1839
Steve Antonede9ca52017-10-16 13:04:27 -07001840// Test that firewalling the ICE connection causes the clients to identify the
1841// disconnected state and then removing the firewall causes them to reconnect.
1842class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08001843 : public PeerConnectionIntegrationBaseTest,
1844 public ::testing::WithParamInterface<
1845 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07001846 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001847 PeerConnectionIntegrationIceStatesTest()
1848 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1849 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07001850 }
1851
1852 void StartStunServer(const SocketAddress& server_address) {
1853 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01001854 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07001855 }
1856
1857 bool TestIPv6() {
1858 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1859 }
1860
1861 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001862 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1863 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07001864 }
1865
1866 std::vector<SocketAddress> CallerAddresses() {
1867 std::vector<SocketAddress> addresses;
1868 addresses.push_back(SocketAddress("1.1.1.1", 0));
1869 if (TestIPv6()) {
1870 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1871 }
1872 return addresses;
1873 }
1874
1875 std::vector<SocketAddress> CalleeAddresses() {
1876 std::vector<SocketAddress> addresses;
1877 addresses.push_back(SocketAddress("2.2.2.2", 0));
1878 if (TestIPv6()) {
1879 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1880 }
1881 return addresses;
1882 }
1883
1884 void SetUpNetworkInterfaces() {
1885 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07001886 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1887 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07001888
1889 // Add network addresses for test.
1890 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001891 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001892 }
1893 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001894 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001895 }
1896 }
1897
1898 private:
1899 uint32_t port_allocator_flags_;
1900 std::unique_ptr<cricket::TestStunServer> stun_server_;
1901};
1902
Yves Gerey100fe632020-01-17 19:15:53 +01001903// Ensure FakeClockForTest is constructed first (see class for rationale).
1904class PeerConnectionIntegrationIceStatesTestWithFakeClock
1905 : public FakeClockForTest,
1906 public PeerConnectionIntegrationIceStatesTest {};
1907
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001908#if !defined(THREAD_SANITIZER)
1909// This test provokes TSAN errors. bugs.webrtc.org/11282
1910
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001911// Tests that if the connection doesn't get set up properly we eventually reach
1912// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01001913TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
1914 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001915 // Block connections to/from the caller and wait for ICE to become
1916 // disconnected.
1917 for (const auto& caller_address : CallerAddresses()) {
1918 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
1919 }
1920
1921 ASSERT_TRUE(CreatePeerConnectionWrappers());
1922 ConnectFakeSignaling();
1923 SetPortAllocatorFlags();
1924 SetUpNetworkInterfaces();
1925 caller()->AddAudioVideoTracks();
1926 caller()->CreateAndSetAndSignalOffer();
1927
1928 // According to RFC7675, if there is no response within 30 seconds then the
1929 // peer should consider the other side to have rejected the connection. This
1930 // is signaled by the state transitioning to "failed".
1931 constexpr int kConsentTimeout = 30000;
1932 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
1933 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01001934 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07001935}
1936
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001937#endif // !defined(THREAD_SANITIZER)
1938
Steve Antonede9ca52017-10-16 13:04:27 -07001939// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
1940// and that the statistics in the metric observers are updated correctly.
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001941// TODO(bugs.webrtc.org/12591): Flaky on Windows.
1942#if defined(WEBRTC_WIN)
1943#define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
1944#else
1945#define MAYBE_VerifyBestConnection VerifyBestConnection
1946#endif
1947TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
Steve Antonede9ca52017-10-16 13:04:27 -07001948 ASSERT_TRUE(CreatePeerConnectionWrappers());
1949 ConnectFakeSignaling();
1950 SetPortAllocatorFlags();
1951 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08001952 caller()->AddAudioVideoTracks();
1953 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07001954 caller()->CreateAndSetAndSignalOffer();
1955
1956 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08001957 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1958 caller()->ice_connection_state(), kDefaultTimeout);
1959 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1960 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07001961
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001962 // TODO(bugs.webrtc.org/9456): Fix it.
1963 const int num_best_ipv4 = webrtc::metrics::NumEvents(
1964 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
1965 const int num_best_ipv6 = webrtc::metrics::NumEvents(
1966 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001967 if (TestIPv6()) {
1968 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
1969 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01001970 EXPECT_METRIC_EQ(0, num_best_ipv4);
1971 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001972 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01001973 EXPECT_METRIC_EQ(1, num_best_ipv4);
1974 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001975 }
1976
Ying Wangef3998f2019-12-09 13:06:53 +01001977 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
1978 "WebRTC.PeerConnection.CandidatePairType_UDP",
1979 webrtc::kIceCandidatePairHostHost));
1980 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1981 "WebRTC.PeerConnection.CandidatePairType_UDP",
1982 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07001983}
1984
1985constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
1986 cricket::PORTALLOCATOR_DISABLE_STUN |
1987 cricket::PORTALLOCATOR_DISABLE_RELAY;
1988constexpr uint32_t kFlagsIPv6NoStun =
1989 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
1990 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
1991constexpr uint32_t kFlagsIPv4Stun =
1992 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
1993
Mirko Bonadeic84f6612019-01-31 12:20:57 +01001994INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08001995 PeerConnectionIntegrationTest,
1996 PeerConnectionIntegrationIceStatesTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02001997 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Seth Hampson2f0d7022018-02-20 11:54:42 -08001998 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
1999 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2000 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07002001
Yves Gerey100fe632020-01-17 19:15:53 +01002002INSTANTIATE_TEST_SUITE_P(
2003 PeerConnectionIntegrationTest,
2004 PeerConnectionIntegrationIceStatesTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02002005 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Yves Gerey100fe632020-01-17 19:15:53 +01002006 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2007 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2008 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2009
deadbeef1dcb1642017-03-29 21:08:16 -07002010// This test sets up a call between two parties with audio and video.
2011// During the call, the caller restarts ICE and the test verifies that
2012// new ICE candidates are generated and audio and video still can flow, and the
2013// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002014TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07002015 ASSERT_TRUE(CreatePeerConnectionWrappers());
2016 ConnectFakeSignaling();
2017 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08002018 caller()->AddAudioVideoTracks();
2019 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002020 caller()->CreateAndSetAndSignalOffer();
2021 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2022 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2023 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002024 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2025 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07002026
2027 // To verify that the ICE restart actually occurs, get
2028 // ufrag/password/candidates before and after restart.
2029 // Create an SDP string of the first audio candidate for both clients.
2030 const webrtc::IceCandidateCollection* audio_candidates_caller =
2031 caller()->pc()->local_description()->candidates(0);
2032 const webrtc::IceCandidateCollection* audio_candidates_callee =
2033 callee()->pc()->local_description()->candidates(0);
2034 ASSERT_GT(audio_candidates_caller->count(), 0u);
2035 ASSERT_GT(audio_candidates_callee->count(), 0u);
2036 std::string caller_candidate_pre_restart;
2037 ASSERT_TRUE(
2038 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2039 std::string callee_candidate_pre_restart;
2040 ASSERT_TRUE(
2041 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2042 const cricket::SessionDescription* desc =
2043 caller()->pc()->local_description()->description();
2044 std::string caller_ufrag_pre_restart =
2045 desc->transport_infos()[0].description.ice_ufrag;
2046 desc = callee()->pc()->local_description()->description();
2047 std::string callee_ufrag_pre_restart =
2048 desc->transport_infos()[0].description.ice_ufrag;
2049
Alex Drake00c7ecf2019-08-06 10:54:47 -07002050 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002051 // Have the caller initiate an ICE restart.
2052 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2053 caller()->CreateAndSetAndSignalOffer();
2054 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2055 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2056 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002057 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07002058 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2059
2060 // Grab the ufrags/candidates again.
2061 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2062 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2063 ASSERT_GT(audio_candidates_caller->count(), 0u);
2064 ASSERT_GT(audio_candidates_callee->count(), 0u);
2065 std::string caller_candidate_post_restart;
2066 ASSERT_TRUE(
2067 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2068 std::string callee_candidate_post_restart;
2069 ASSERT_TRUE(
2070 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2071 desc = caller()->pc()->local_description()->description();
2072 std::string caller_ufrag_post_restart =
2073 desc->transport_infos()[0].description.ice_ufrag;
2074 desc = callee()->pc()->local_description()->description();
2075 std::string callee_ufrag_post_restart =
2076 desc->transport_infos()[0].description.ice_ufrag;
2077 // Sanity check that an ICE restart was actually negotiated in SDP.
2078 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2079 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2080 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2081 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07002082 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002083
2084 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002085 MediaExpectations media_expectations;
2086 media_expectations.ExpectBidirectionalAudioAndVideo();
2087 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002088}
2089
2090// Verify that audio/video can be received end-to-end when ICE renomination is
2091// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002092TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07002093 PeerConnectionInterface::RTCConfiguration config;
2094 config.enable_ice_renomination = true;
2095 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2096 ConnectFakeSignaling();
2097 // Do normal offer/answer and wait for some frames to be received in each
2098 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002099 caller()->AddAudioVideoTracks();
2100 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002101 caller()->CreateAndSetAndSignalOffer();
2102 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2103 // Sanity check that ICE renomination was actually negotiated.
2104 const cricket::SessionDescription* desc =
2105 caller()->pc()->local_description()->description();
2106 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002107 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002108 }
2109 desc = callee()->pc()->local_description()->description();
2110 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002111 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002112 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08002113 MediaExpectations media_expectations;
2114 media_expectations.ExpectBidirectionalAudioAndVideo();
2115 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002116}
2117
Steve Anton6f25b092017-10-23 09:39:20 -07002118// With a max bundle policy and RTCP muxing, adding a new media description to
2119// the connection should not affect ICE at all because the new media will use
2120// the existing connection.
Rasmus Brandt685be142021-03-15 14:03:38 +01002121// TODO(bugs.webrtc.org/12538): Fails on tsan.
2122#if defined(THREAD_SANITIZER)
2123#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2124 DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2125#else
2126#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2127 AddMediaToConnectedBundleDoesNotRestartIce
2128#endif
Seth Hampson2f0d7022018-02-20 11:54:42 -08002129TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt685be142021-03-15 14:03:38 +01002130 MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07002131 PeerConnectionInterface::RTCConfiguration config;
2132 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2133 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2134 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2135 config, PeerConnectionInterface::RTCConfiguration()));
2136 ConnectFakeSignaling();
2137
Steve Anton15324772018-01-16 10:26:49 -08002138 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002139 caller()->CreateAndSetAndSignalOffer();
2140 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07002141 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2142 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07002143
2144 caller()->clear_ice_connection_state_history();
2145
Steve Anton15324772018-01-16 10:26:49 -08002146 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002147 caller()->CreateAndSetAndSignalOffer();
2148 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2149
2150 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2151}
2152
deadbeef1dcb1642017-03-29 21:08:16 -07002153// This test sets up a call between two parties with audio and video. It then
2154// renegotiates setting the video m-line to "port 0", then later renegotiates
2155// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002156TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002157 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2158 ASSERT_TRUE(CreatePeerConnectionWrappers());
2159 ConnectFakeSignaling();
2160
2161 // Do initial negotiation, only sending media from the caller. Will result in
2162 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08002163 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002164 caller()->CreateAndSetAndSignalOffer();
2165 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2166
2167 // Negotiate again, disabling the video "m=" section (the callee will set the
2168 // port to 0 due to offer_to_receive_video = 0).
Florent Castelli15a38de2022-04-06 00:38:21 +02002169 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002170 PeerConnectionInterface::RTCOfferAnswerOptions options;
2171 options.offer_to_receive_video = 0;
2172 callee()->SetOfferAnswerOptions(options);
2173 } else {
2174 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002175 callee()
2176 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2177 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002178 });
2179 }
deadbeef1dcb1642017-03-29 21:08:16 -07002180 caller()->CreateAndSetAndSignalOffer();
2181 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2182 // Sanity check that video "m=" section was actually rejected.
2183 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2184 callee()->pc()->local_description()->description());
2185 ASSERT_NE(nullptr, answer_video_content);
2186 ASSERT_TRUE(answer_video_content->rejected);
2187
2188 // Enable video and do negotiation again, making sure video is received
2189 // end-to-end, also adding media stream to callee.
Florent Castelli15a38de2022-04-06 00:38:21 +02002190 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002191 PeerConnectionInterface::RTCOfferAnswerOptions options;
2192 options.offer_to_receive_video = 1;
2193 callee()->SetOfferAnswerOptions(options);
2194 } else {
2195 // The caller's transceiver is stopped, so we need to add another track.
2196 auto caller_transceiver =
2197 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002198 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002199 caller()->AddVideoTrack();
2200 }
2201 callee()->AddVideoTrack();
2202 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07002203 caller()->CreateAndSetAndSignalOffer();
2204 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002205
deadbeef1dcb1642017-03-29 21:08:16 -07002206 // Verify the caller receives frames from the newly added stream, and the
2207 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002208 MediaExpectations media_expectations;
2209 media_expectations.CalleeExpectsSomeAudio();
2210 media_expectations.ExpectBidirectionalVideo();
2211 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002212}
2213
deadbeef1dcb1642017-03-29 21:08:16 -07002214// This tests that if we negotiate after calling CreateSender but before we
2215// have a track, then set a track later, frames from the newly-set track are
2216// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002217TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07002218 MediaFlowsAfterEarlyWarmupWithCreateSender) {
2219 ASSERT_TRUE(CreatePeerConnectionWrappers());
2220 ConnectFakeSignaling();
2221 auto caller_audio_sender =
2222 caller()->pc()->CreateSender("audio", "caller_stream");
2223 auto caller_video_sender =
2224 caller()->pc()->CreateSender("video", "caller_stream");
2225 auto callee_audio_sender =
2226 callee()->pc()->CreateSender("audio", "callee_stream");
2227 auto callee_video_sender =
2228 callee()->pc()->CreateSender("video", "callee_stream");
2229 caller()->CreateAndSetAndSignalOffer();
2230 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2231 // Wait for ICE to complete, without any tracks being set.
2232 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2233 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2234 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2235 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2236 // Now set the tracks, and expect frames to immediately start flowing.
Niels Möllerafb246b2022-04-20 14:26:50 +02002237 EXPECT_TRUE(
2238 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2239 EXPECT_TRUE(
2240 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2241 EXPECT_TRUE(
2242 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2243 EXPECT_TRUE(
2244 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002245 MediaExpectations media_expectations;
2246 media_expectations.ExpectBidirectionalAudioAndVideo();
2247 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2248}
2249
2250// This tests that if we negotiate after calling AddTransceiver but before we
2251// have a track, then set a track later, frames from the newly-set tracks are
2252// received end-to-end.
2253TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2254 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2255 ASSERT_TRUE(CreatePeerConnectionWrappers());
2256 ConnectFakeSignaling();
2257 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2258 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2259 auto caller_audio_sender = audio_result.MoveValue()->sender();
2260 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2261 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2262 auto caller_video_sender = video_result.MoveValue()->sender();
2263 callee()->SetRemoteOfferHandler([this] {
2264 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02002265 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002266 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002267 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002268 RtpTransceiverDirection::kSendRecv);
2269 });
2270 caller()->CreateAndSetAndSignalOffer();
2271 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2272 // Wait for ICE to complete, without any tracks being set.
2273 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2274 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2275 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2276 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2277 // Now set the tracks, and expect frames to immediately start flowing.
2278 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2279 auto callee_video_sender = callee()->pc()->GetSenders()[1];
Niels Möllerafb246b2022-04-20 14:26:50 +02002280 ASSERT_TRUE(
2281 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2282 ASSERT_TRUE(
2283 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2284 ASSERT_TRUE(
2285 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2286 ASSERT_TRUE(
2287 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002288 MediaExpectations media_expectations;
2289 media_expectations.ExpectBidirectionalAudioAndVideo();
2290 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002291}
2292
2293// This test verifies that a remote video track can be added via AddStream,
2294// and sent end-to-end. For this particular test, it's simply echoed back
2295// from the caller to the callee, rather than being forwarded to a third
2296// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002297TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07002298 ASSERT_TRUE(CreatePeerConnectionWrappers());
2299 ConnectFakeSignaling();
2300 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08002301 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002302 caller()->CreateAndSetAndSignalOffer();
2303 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002304 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07002305
2306 // Echo the stream back, and do a new offer/anwer (initiated by callee this
2307 // time).
2308 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2309 callee()->CreateAndSetAndSignalOffer();
2310 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2311
Seth Hampson2f0d7022018-02-20 11:54:42 -08002312 MediaExpectations media_expectations;
2313 media_expectations.ExpectBidirectionalVideo();
2314 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002315}
2316
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002317#if !defined(THREAD_SANITIZER)
2318// This test provokes TSAN errors. bugs.webrtc.org/11282
2319
deadbeef1dcb1642017-03-29 21:08:16 -07002320// Test that we achieve the expected end-to-end connection time, using a
2321// fake clock and simulated latency on the media and signaling paths.
2322// We use a TURN<->TURN connection because this is usually the quickest to
2323// set up initially, especially when we're confident the connection will work
2324// and can start sending media before we get a STUN response.
2325//
2326// With various optimizations enabled, here are the network delays we expect to
2327// be on the critical path:
2328// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2329// signaling answer (with DTLS fingerprint).
2330// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2331// using TURN<->TURN pair, and DTLS exchange is 4 packets,
2332// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01002333TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2334 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07002335 static constexpr int media_hop_delay_ms = 50;
2336 static constexpr int signaling_trip_delay_ms = 500;
2337 // For explanation of these values, see comment above.
2338 static constexpr int required_media_hops = 9;
2339 static constexpr int required_signaling_trips = 2;
2340 // For internal delays (such as posting an event asychronously).
2341 static constexpr int allowed_internal_delay_ms = 20;
2342 static constexpr int total_connection_time_ms =
2343 media_hop_delay_ms * required_media_hops +
2344 signaling_trip_delay_ms * required_signaling_trips +
2345 allowed_internal_delay_ms;
2346
2347 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2348 3478};
2349 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2350 0};
2351 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2352 3478};
2353 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2354 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002355 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2356 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002357
Seth Hampsonaed71642018-06-11 07:41:32 -07002358 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2359 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07002360 // Bypass permission check on received packets so media can be sent before
2361 // the candidate is signaled.
Danil Chapovalov2aaef452022-08-12 15:55:11 +02002362 SendTask(network_thread(), [turn_server_1] {
Seth Hampsonaed71642018-06-11 07:41:32 -07002363 turn_server_1->set_enable_permission_checks(false);
2364 });
Danil Chapovalov2aaef452022-08-12 15:55:11 +02002365 SendTask(network_thread(), [turn_server_2] {
Seth Hampsonaed71642018-06-11 07:41:32 -07002366 turn_server_2->set_enable_permission_checks(false);
2367 });
deadbeef1dcb1642017-03-29 21:08:16 -07002368
2369 PeerConnectionInterface::RTCConfiguration client_1_config;
2370 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2371 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2372 ice_server_1.username = "test";
2373 ice_server_1.password = "test";
2374 client_1_config.servers.push_back(ice_server_1);
2375 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2376 client_1_config.presume_writable_when_fully_relayed = true;
2377
2378 PeerConnectionInterface::RTCConfiguration client_2_config;
2379 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2380 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2381 ice_server_2.username = "test";
2382 ice_server_2.password = "test";
2383 client_2_config.servers.push_back(ice_server_2);
2384 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2385 client_2_config.presume_writable_when_fully_relayed = true;
2386
2387 ASSERT_TRUE(
2388 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2389 // Set up the simulated delays.
2390 SetSignalingDelayMs(signaling_trip_delay_ms);
2391 ConnectFakeSignaling();
2392 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2393 virtual_socket_server()->UpdateDelayDistribution();
2394
2395 // Set "offer to receive audio/video" without adding any tracks, so we just
2396 // set up ICE/DTLS with no media.
2397 PeerConnectionInterface::RTCOfferAnswerOptions options;
2398 options.offer_to_receive_audio = 1;
2399 options.offer_to_receive_video = 1;
2400 caller()->SetOfferAnswerOptions(options);
2401 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07002402 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01002403 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002404 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2405 // If this is not done a DCHECK can be hit in ports.cc, because a large
2406 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07002407 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07002408}
2409
Philipp Hancke1fe14f22022-06-17 11:34:31 +02002410TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2411 OnIceCandidateFlushesGetStatsCache) {
2412 ASSERT_TRUE(CreatePeerConnectionWrappers());
2413 ConnectFakeSignaling();
2414 caller()->AddAudioTrack();
2415
2416 // Call getStats, assert there are no candidates.
2417 rtc::scoped_refptr<const webrtc::RTCStatsReport> first_report =
2418 caller()->NewGetStats();
2419 ASSERT_TRUE(first_report);
2420 auto first_candidate_stats =
2421 first_report->GetStatsOfType<webrtc::RTCLocalIceCandidateStats>();
2422 ASSERT_EQ(first_candidate_stats.size(), 0u);
2423
Philipp Hanckea09b9212022-06-22 07:41:22 +02002424 // Create an offer at the caller and set it as remote description on the
2425 // callee.
Philipp Hancke1fe14f22022-06-17 11:34:31 +02002426 caller()->CreateAndSetAndSignalOffer();
Philipp Hancke1fe14f22022-06-17 11:34:31 +02002427 // Call getStats again, assert there are candidates now.
2428 rtc::scoped_refptr<const webrtc::RTCStatsReport> second_report =
2429 caller()->NewGetStats();
2430 ASSERT_TRUE(second_report);
2431 auto second_candidate_stats =
2432 second_report->GetStatsOfType<webrtc::RTCLocalIceCandidateStats>();
2433 ASSERT_NE(second_candidate_stats.size(), 0u);
2434
2435 // The fake clock ensures that no time has passed so the cache must have been
2436 // explicitly invalidated.
2437 EXPECT_EQ(first_report->timestamp_us(), second_report->timestamp_us());
2438}
2439
Philipp Hanckea09b9212022-06-22 07:41:22 +02002440TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2441 AddIceCandidateFlushesGetStatsCache) {
2442 ASSERT_TRUE(CreatePeerConnectionWrappers());
2443 ConnectFakeSignalingForSdpOnly();
2444 caller()->AddAudioTrack();
2445
2446 // Start candidate gathering and wait for it to complete. Candidates are not
2447 // signalled.
2448 caller()->CreateAndSetAndSignalOffer();
2449 ASSERT_TRUE_SIMULATED_WAIT(caller()->IceGatheringStateComplete(),
2450 kDefaultTimeout, FakeClock());
2451
2452 // Call getStats, assert there are no candidates.
2453 rtc::scoped_refptr<const webrtc::RTCStatsReport> first_report =
2454 caller()->NewGetStats();
2455 ASSERT_TRUE(first_report);
2456 auto first_candidate_stats =
2457 first_report->GetStatsOfType<webrtc::RTCRemoteIceCandidateStats>();
2458 ASSERT_EQ(first_candidate_stats.size(), 0u);
2459
2460 // Add a "fake" candidate.
2461 absl::optional<RTCError> result;
2462 caller()->pc()->AddIceCandidate(
2463 absl::WrapUnique(webrtc::CreateIceCandidate(
2464 "", 0,
2465 "candidate:2214029314 1 udp 2122260223 127.0.0.1 49152 typ host",
2466 nullptr)),
2467 [&result](RTCError r) { result = r; });
2468 ASSERT_TRUE_WAIT(result.has_value(), kDefaultTimeout);
2469 ASSERT_TRUE(result.value().ok());
2470
2471 // Call getStats again, assert there is a remote candidate now.
2472 rtc::scoped_refptr<const webrtc::RTCStatsReport> second_report =
2473 caller()->NewGetStats();
2474 ASSERT_TRUE(second_report);
2475 auto second_candidate_stats =
2476 second_report->GetStatsOfType<webrtc::RTCRemoteIceCandidateStats>();
2477 ASSERT_EQ(second_candidate_stats.size(), 1u);
2478
2479 // The fake clock ensures that no time has passed so the cache must have been
2480 // explicitly invalidated.
2481 EXPECT_EQ(first_report->timestamp_us(), second_report->timestamp_us());
2482}
2483
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002484#endif // !defined(THREAD_SANITIZER)
2485
Jonas Orelandbdcee282017-10-10 14:01:40 +02002486// Verify that a TurnCustomizer passed in through RTCConfiguration
2487// is actually used by the underlying TURN candidate pair.
2488// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002489TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02002490 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2491 3478};
2492 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2493 0};
2494 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2495 3478};
2496 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2497 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002498 CreateTurnServer(turn_server_1_internal_address,
2499 turn_server_1_external_address);
2500 CreateTurnServer(turn_server_2_internal_address,
2501 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002502
2503 PeerConnectionInterface::RTCConfiguration client_1_config;
2504 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2505 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2506 ice_server_1.username = "test";
2507 ice_server_1.password = "test";
2508 client_1_config.servers.push_back(ice_server_1);
2509 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002510 auto* customizer1 = CreateTurnCustomizer();
2511 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002512
2513 PeerConnectionInterface::RTCConfiguration client_2_config;
2514 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2515 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2516 ice_server_2.username = "test";
2517 ice_server_2.password = "test";
2518 client_2_config.servers.push_back(ice_server_2);
2519 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002520 auto* customizer2 = CreateTurnCustomizer();
2521 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002522
2523 ASSERT_TRUE(
2524 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2525 ConnectFakeSignaling();
2526
2527 // Set "offer to receive audio/video" without adding any tracks, so we just
2528 // set up ICE/DTLS with no media.
2529 PeerConnectionInterface::RTCOfferAnswerOptions options;
2530 options.offer_to_receive_audio = 1;
2531 options.offer_to_receive_video = 1;
2532 caller()->SetOfferAnswerOptions(options);
2533 caller()->CreateAndSetAndSignalOffer();
2534 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2535
Seth Hampsonaed71642018-06-11 07:41:32 -07002536 ExpectTurnCustomizerCountersIncremented(customizer1);
2537 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002538}
2539
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002540// Verifies that you can use TCP instead of UDP to connect to a TURN server and
2541// send media between the caller and the callee.
2542TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2543 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2544 3478};
2545 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2546
2547 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07002548 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2549 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002550
2551 webrtc::PeerConnectionInterface::IceServer ice_server;
2552 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2553 ice_server.username = "test";
2554 ice_server.password = "test";
2555
2556 PeerConnectionInterface::RTCConfiguration client_1_config;
2557 client_1_config.servers.push_back(ice_server);
2558 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2559
2560 PeerConnectionInterface::RTCConfiguration client_2_config;
2561 client_2_config.servers.push_back(ice_server);
2562 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2563
2564 ASSERT_TRUE(
2565 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2566
2567 // Do normal offer/answer and wait for ICE to complete.
2568 ConnectFakeSignaling();
2569 caller()->AddAudioVideoTracks();
2570 callee()->AddAudioVideoTracks();
2571 caller()->CreateAndSetAndSignalOffer();
2572 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2573 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2574 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2575
2576 MediaExpectations media_expectations;
2577 media_expectations.ExpectBidirectionalAudioAndVideo();
2578 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2579}
2580
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002581// Verify that a SSLCertificateVerifier passed in through
2582// PeerConnectionDependencies is actually used by the underlying SSL
2583// implementation to determine whether a certificate presented by the TURN
2584// server is accepted by the client. Note that openssladapter_unittest.cc
2585// contains more detailed, lower-level tests.
2586TEST_P(PeerConnectionIntegrationTest,
2587 SSLCertificateVerifierUsedForTurnConnections) {
2588 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2589 3478};
2590 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2591
2592 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2593 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002594 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2595 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002596
2597 webrtc::PeerConnectionInterface::IceServer ice_server;
2598 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2599 ice_server.username = "test";
2600 ice_server.password = "test";
2601
2602 PeerConnectionInterface::RTCConfiguration client_1_config;
2603 client_1_config.servers.push_back(ice_server);
2604 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2605
2606 PeerConnectionInterface::RTCConfiguration client_2_config;
2607 client_2_config.servers.push_back(ice_server);
2608 // Setting the type to kRelay forces the connection to go through a TURN
2609 // server.
2610 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2611
2612 // Get a copy to the pointer so we can verify calls later.
2613 rtc::TestCertificateVerifier* client_1_cert_verifier =
2614 new rtc::TestCertificateVerifier();
2615 client_1_cert_verifier->verify_certificate_ = true;
2616 rtc::TestCertificateVerifier* client_2_cert_verifier =
2617 new rtc::TestCertificateVerifier();
2618 client_2_cert_verifier->verify_certificate_ = true;
2619
2620 // Create the dependencies with the test certificate verifier.
2621 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2622 client_1_deps.tls_cert_verifier =
2623 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2624 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2625 client_2_deps.tls_cert_verifier =
2626 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2627
2628 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2629 client_1_config, std::move(client_1_deps), client_2_config,
2630 std::move(client_2_deps)));
2631 ConnectFakeSignaling();
2632
2633 // Set "offer to receive audio/video" without adding any tracks, so we just
2634 // set up ICE/DTLS with no media.
2635 PeerConnectionInterface::RTCOfferAnswerOptions options;
2636 options.offer_to_receive_audio = 1;
2637 options.offer_to_receive_video = 1;
2638 caller()->SetOfferAnswerOptions(options);
2639 caller()->CreateAndSetAndSignalOffer();
2640 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2641
2642 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2643 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002644}
2645
Qingsi Wang25ec8882019-11-15 12:33:05 -08002646// Test that the injected ICE transport factory is used to create ICE transports
2647// for WebRTC connections.
2648TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2649 PeerConnectionInterface::RTCConfiguration default_config;
2650 PeerConnectionDependencies dependencies(nullptr);
2651 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2652 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2653 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02002654 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2655 std::move(dependencies), nullptr,
2656 /*reset_encoder_factory=*/false,
2657 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08002658 ASSERT_TRUE(wrapper);
2659 wrapper->CreateDataChannel();
Tommi87f70902021-04-27 14:43:08 +02002660 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02002661 wrapper->pc()->SetLocalDescription(observer.get(),
Qingsi Wang25ec8882019-11-15 12:33:05 -08002662 wrapper->CreateOfferAndWait().release());
2663}
2664
deadbeefc964d0b2017-04-03 10:03:35 -07002665// Test that audio and video flow end-to-end when codec names don't use the
2666// expected casing, given that they're supposed to be case insensitive. To test
2667// this, all but one codec is removed from each media description, and its
2668// casing is changed.
2669//
2670// In the past, this has regressed and caused crashes/black video, due to the
2671// fact that code at some layers was doing case-insensitive comparisons and
2672// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002673TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07002674 ASSERT_TRUE(CreatePeerConnectionWrappers());
2675 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002676 caller()->AddAudioVideoTracks();
2677 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07002678
2679 // Remove all but one audio/video codec (opus and VP8), and change the
2680 // casing of the caller's generated offer.
2681 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2682 cricket::AudioContentDescription* audio =
2683 GetFirstAudioContentDescription(description);
2684 ASSERT_NE(nullptr, audio);
2685 auto audio_codecs = audio->codecs();
2686 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2687 [](const cricket::AudioCodec& codec) {
2688 return codec.name != "opus";
2689 }),
2690 audio_codecs.end());
2691 ASSERT_EQ(1u, audio_codecs.size());
2692 audio_codecs[0].name = "OpUs";
2693 audio->set_codecs(audio_codecs);
2694
2695 cricket::VideoContentDescription* video =
2696 GetFirstVideoContentDescription(description);
2697 ASSERT_NE(nullptr, video);
2698 auto video_codecs = video->codecs();
2699 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2700 [](const cricket::VideoCodec& codec) {
2701 return codec.name != "VP8";
2702 }),
2703 video_codecs.end());
2704 ASSERT_EQ(1u, video_codecs.size());
2705 video_codecs[0].name = "vP8";
2706 video->set_codecs(video_codecs);
2707 });
2708
2709 caller()->CreateAndSetAndSignalOffer();
2710 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2711
2712 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002713 MediaExpectations media_expectations;
2714 media_expectations.ExpectBidirectionalAudioAndVideo();
2715 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07002716}
2717
Jonas Oreland49ac5952018-09-26 16:04:32 +02002718TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07002719 ASSERT_TRUE(CreatePeerConnectionWrappers());
2720 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002721 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07002722 caller()->CreateAndSetAndSignalOffer();
2723 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07002724 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002725 MediaExpectations media_expectations;
2726 media_expectations.CalleeExpectsSomeAudio(1);
2727 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02002728 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07002729 auto receiver = callee()->pc()->GetReceivers()[0];
2730 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002731 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07002732 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2733 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02002734 sources[0].source_id());
2735 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2736}
2737
2738TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2739 ASSERT_TRUE(CreatePeerConnectionWrappers());
2740 ConnectFakeSignaling();
2741 caller()->AddVideoTrack();
2742 caller()->CreateAndSetAndSignalOffer();
2743 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2744 // Wait for one video frame to be received by the callee.
2745 MediaExpectations media_expectations;
2746 media_expectations.CalleeExpectsSomeVideo(1);
2747 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2748 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2749 auto receiver = callee()->pc()->GetReceivers()[0];
2750 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2751 auto sources = receiver->GetSources();
2752 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02002753 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002754 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2755 sources[0].source_id());
2756 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07002757}
2758
deadbeef2f425aa2017-04-14 10:41:32 -07002759// Test that if a track is removed and added again with a different stream ID,
2760// the new stream ID is successfully communicated in SDP and media continues to
2761// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002762// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2763// it will not reuse a transceiver that has already been sending. After creating
2764// a new transceiver it tries to create an offer with two senders of the same
2765// track ids and it fails.
2766TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07002767 ASSERT_TRUE(CreatePeerConnectionWrappers());
2768 ConnectFakeSignaling();
2769
deadbeef2f425aa2017-04-14 10:41:32 -07002770 // Add track using stream 1, do offer/answer.
2771 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2772 caller()->CreateLocalAudioTrack();
2773 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07002774 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07002775 caller()->CreateAndSetAndSignalOffer();
2776 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002777 {
2778 MediaExpectations media_expectations;
2779 media_expectations.CalleeExpectsSomeAudio(1);
2780 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2781 }
deadbeef2f425aa2017-04-14 10:41:32 -07002782 // Remove the sender, and create a new one with the new stream.
Harald Alvestrand93dd7632022-01-19 12:28:45 +00002783 caller()->pc()->RemoveTrackOrError(sender);
Steve Antond78323f2018-07-11 11:13:44 -07002784 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07002785 caller()->CreateAndSetAndSignalOffer();
2786 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2787 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002788 {
2789 MediaExpectations media_expectations;
2790 media_expectations.CalleeExpectsSomeAudio();
2791 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2792 }
deadbeef2f425aa2017-04-14 10:41:32 -07002793}
2794
Seth Hampson2f0d7022018-02-20 11:54:42 -08002795TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02002796 ASSERT_TRUE(CreatePeerConnectionWrappers());
2797 ConnectFakeSignaling();
2798
Mirko Bonadei317a1f02019-09-17 17:06:18 +02002799 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002800 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
Ali Tofighb7821ce2022-07-12 16:08:13 +02002801 ON_CALL(*output, Write(::testing::A<absl::string_view>()))
Björn Terelius63299a32022-07-05 10:58:52 +02002802 .WillByDefault(::testing::Return(true));
Ali Tofighb7821ce2022-07-12 16:08:13 +02002803 EXPECT_CALL(*output, Write(::testing::A<absl::string_view>()))
Björn Terelius63299a32022-07-05 10:58:52 +02002804 .Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01002805 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2806 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02002807
Steve Anton15324772018-01-16 10:26:49 -08002808 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02002809 caller()->CreateAndSetAndSignalOffer();
2810 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2811}
2812
Steve Antonede9ca52017-10-16 13:04:27 -07002813// Test that if candidates are only signaled by applying full session
2814// descriptions (instead of using AddIceCandidate), the peers can connect to
2815// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002816TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07002817 ASSERT_TRUE(CreatePeerConnectionWrappers());
2818 // Each side will signal the session descriptions but not candidates.
2819 ConnectFakeSignalingForSdpOnly();
2820
2821 // Add audio video track and exchange the initial offer/answer with media
2822 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08002823 caller()->AddAudioVideoTracks();
2824 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002825 caller()->CreateAndSetAndSignalOffer();
2826
2827 // Wait for all candidates to be gathered on both the caller and callee.
2828 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2829 caller()->ice_gathering_state(), kDefaultTimeout);
2830 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2831 callee()->ice_gathering_state(), kDefaultTimeout);
2832
2833 // The candidates will now be included in the session description, so
2834 // signaling them will start the ICE connection.
2835 caller()->CreateAndSetAndSignalOffer();
2836 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2837
2838 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002839 MediaExpectations media_expectations;
2840 media_expectations.ExpectBidirectionalAudioAndVideo();
2841 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07002842}
2843
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002844#if !defined(THREAD_SANITIZER)
2845// These tests provokes TSAN errors. See bugs.webrtc.org/11305.
2846
henrika5f6bf242017-11-01 11:06:56 +01002847// Test that SetAudioPlayout can be used to disable audio playout from the
2848// start, then later enable it. This may be useful, for example, if the caller
2849// needs to play a local ringtone until some event occurs, after which it
2850// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002851TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01002852 ASSERT_TRUE(CreatePeerConnectionWrappers());
2853 ConnectFakeSignaling();
2854
2855 // Set up audio-only call where audio playout is disabled on caller's side.
2856 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08002857 caller()->AddAudioTrack();
2858 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002859 caller()->CreateAndSetAndSignalOffer();
2860 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2861
2862 // Pump messages for a second.
2863 WAIT(false, 1000);
2864 // Since audio playout is disabled, the caller shouldn't have received
2865 // anything (at the playout level, at least).
2866 EXPECT_EQ(0, caller()->audio_frames_received());
2867 // As a sanity check, make sure the callee (for which playout isn't disabled)
2868 // did still see frames on its audio level.
2869 ASSERT_GT(callee()->audio_frames_received(), 0);
2870
2871 // Enable playout again, and ensure audio starts flowing.
2872 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002873 MediaExpectations media_expectations;
2874 media_expectations.ExpectBidirectionalAudio();
2875 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01002876}
2877
Harald Alvestrand39993842021-02-17 09:05:31 +00002878double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
henrika5f6bf242017-11-01 11:06:56 +01002879 auto report = pc->NewGetStats();
Henrik Boström323e9df2022-12-24 10:33:39 +01002880 auto inbound_rtps =
2881 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
2882 RTC_CHECK(!inbound_rtps.empty());
2883 auto* inbound_rtp = inbound_rtps[0];
2884 if (!inbound_rtp->total_audio_energy.is_defined()) {
henrika5f6bf242017-11-01 11:06:56 +01002885 return 0.0;
2886 }
Henrik Boström323e9df2022-12-24 10:33:39 +01002887 return *inbound_rtp->total_audio_energy;
henrika5f6bf242017-11-01 11:06:56 +01002888}
2889
2890// Test that if audio playout is disabled via the SetAudioPlayout() method, then
2891// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002892TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01002893 DisableAudioPlayoutStillGeneratesAudioStats) {
2894 ASSERT_TRUE(CreatePeerConnectionWrappers());
2895 ConnectFakeSignaling();
2896
2897 // Set up audio-only call where playout is disabled but audio-processing is
2898 // still active.
Steve Anton15324772018-01-16 10:26:49 -08002899 caller()->AddAudioTrack();
2900 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002901 caller()->pc()->SetAudioPlayout(false);
2902
2903 caller()->CreateAndSetAndSignalOffer();
2904 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2905
2906 // Wait for the callee to receive audio stats.
2907 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
2908}
2909
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002910#endif // !defined(THREAD_SANITIZER)
2911
henrika4f167df2017-11-01 14:45:55 +01002912// Test that SetAudioRecording can be used to disable audio recording from the
2913// start, then later enable it. This may be useful, for example, if the caller
2914// wants to ensure that no audio resources are active before a certain state
2915// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002916TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01002917 ASSERT_TRUE(CreatePeerConnectionWrappers());
2918 ConnectFakeSignaling();
2919
2920 // Set up audio-only call where audio recording is disabled on caller's side.
2921 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08002922 caller()->AddAudioTrack();
2923 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01002924 caller()->CreateAndSetAndSignalOffer();
2925 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2926
2927 // Pump messages for a second.
2928 WAIT(false, 1000);
2929 // Since caller has disabled audio recording, the callee shouldn't have
2930 // received anything.
2931 EXPECT_EQ(0, callee()->audio_frames_received());
2932 // As a sanity check, make sure the caller did still see frames on its
2933 // audio level since audio recording is enabled on the calle side.
2934 ASSERT_GT(caller()->audio_frames_received(), 0);
2935
2936 // Enable audio recording again, and ensure audio starts flowing.
2937 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002938 MediaExpectations media_expectations;
2939 media_expectations.ExpectBidirectionalAudio();
2940 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01002941}
2942
Qingsi Wang7685e862018-06-11 20:15:46 -07002943TEST_P(PeerConnectionIntegrationTest,
2944 IceEventsGeneratedAndLoggedInRtcEventLog) {
2945 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
2946 ConnectFakeSignaling();
2947 PeerConnectionInterface::RTCOfferAnswerOptions options;
2948 options.offer_to_receive_audio = 1;
2949 caller()->SetOfferAnswerOptions(options);
2950 caller()->CreateAndSetAndSignalOffer();
2951 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2952 ASSERT_NE(nullptr, caller()->event_log_factory());
2953 ASSERT_NE(nullptr, callee()->event_log_factory());
2954 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002955 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002956 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002957 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002958 ASSERT_NE(nullptr, caller_event_log);
2959 ASSERT_NE(nullptr, callee_event_log);
2960 int caller_ice_config_count = caller_event_log->GetEventCount(
2961 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2962 int caller_ice_event_count = caller_event_log->GetEventCount(
2963 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2964 int callee_ice_config_count = callee_event_log->GetEventCount(
2965 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2966 int callee_ice_event_count = callee_event_log->GetEventCount(
2967 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2968 EXPECT_LT(0, caller_ice_config_count);
2969 EXPECT_LT(0, caller_ice_event_count);
2970 EXPECT_LT(0, callee_ice_config_count);
2971 EXPECT_LT(0, callee_ice_event_count);
2972}
2973
Qingsi Wangc129c352019-04-18 10:41:58 -07002974TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07002975 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2976 3478};
2977 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2978
2979 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
2980
2981 webrtc::PeerConnectionInterface::IceServer ice_server;
2982 ice_server.urls.push_back("turn:88.88.88.0:3478");
2983 ice_server.username = "test";
2984 ice_server.password = "test";
2985
2986 PeerConnectionInterface::RTCConfiguration caller_config;
2987 caller_config.servers.push_back(ice_server);
2988 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
2989 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07002990 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07002991
2992 PeerConnectionInterface::RTCConfiguration callee_config;
2993 callee_config.servers.push_back(ice_server);
2994 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
2995 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07002996 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07002997
2998 ASSERT_TRUE(
2999 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3000
3001 // Do normal offer/answer and wait for ICE to complete.
3002 ConnectFakeSignaling();
3003 caller()->AddAudioVideoTracks();
3004 callee()->AddAudioVideoTracks();
3005 caller()->CreateAndSetAndSignalOffer();
3006 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3007 // Since we are doing continual gathering, the ICE transport does not reach
3008 // kIceGatheringComplete (see
3009 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
3010 // kIceConnectionComplete.
3011 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3012 caller()->ice_connection_state(), kDefaultTimeout);
3013 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3014 callee()->ice_connection_state(), kDefaultTimeout);
3015 // Note that we cannot use the metric
Artem Titovcfea2182021-08-10 01:22:31 +02003016 // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
Qingsi Wangc129c352019-04-18 10:41:58 -07003017 // metric is only populated when we reach kIceConnectionComplete in the
3018 // current implementation.
3019 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3020 caller()->last_candidate_gathered().type());
3021 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3022 callee()->last_candidate_gathered().type());
3023
3024 // Loosen the caller's candidate filter.
3025 caller_config = caller()->pc()->GetConfiguration();
3026 caller_config.type = webrtc::PeerConnectionInterface::kAll;
3027 caller()->pc()->SetConfiguration(caller_config);
3028 // We should have gathered a new host candidate.
3029 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3030 caller()->last_candidate_gathered().type(), kDefaultTimeout);
3031
3032 // Loosen the callee's candidate filter.
3033 callee_config = callee()->pc()->GetConfiguration();
3034 callee_config.type = webrtc::PeerConnectionInterface::kAll;
3035 callee()->pc()->SetConfiguration(callee_config);
3036 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3037 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02003038
3039 // Create an offer and verify that it does not contain an ICE restart (i.e new
3040 // ice credentials).
3041 std::string caller_ufrag_pre_offer = caller()
3042 ->pc()
3043 ->local_description()
3044 ->description()
3045 ->transport_infos()[0]
3046 .description.ice_ufrag;
3047 caller()->CreateAndSetAndSignalOffer();
3048 std::string caller_ufrag_post_offer = caller()
3049 ->pc()
3050 ->local_description()
3051 ->description()
3052 ->transport_infos()[0]
3053 .description.ice_ufrag;
3054 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07003055}
3056
Eldar Relloda13ea22019-06-01 12:23:43 +03003057TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03003058 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3059 3478};
3060 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3061
3062 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3063
3064 webrtc::PeerConnectionInterface::IceServer ice_server;
3065 ice_server.urls.push_back("turn:88.88.88.0:3478");
3066 ice_server.username = "test";
3067 ice_server.password = "123";
3068
3069 PeerConnectionInterface::RTCConfiguration caller_config;
3070 caller_config.servers.push_back(ice_server);
3071 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3072 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3073
3074 PeerConnectionInterface::RTCConfiguration callee_config;
3075 callee_config.servers.push_back(ice_server);
3076 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3077 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3078
3079 ASSERT_TRUE(
3080 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3081
3082 // Do normal offer/answer and wait for ICE to complete.
3083 ConnectFakeSignaling();
3084 caller()->AddAudioVideoTracks();
3085 callee()->AddAudioVideoTracks();
3086 caller()->CreateAndSetAndSignalOffer();
3087 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3088 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3089 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3090 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02003091 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03003092}
3093
Eldar Rellofa8019c2020-05-14 11:59:33 +03003094TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3095 webrtc::PeerConnectionInterface::IceServer ice_server;
3096 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3097 ice_server.username = "test";
3098 ice_server.password = "test";
3099
3100 PeerConnectionInterface::RTCConfiguration caller_config;
3101 caller_config.servers.push_back(ice_server);
3102 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3103 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3104
3105 PeerConnectionInterface::RTCConfiguration callee_config;
3106 callee_config.servers.push_back(ice_server);
3107 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3108 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3109
3110 ASSERT_TRUE(
3111 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3112
3113 // Do normal offer/answer and wait for ICE to complete.
3114 ConnectFakeSignaling();
3115 caller()->AddAudioVideoTracks();
3116 callee()->AddAudioVideoTracks();
3117 caller()->CreateAndSetAndSignalOffer();
3118 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3119 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3120 EXPECT_EQ(caller()->error_event().address, "");
3121}
3122
Eldar Rello5ab79e62019-10-09 18:29:44 +03003123TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3124 AudioKeepsFlowingAfterImplicitRollback) {
3125 PeerConnectionInterface::RTCConfiguration config;
3126 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3127 config.enable_implicit_rollback = true;
3128 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3129 ConnectFakeSignaling();
3130 caller()->AddAudioTrack();
3131 callee()->AddAudioTrack();
3132 caller()->CreateAndSetAndSignalOffer();
3133 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3134 MediaExpectations media_expectations;
3135 media_expectations.ExpectBidirectionalAudio();
3136 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3137 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
3138 caller()->AddVideoTrack();
3139 callee()->AddVideoTrack();
Tommi87f70902021-04-27 14:43:08 +02003140 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003141 callee()->pc()->SetLocalDescription(observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003142 callee()->CreateOfferAndWait().release());
3143 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3144 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
3145 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3146 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3147}
3148
3149TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3150 ImplicitRollbackVisitsStableState) {
3151 RTCConfiguration config;
3152 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3153 config.enable_implicit_rollback = true;
3154
3155 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3156
Tommi87f70902021-04-27 14:43:08 +02003157 auto sld_observer =
3158 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003159 callee()->pc()->SetLocalDescription(sld_observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003160 callee()->CreateOfferAndWait().release());
3161 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3162 EXPECT_EQ(sld_observer->error(), "");
3163
Tommi87f70902021-04-27 14:43:08 +02003164 auto srd_observer =
3165 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003166 callee()->pc()->SetRemoteDescription(
Niels Möllerafb246b2022-04-20 14:26:50 +02003167 srd_observer.get(), caller()->CreateOfferAndWait().release());
Eldar Rello5ab79e62019-10-09 18:29:44 +03003168 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3169 EXPECT_EQ(srd_observer->error(), "");
3170
3171 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3172 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3173 PeerConnectionInterface::kStable,
3174 PeerConnectionInterface::kHaveRemoteOffer));
3175}
3176
Eldar Rellobd9c33a2020-10-01 17:52:45 +03003177TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3178 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3179 ASSERT_TRUE(CreatePeerConnectionWrappers());
3180 ConnectFakeSignaling();
3181 caller()->AddVideoTrack();
3182 callee()->AddVideoTrack();
3183 auto munger = [](cricket::SessionDescription* desc) {
3184 cricket::VideoContentDescription* video =
3185 GetFirstVideoContentDescription(desc);
3186 auto codecs = video->codecs();
3187 for (auto&& codec : codecs) {
3188 if (codec.name == "H264") {
3189 std::string value;
3190 // The parameter is not supposed to be present in SDP by default.
3191 EXPECT_FALSE(
3192 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3193 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3194 std::string(""));
3195 }
3196 }
3197 video->set_codecs(codecs);
3198 };
3199 // Munge local offer for SLD.
3200 caller()->SetGeneratedSdpMunger(munger);
3201 // Munge remote answer for SRD.
3202 caller()->SetReceivedSdpMunger(munger);
3203 caller()->CreateAndSetAndSignalOffer();
3204 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3205 // Observe that after munging the parameter is present in generated SDP.
3206 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3207 cricket::VideoContentDescription* video =
3208 GetFirstVideoContentDescription(desc);
3209 for (auto&& codec : video->codecs()) {
3210 if (codec.name == "H264") {
3211 std::string value;
3212 EXPECT_TRUE(
3213 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3214 }
3215 }
3216 });
3217 caller()->CreateOfferAndWait();
3218}
3219
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003220TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00003221 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003222 PeerConnectionInterface::RTCConfiguration config;
3223 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3224 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3225 ConnectFakeSignaling();
3226 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3227
3228 caller()->CreateAndSetAndSignalOffer();
3229 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3230 int current_size = caller()->pc()->GetTransceivers().size();
3231 // Add more tracks until we get close to having issues.
3232 // Issues have been seen at:
3233 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003234 // - 16 tracks on android_arm_dbg (flaky)
3235 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003236 // Double the number of tracks
3237 for (int i = 0; i < current_size; i++) {
3238 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3239 }
3240 current_size = caller()->pc()->GetTransceivers().size();
3241 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3242 auto start_time_ms = rtc::TimeMillis();
3243 caller()->CreateAndSetAndSignalOffer();
3244 // We want to stop when the time exceeds one second.
3245 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3246 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3247 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3248 ASSERT_GT(1000, elapsed_time_ms)
3249 << "Audio transceivers: Negotiation took too long after "
3250 << current_size << " tracks added";
3251 }
3252}
3253
3254TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3255 RenegotiateManyVideoTransceivers) {
3256 PeerConnectionInterface::RTCConfiguration config;
3257 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3258 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3259 ConnectFakeSignaling();
3260 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3261
3262 caller()->CreateAndSetAndSignalOffer();
3263 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3264 int current_size = caller()->pc()->GetTransceivers().size();
3265 // Add more tracks until we get close to having issues.
3266 // Issues have been seen at:
3267 // - 96 on a Linux workstation
3268 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3269 // - 32 on android_arm64_rel and linux_dbg bots
Harald Alvestrand785e23b2021-03-15 21:26:27 +00003270 // - 16 on Android 64 (Nexus 5x)
3271 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003272 // Double the number of tracks
3273 for (int i = 0; i < current_size; i++) {
3274 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3275 }
3276 current_size = caller()->pc()->GetTransceivers().size();
3277 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3278 auto start_time_ms = rtc::TimeMillis();
3279 caller()->CreateAndSetAndSignalOffer();
3280 // We want to stop when the time exceeds one second.
3281 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3282 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3283 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3284 ASSERT_GT(1000, elapsed_time_ms)
3285 << "Video transceivers: Negotiation took too long after "
3286 << current_size << " tracks added";
3287 }
3288}
3289
Harald Alvestrand94324f22021-01-13 12:31:53 +00003290TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3291 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3292 PeerConnectionInterface::RTCConfiguration config;
3293 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3294 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3295 ConnectFakeSignaling();
3296 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003297 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003298 caller()->CreateAndSetAndSignalOffer();
3299 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3300 // Wait until we can see the audio flowing.
3301 MediaExpectations media_expectations;
3302 media_expectations.CalleeExpectsSomeAudio();
3303 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3304
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003305 // Get the baseline numbers for audio_packets and audio_delay
3306 // in both directions.
3307 caller()->StartWatchingDelayStats();
3308 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003309
3310 int current_size = caller()->pc()->GetTransceivers().size();
3311 // Add more tracks until we get close to having issues.
3312 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003313 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00003314 // Double the number of tracks
3315 for (int i = 0; i < current_size; i++) {
3316 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3317 }
3318 current_size = caller()->pc()->GetTransceivers().size();
3319 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3320 auto start_time_ms = rtc::TimeMillis();
3321 caller()->CreateAndSetAndSignalOffer();
3322 // We want to stop when the time exceeds one second.
3323 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3324 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3325 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3326 // This is a guard against the test using excessive amounts of time.
3327 ASSERT_GT(5000, elapsed_time_ms)
3328 << "Video transceivers: Negotiation took too long after "
3329 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003330 caller()->UpdateDelayStats("caller reception", current_size);
3331 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00003332 }
3333}
3334
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003335INSTANTIATE_TEST_SUITE_P(
3336 PeerConnectionIntegrationTest,
3337 PeerConnectionIntegrationTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003338 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003339 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3340 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3341 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Steve Antond3679212018-01-17 17:41:02 -08003342
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003343INSTANTIATE_TEST_SUITE_P(
3344 PeerConnectionIntegrationTest,
3345 PeerConnectionIntegrationTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02003346 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003347 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3348 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3349 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Yves Gerey100fe632020-01-17 19:15:53 +01003350
Steve Anton74255ff2018-01-24 18:32:57 -08003351// Tests that verify interoperability between Plan B and Unified Plan
3352// PeerConnections.
3353class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003354 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08003355 public ::testing::WithParamInterface<
3356 std::tuple<SdpSemantics, SdpSemantics>> {
3357 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003358 // Setting the SdpSemantics for the base test to kDefault does not matter
3359 // because we specify not to use the test semantics when creating
Harald Alvestrand39993842021-02-17 09:05:31 +00003360 // PeerConnectionIntegrationWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08003361 PeerConnectionIntegrationInteropTest()
Florent Castelli15a38de2022-04-06 00:38:21 +02003362 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED),
Seth Hampson2f0d7022018-02-20 11:54:42 -08003363 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08003364 callee_semantics_(std::get<1>(GetParam())) {}
3365
3366 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07003367 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3368 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08003369 }
3370
3371 const SdpSemantics caller_semantics_;
3372 const SdpSemantics callee_semantics_;
3373};
3374
3375TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3376 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3377 ConnectFakeSignaling();
3378
3379 caller()->CreateAndSetAndSignalOffer();
3380 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3381}
3382
3383TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3384 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3385 ConnectFakeSignaling();
3386 auto audio_sender = caller()->AddAudioTrack();
3387
3388 caller()->CreateAndSetAndSignalOffer();
3389 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3390
3391 // Verify that one audio receiver has been created on the remote and that it
3392 // has the same track ID as the sending track.
3393 auto receivers = callee()->pc()->GetReceivers();
3394 ASSERT_EQ(1u, receivers.size());
3395 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3396 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3397
Seth Hampson2f0d7022018-02-20 11:54:42 -08003398 MediaExpectations media_expectations;
3399 media_expectations.CalleeExpectsSomeAudio();
3400 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003401}
3402
3403TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3404 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3405 ConnectFakeSignaling();
3406 auto video_sender = caller()->AddVideoTrack();
3407 auto audio_sender = caller()->AddAudioTrack();
3408
3409 caller()->CreateAndSetAndSignalOffer();
3410 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3411
3412 // Verify that one audio and one video receiver have been created on the
3413 // remote and that they have the same track IDs as the sending tracks.
3414 auto audio_receivers =
3415 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3416 ASSERT_EQ(1u, audio_receivers.size());
3417 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3418 auto video_receivers =
3419 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3420 ASSERT_EQ(1u, video_receivers.size());
3421 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3422
Seth Hampson2f0d7022018-02-20 11:54:42 -08003423 MediaExpectations media_expectations;
3424 media_expectations.CalleeExpectsSomeAudioAndVideo();
3425 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003426}
3427
3428TEST_P(PeerConnectionIntegrationInteropTest,
3429 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3430 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3431 ConnectFakeSignaling();
3432 caller()->AddAudioVideoTracks();
3433 callee()->AddAudioVideoTracks();
3434
3435 caller()->CreateAndSetAndSignalOffer();
3436 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3437
Seth Hampson2f0d7022018-02-20 11:54:42 -08003438 MediaExpectations media_expectations;
3439 media_expectations.ExpectBidirectionalAudioAndVideo();
3440 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003441}
3442
3443TEST_P(PeerConnectionIntegrationInteropTest,
3444 ReverseRolesOneAudioLocalToOneVideoRemote) {
3445 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3446 ConnectFakeSignaling();
3447 caller()->AddAudioTrack();
3448 callee()->AddVideoTrack();
3449
3450 caller()->CreateAndSetAndSignalOffer();
3451 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3452
3453 // Verify that only the audio track has been negotiated.
3454 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3455 // Might also check that the callee's NegotiationNeeded flag is set.
3456
3457 // Reverse roles.
3458 callee()->CreateAndSetAndSignalOffer();
3459 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3460
Seth Hampson2f0d7022018-02-20 11:54:42 -08003461 MediaExpectations media_expectations;
3462 media_expectations.CallerExpectsSomeVideo();
3463 media_expectations.CalleeExpectsSomeAudio();
3464 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003465}
3466
Taylor Brandstetter1c7ecef2021-08-11 12:38:35 -07003467TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3468 ASSERT_TRUE(CreatePeerConnectionWrappers());
3469 ConnectFakeSignaling();
3470 caller()->AddAudioVideoTracks();
3471 caller()->CreateAndSetAndSignalOffer();
3472 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3473 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3474 caller()->ExpectCandidates(0);
3475 callee()->ExpectCandidates(0);
3476 caller()->AddAudioTrack();
3477 caller()->CreateAndSetAndSignalOffer();
3478 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3479}
3480
Harald Alvestrand35ba0c52022-05-05 07:37:41 +00003481TEST_P(PeerConnectionIntegrationTest, MediaCallWithoutMediaEngineFails) {
3482 ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
3483 // AddTrack should fail.
3484 EXPECT_FALSE(
3485 caller()->pc()->AddTrack(caller()->CreateLocalAudioTrack(), {}).ok());
3486}
3487
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003488INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07003489 PeerConnectionIntegrationTest,
3490 PeerConnectionIntegrationInteropTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003491 Values(std::make_tuple(SdpSemantics::kPlanB_DEPRECATED,
3492 SdpSemantics::kUnifiedPlan),
3493 std::make_tuple(SdpSemantics::kUnifiedPlan,
3494 SdpSemantics::kPlanB_DEPRECATED)));
Steve Antonba42e992018-04-09 14:10:01 -07003495
3496// Test that if the Unified Plan side offers two video tracks then the Plan B
3497// side will only see the first one and ignore the second.
3498TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07003499 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
Florent Castelli15a38de2022-04-06 00:38:21 +02003500 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB_DEPRECATED));
Steve Anton74255ff2018-01-24 18:32:57 -08003501 ConnectFakeSignaling();
3502 auto first_sender = caller()->AddVideoTrack();
3503 caller()->AddVideoTrack();
3504
3505 caller()->CreateAndSetAndSignalOffer();
3506 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3507
3508 // Verify that there is only one receiver and it corresponds to the first
3509 // added track.
3510 auto receivers = callee()->pc()->GetReceivers();
3511 ASSERT_EQ(1u, receivers.size());
3512 EXPECT_TRUE(receivers[0]->track()->enabled());
3513 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3514
Seth Hampson2f0d7022018-02-20 11:54:42 -08003515 MediaExpectations media_expectations;
3516 media_expectations.CalleeExpectsSomeVideo();
3517 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003518}
3519
Steve Anton2bed3972019-01-04 17:04:30 -08003520// Test that if the initial offer tagged BUNDLE section is rejected due to its
3521// associated RtpTransceiver being stopped and another transceiver is added,
3522// then renegotiation causes the callee to receive the new video track without
3523// error.
3524// This is a regression test for bugs.webrtc.org/9954
3525TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3526 ReOfferWithStoppedBundleTaggedTransceiver) {
3527 RTCConfiguration config;
3528 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3529 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3530 ConnectFakeSignaling();
3531 auto audio_transceiver_or_error =
3532 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3533 ASSERT_TRUE(audio_transceiver_or_error.ok());
3534 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3535
3536 caller()->CreateAndSetAndSignalOffer();
3537 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3538 {
3539 MediaExpectations media_expectations;
3540 media_expectations.CalleeExpectsSomeAudio();
3541 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3542 }
3543
Harald Alvestrand6060df52020-08-11 09:54:02 +02003544 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08003545 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3546
3547 caller()->CreateAndSetAndSignalOffer();
3548 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3549 {
3550 MediaExpectations media_expectations;
3551 media_expectations.CalleeExpectsSomeVideo();
3552 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3553 }
3554}
3555
Harald Alvestrandbedb6052020-08-20 14:50:10 +02003556TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3557 StopTransceiverRemovesDtlsTransports) {
3558 RTCConfiguration config;
3559 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3560 ConnectFakeSignaling();
3561 auto audio_transceiver_or_error =
3562 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3563 ASSERT_TRUE(audio_transceiver_or_error.ok());
3564 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3565
3566 caller()->CreateAndSetAndSignalOffer();
3567 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3568
3569 audio_transceiver->StopStandard();
3570 caller()->CreateAndSetAndSignalOffer();
3571 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3572 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3573 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3574 caller()->pc()->ice_gathering_state());
3575 EXPECT_THAT(caller()->ice_gathering_state_history(),
3576 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3577 PeerConnectionInterface::kIceGatheringComplete,
3578 PeerConnectionInterface::kIceGatheringNew));
3579}
3580
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003581TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00003582 StopTransceiverStopsAndRemovesTransceivers) {
3583 RTCConfiguration config;
3584 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3585 ConnectFakeSignaling();
3586 auto audio_transceiver_or_error =
3587 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3588 ASSERT_TRUE(audio_transceiver_or_error.ok());
3589 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3590
3591 caller()->CreateAndSetAndSignalOffer();
3592 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3593 caller_transceiver->StopStandard();
3594
3595 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3596 caller()->CreateAndSetAndSignalOffer();
3597 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3598 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3599 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3600 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3601 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3602 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3603 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3604 EXPECT_TRUE(caller_transceiver->stopped());
3605 EXPECT_TRUE(callee_transceiver->stopped());
3606}
3607
3608TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003609 StopTransceiverEndsIncomingAudioTrack) {
3610 RTCConfiguration config;
3611 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3612 ConnectFakeSignaling();
3613 auto audio_transceiver_or_error =
3614 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3615 ASSERT_TRUE(audio_transceiver_or_error.ok());
3616 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3617
3618 caller()->CreateAndSetAndSignalOffer();
3619 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3620 auto caller_track = audio_transceiver->receiver()->track();
3621 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3622 audio_transceiver->StopStandard();
3623 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3624 caller_track->state());
3625 caller()->CreateAndSetAndSignalOffer();
3626 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3627 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3628 callee_track->state());
3629}
3630
3631TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3632 StopTransceiverEndsIncomingVideoTrack) {
3633 RTCConfiguration config;
3634 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3635 ConnectFakeSignaling();
3636 auto audio_transceiver_or_error =
3637 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3638 ASSERT_TRUE(audio_transceiver_or_error.ok());
3639 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3640
3641 caller()->CreateAndSetAndSignalOffer();
3642 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3643 auto caller_track = audio_transceiver->receiver()->track();
3644 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3645 audio_transceiver->StopStandard();
3646 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3647 caller_track->state());
3648 caller()->CreateAndSetAndSignalOffer();
3649 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3650 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3651 callee_track->state());
3652}
3653
Jonas Oreland65455162022-06-08 11:25:46 +02003654TEST_P(PeerConnectionIntegrationTest, EndToEndRtpSenderVideoEncoderSelector) {
3655 ASSERT_TRUE(
3656 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
3657 ConnectFakeSignaling();
3658 // Add one-directional video, from caller to callee.
3659 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
3660 caller()->CreateLocalVideoTrack();
3661 auto sender = caller()->AddTrack(caller_track);
3662 PeerConnectionInterface::RTCOfferAnswerOptions options;
3663 options.offer_to_receive_video = 0;
3664 caller()->SetOfferAnswerOptions(options);
3665 caller()->CreateAndSetAndSignalOffer();
3666 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3667 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
3668
3669 std::unique_ptr<MockEncoderSelector> encoder_selector =
3670 std::make_unique<MockEncoderSelector>();
3671 EXPECT_CALL(*encoder_selector, OnCurrentEncoder);
3672
3673 sender->SetEncoderSelector(std::move(encoder_selector));
3674
3675 // Expect video to be received in one direction.
3676 MediaExpectations media_expectations;
3677 media_expectations.CallerExpectsNoVideo();
3678 media_expectations.CalleeExpectsSomeVideo();
3679
3680 EXPECT_TRUE(ExpectNewFrames(media_expectations));
3681}
3682
Harald Alvestrand89c40e22021-02-17 08:58:35 +00003683} // namespace
Harald Alvestrand39993842021-02-17 09:05:31 +00003684
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01003685} // namespace webrtc