blob: 638e7edb0f51a77184797646fdc54dd30d63a23c [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"
85#include "rtc_base/location.h"
86#include "rtc_base/logging.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000087#include "rtc_base/socket_address.h"
88#include "rtc_base/ssl_certificate.h"
89#include "rtc_base/ssl_fingerprint.h"
90#include "rtc_base/ssl_identity.h"
91#include "rtc_base/ssl_stream_adapter.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));
Ying Wangef3998f2019-12-09 13:06:53 +0100271 EXPECT_METRIC_LE(
272 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
273 webrtc::kEnumCounterKeyProtocolDtls));
274 EXPECT_METRIC_EQ(
275 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
276 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -0700277}
278
Harald Alvestrandca327932022-04-04 15:37:31 +0000279#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06 +0000280// Uses SDES instead of DTLS for key agreement.
281TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
282 PeerConnectionInterface::RTCConfiguration sdes_config;
283 sdes_config.enable_dtls_srtp.emplace(false);
284 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
285 ConnectFakeSignaling();
286
287 // Do normal offer/answer and wait for some frames to be received in each
288 // direction.
289 caller()->AddAudioVideoTracks();
290 callee()->AddAudioVideoTracks();
291 caller()->CreateAndSetAndSignalOffer();
292 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
293 MediaExpectations media_expectations;
294 media_expectations.ExpectBidirectionalAudioAndVideo();
295 ASSERT_TRUE(ExpectNewFrames(media_expectations));
296 EXPECT_METRIC_LE(
297 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
298 webrtc::kEnumCounterKeyProtocolSdes));
299 EXPECT_METRIC_EQ(
300 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
301 webrtc::kEnumCounterKeyProtocolDtls));
302}
Harald Alvestrandca327932022-04-04 15:37:31 +0000303#endif
Harald Alvestrand50b95522021-11-18 10:01:06 +0000304
Artem Titov880fa812021-07-30 22:30:23 +0200305// Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions`
Steve Anton9a44b2d2019-07-12 12:58:30 -0700306// option to offer encrypted versions of all header extensions alongside the
307// unencrypted versions.
308TEST_P(PeerConnectionIntegrationTest,
309 EndToEndCallWithEncryptedRtpHeaderExtensions) {
310 CryptoOptions crypto_options;
311 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
312 PeerConnectionInterface::RTCConfiguration config;
313 config.crypto_options = crypto_options;
314 // Note: This allows offering >14 RTP header extensions.
315 config.offer_extmap_allow_mixed = true;
316 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
317 ConnectFakeSignaling();
318
319 // Do normal offer/answer and wait for some frames to be received in each
320 // direction.
321 caller()->AddAudioVideoTracks();
322 callee()->AddAudioVideoTracks();
323 caller()->CreateAndSetAndSignalOffer();
324 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
325 MediaExpectations media_expectations;
326 media_expectations.ExpectBidirectionalAudioAndVideo();
327 ASSERT_TRUE(ExpectNewFrames(media_expectations));
328}
329
deadbeef1dcb1642017-03-29 21:08:16 -0700330// This test sets up a call between two parties with a source resolution of
331// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800332TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700333 Send1280By720ResolutionAndReceive16To9AspectRatio) {
334 ASSERT_TRUE(CreatePeerConnectionWrappers());
335 ConnectFakeSignaling();
336
Niels Möller5c7efe72018-05-11 10:34:46 +0200337 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
338 webrtc::FakePeriodicVideoSource::Config config;
339 config.width = 1280;
340 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +0200341 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200342 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
343 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -0700344
345 // Do normal offer/answer and wait for at least one frame to be received in
346 // each direction.
347 caller()->CreateAndSetAndSignalOffer();
348 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
349 callee()->min_video_frames_received_per_track() > 0,
350 kMaxWaitForFramesMs);
351
352 // Check rendered aspect ratio.
353 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
354 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
355 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
356 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
357}
358
359// This test sets up an one-way call, with media only from caller to
360// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800361TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -0700362 ASSERT_TRUE(CreatePeerConnectionWrappers());
363 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800364 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700365 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800366 MediaExpectations media_expectations;
367 media_expectations.CalleeExpectsSomeAudioAndVideo();
368 media_expectations.CallerExpectsNoAudio();
369 media_expectations.CallerExpectsNoVideo();
370 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700371}
372
Johannes Kron3e983682020-03-29 22:17:00 +0200373// Tests that send only works without the caller having a decoder factory and
374// the callee having an encoder factory.
375TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
376 ASSERT_TRUE(
377 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
378 ConnectFakeSignaling();
379 // Add one-directional video, from caller to callee.
380 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
381 caller()->CreateLocalVideoTrack();
382 caller()->AddTrack(caller_track);
383 PeerConnectionInterface::RTCOfferAnswerOptions options;
384 options.offer_to_receive_video = 0;
385 caller()->SetOfferAnswerOptions(options);
386 caller()->CreateAndSetAndSignalOffer();
387 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
388 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
389
390 // Expect video to be received in one direction.
391 MediaExpectations media_expectations;
392 media_expectations.CallerExpectsNoVideo();
393 media_expectations.CalleeExpectsSomeVideo();
394
395 EXPECT_TRUE(ExpectNewFrames(media_expectations));
396}
397
398// Tests that receive only works without the caller having an encoder factory
399// and the callee having a decoder factory.
400TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
401 ASSERT_TRUE(
402 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
403 ConnectFakeSignaling();
404 // Add one-directional video, from callee to caller.
405 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
406 callee()->CreateLocalVideoTrack();
407 callee()->AddTrack(callee_track);
408 PeerConnectionInterface::RTCOfferAnswerOptions options;
409 options.offer_to_receive_video = 1;
410 caller()->SetOfferAnswerOptions(options);
411 caller()->CreateAndSetAndSignalOffer();
412 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
413 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
414
415 // Expect video to be received in one direction.
416 MediaExpectations media_expectations;
417 media_expectations.CallerExpectsSomeVideo();
418 media_expectations.CalleeExpectsNoVideo();
419
420 EXPECT_TRUE(ExpectNewFrames(media_expectations));
421}
422
423TEST_P(PeerConnectionIntegrationTest,
424 EndToEndCallAddReceiveVideoToSendOnlyCall) {
425 ASSERT_TRUE(CreatePeerConnectionWrappers());
426 ConnectFakeSignaling();
427 // Add one-directional video, from caller to callee.
428 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
429 caller()->CreateLocalVideoTrack();
430 caller()->AddTrack(caller_track);
431 caller()->CreateAndSetAndSignalOffer();
432 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
433
434 // Add receive video.
435 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
436 callee()->CreateLocalVideoTrack();
437 callee()->AddTrack(callee_track);
438 caller()->CreateAndSetAndSignalOffer();
439 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
440
441 // Ensure that video frames are received end-to-end.
442 MediaExpectations media_expectations;
443 media_expectations.ExpectBidirectionalVideo();
444 ASSERT_TRUE(ExpectNewFrames(media_expectations));
445}
446
447TEST_P(PeerConnectionIntegrationTest,
448 EndToEndCallAddSendVideoToReceiveOnlyCall) {
449 ASSERT_TRUE(CreatePeerConnectionWrappers());
450 ConnectFakeSignaling();
451 // Add one-directional video, from callee to caller.
452 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
453 callee()->CreateLocalVideoTrack();
454 callee()->AddTrack(callee_track);
455 caller()->CreateAndSetAndSignalOffer();
456 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
457
458 // Add send video.
459 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
460 caller()->CreateLocalVideoTrack();
461 caller()->AddTrack(caller_track);
462 caller()->CreateAndSetAndSignalOffer();
463 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
464
465 // Expect video to be received in one direction.
466 MediaExpectations media_expectations;
467 media_expectations.ExpectBidirectionalVideo();
468 ASSERT_TRUE(ExpectNewFrames(media_expectations));
469}
470
471TEST_P(PeerConnectionIntegrationTest,
472 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
473 ASSERT_TRUE(CreatePeerConnectionWrappers());
474 ConnectFakeSignaling();
475 // Add send video, from caller to callee.
476 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
477 caller()->CreateLocalVideoTrack();
478 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
479 caller()->AddTrack(caller_track);
480 // Add receive video, from callee to caller.
481 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
482 callee()->CreateLocalVideoTrack();
483
484 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
485 callee()->AddTrack(callee_track);
486 caller()->CreateAndSetAndSignalOffer();
487 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
488
489 // Remove receive video (i.e., callee sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000490 callee()->pc()->RemoveTrackOrError(callee_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200491
492 caller()->CreateAndSetAndSignalOffer();
493 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
494
495 // Expect one-directional video.
496 MediaExpectations media_expectations;
497 media_expectations.CallerExpectsNoVideo();
498 media_expectations.CalleeExpectsSomeVideo();
499
500 ASSERT_TRUE(ExpectNewFrames(media_expectations));
501}
502
503TEST_P(PeerConnectionIntegrationTest,
504 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
505 ASSERT_TRUE(CreatePeerConnectionWrappers());
506 ConnectFakeSignaling();
507 // Add send video, from caller to callee.
508 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
509 caller()->CreateLocalVideoTrack();
510 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
511 caller()->AddTrack(caller_track);
512 // Add receive video, from callee to caller.
513 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
514 callee()->CreateLocalVideoTrack();
515
516 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
517 callee()->AddTrack(callee_track);
518 caller()->CreateAndSetAndSignalOffer();
519 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
520
521 // Remove send video (i.e., caller sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000522 caller()->pc()->RemoveTrackOrError(caller_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200523
524 caller()->CreateAndSetAndSignalOffer();
525 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
526
527 // Expect one-directional video.
528 MediaExpectations media_expectations;
529 media_expectations.CalleeExpectsNoVideo();
530 media_expectations.CallerExpectsSomeVideo();
531
532 ASSERT_TRUE(ExpectNewFrames(media_expectations));
533}
534
deadbeef1dcb1642017-03-29 21:08:16 -0700535// This test sets up a audio call initially, with the callee rejecting video
536// initially. Then later the callee decides to upgrade to audio/video, and
537// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800538TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -0700539 ASSERT_TRUE(CreatePeerConnectionWrappers());
540 ConnectFakeSignaling();
541 // Initially, offer an audio/video stream from the caller, but refuse to
542 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -0800543 caller()->AddAudioVideoTracks();
544 callee()->AddAudioTrack();
Florent Castelli15a38de2022-04-06 00:38:21 +0200545 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800546 PeerConnectionInterface::RTCOfferAnswerOptions options;
547 options.offer_to_receive_video = 0;
548 callee()->SetOfferAnswerOptions(options);
549 } else {
550 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200551 callee()
552 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
553 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800554 });
555 }
deadbeef1dcb1642017-03-29 21:08:16 -0700556 // Do offer/answer and make sure audio is still received end-to-end.
557 caller()->CreateAndSetAndSignalOffer();
558 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800559 {
560 MediaExpectations media_expectations;
561 media_expectations.ExpectBidirectionalAudio();
562 media_expectations.ExpectNoVideo();
563 ASSERT_TRUE(ExpectNewFrames(media_expectations));
564 }
deadbeef1dcb1642017-03-29 21:08:16 -0700565 // Sanity check that the callee's description has a rejected video section.
566 ASSERT_NE(nullptr, callee()->pc()->local_description());
567 const ContentInfo* callee_video_content =
568 GetFirstVideoContent(callee()->pc()->local_description()->description());
569 ASSERT_NE(nullptr, callee_video_content);
570 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800571
deadbeef1dcb1642017-03-29 21:08:16 -0700572 // Now negotiate with video and ensure negotiation succeeds, with video
573 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -0800574 callee()->AddVideoTrack();
Florent Castelli15a38de2022-04-06 00:38:21 +0200575 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800576 PeerConnectionInterface::RTCOfferAnswerOptions options;
577 options.offer_to_receive_video = 1;
578 callee()->SetOfferAnswerOptions(options);
579 } else {
580 callee()->SetRemoteOfferHandler(nullptr);
581 caller()->SetRemoteOfferHandler([this] {
582 // The caller creates a new transceiver to receive video on when receiving
583 // the offer, but by default it is send only.
584 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200585 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800586 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +0200587 transceivers[1]->receiver()->media_type());
Niels Möllerafb246b2022-04-20 14:26:50 +0200588 transceivers[1]->sender()->SetTrack(
589 caller()->CreateLocalVideoTrack().get());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200590 transceivers[1]->SetDirectionWithError(
591 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800592 });
593 }
deadbeef1dcb1642017-03-29 21:08:16 -0700594 callee()->CreateAndSetAndSignalOffer();
595 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800596 {
597 // Expect additional audio frames to be received after the upgrade.
598 MediaExpectations media_expectations;
599 media_expectations.ExpectBidirectionalAudioAndVideo();
600 ASSERT_TRUE(ExpectNewFrames(media_expectations));
601 }
deadbeef1dcb1642017-03-29 21:08:16 -0700602}
603
deadbeef4389b4d2017-09-07 09:07:36 -0700604// Simpler than the above test; just add an audio track to an established
605// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800606TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -0700607 ASSERT_TRUE(CreatePeerConnectionWrappers());
608 ConnectFakeSignaling();
609 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -0800610 caller()->AddVideoTrack();
611 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700612 caller()->CreateAndSetAndSignalOffer();
613 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
614 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -0800615 caller()->AddAudioTrack();
616 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700617 caller()->CreateAndSetAndSignalOffer();
618 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
619 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800620 MediaExpectations media_expectations;
621 media_expectations.ExpectBidirectionalAudioAndVideo();
622 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -0700623}
624
deadbeef1dcb1642017-03-29 21:08:16 -0700625// This test sets up a non-bundled call and negotiates bundling at the same
626// time as starting an ICE restart. When bundling is in effect in the restart,
627// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800628TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -0700629 ASSERT_TRUE(CreatePeerConnectionWrappers());
630 ConnectFakeSignaling();
631
Steve Anton15324772018-01-16 10:26:49 -0800632 caller()->AddAudioVideoTracks();
633 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700634 // Remove the bundle group from the SDP received by the callee.
635 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
636 desc->RemoveGroupByName("BUNDLE");
637 });
638 caller()->CreateAndSetAndSignalOffer();
639 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
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 // Now stop removing the BUNDLE group, and trigger an ICE restart.
646 callee()->SetReceivedSdpMunger(nullptr);
647 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
648 caller()->CreateAndSetAndSignalOffer();
649 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
650
651 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800652 {
653 MediaExpectations media_expectations;
654 media_expectations.ExpectBidirectionalAudioAndVideo();
655 ASSERT_TRUE(ExpectNewFrames(media_expectations));
656 }
deadbeef1dcb1642017-03-29 21:08:16 -0700657}
658
659// Test CVO (Coordination of Video Orientation). If a video source is rotated
660// and both peers support the CVO RTP header extension, the actual video frames
661// don't need to be encoded in different resolutions, since the rotation is
662// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800663TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700664 ASSERT_TRUE(CreatePeerConnectionWrappers());
665 ConnectFakeSignaling();
666 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800667 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700668 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800669 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700670 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
671
672 // Wait for video frames to be received by both sides.
673 caller()->CreateAndSetAndSignalOffer();
674 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
675 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
676 callee()->min_video_frames_received_per_track() > 0,
677 kMaxWaitForFramesMs);
678
679 // Ensure that the aspect ratio is unmodified.
680 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
681 // not just assumed.
682 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
683 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
684 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
685 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
686 // Ensure that the CVO bits were surfaced to the renderer.
687 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
688 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
689}
690
691// Test that when the CVO extension isn't supported, video is rotated the
692// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800693TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700694 ASSERT_TRUE(CreatePeerConnectionWrappers());
695 ConnectFakeSignaling();
696 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800697 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700698 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800699 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700700 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
701
702 // Remove the CVO extension from the offered SDP.
703 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
704 cricket::VideoContentDescription* video =
705 GetFirstVideoContentDescription(desc);
706 video->ClearRtpHeaderExtensions();
707 });
708 // Wait for video frames to be received by both sides.
709 caller()->CreateAndSetAndSignalOffer();
710 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
711 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
712 callee()->min_video_frames_received_per_track() > 0,
713 kMaxWaitForFramesMs);
714
715 // Expect that the aspect ratio is inversed to account for the 90/270 degree
716 // rotation.
717 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
718 // not just assumed.
719 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
720 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
721 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
722 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
723 // Expect that each endpoint is unaware of the rotation of the other endpoint.
724 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
725 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
726}
727
deadbeef1dcb1642017-03-29 21:08:16 -0700728// Test that if the answerer rejects the audio m= section, no audio is sent or
729// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800730TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700731 ASSERT_TRUE(CreatePeerConnectionWrappers());
732 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800733 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200734 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800735 // Only add video track for callee, and set offer_to_receive_audio to 0, so
736 // it will reject the audio m= section completely.
737 PeerConnectionInterface::RTCOfferAnswerOptions options;
738 options.offer_to_receive_audio = 0;
739 callee()->SetOfferAnswerOptions(options);
740 } else {
741 // Stopping the audio RtpTransceiver will cause the media section to be
742 // rejected in the answer.
743 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200744 callee()
745 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
746 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800747 });
748 }
Steve Anton15324772018-01-16 10:26:49 -0800749 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700750 // Do offer/answer and wait for successful end-to-end video frames.
751 caller()->CreateAndSetAndSignalOffer();
752 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800753 MediaExpectations media_expectations;
754 media_expectations.ExpectBidirectionalVideo();
755 media_expectations.ExpectNoAudio();
756 ASSERT_TRUE(ExpectNewFrames(media_expectations));
757
deadbeef1dcb1642017-03-29 21:08:16 -0700758 // Sanity check that the callee's description has a rejected audio section.
759 ASSERT_NE(nullptr, callee()->pc()->local_description());
760 const ContentInfo* callee_audio_content =
761 GetFirstAudioContent(callee()->pc()->local_description()->description());
762 ASSERT_NE(nullptr, callee_audio_content);
763 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800764 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200765 // The caller's transceiver should have stopped after receiving the answer,
766 // and thus no longer listed in transceivers.
767 EXPECT_EQ(nullptr,
768 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800769 }
deadbeef1dcb1642017-03-29 21:08:16 -0700770}
771
772// Test that if the answerer rejects the video m= section, no video is sent or
773// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800774TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700775 ASSERT_TRUE(CreatePeerConnectionWrappers());
776 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800777 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200778 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800779 // Only add audio track for callee, and set offer_to_receive_video to 0, so
780 // it will reject the video m= section completely.
781 PeerConnectionInterface::RTCOfferAnswerOptions options;
782 options.offer_to_receive_video = 0;
783 callee()->SetOfferAnswerOptions(options);
784 } else {
785 // Stopping the video RtpTransceiver will cause the media section to be
786 // rejected in the answer.
787 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200788 callee()
789 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
790 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800791 });
792 }
Steve Anton15324772018-01-16 10:26:49 -0800793 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700794 // Do offer/answer and wait for successful end-to-end audio frames.
795 caller()->CreateAndSetAndSignalOffer();
796 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800797 MediaExpectations media_expectations;
798 media_expectations.ExpectBidirectionalAudio();
799 media_expectations.ExpectNoVideo();
800 ASSERT_TRUE(ExpectNewFrames(media_expectations));
801
deadbeef1dcb1642017-03-29 21:08:16 -0700802 // Sanity check that the callee's description has a rejected video section.
803 ASSERT_NE(nullptr, callee()->pc()->local_description());
804 const ContentInfo* callee_video_content =
805 GetFirstVideoContent(callee()->pc()->local_description()->description());
806 ASSERT_NE(nullptr, callee_video_content);
807 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800808 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200809 // The caller's transceiver should have stopped after receiving the answer,
810 // and thus is no longer present.
811 EXPECT_EQ(nullptr,
812 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800813 }
deadbeef1dcb1642017-03-29 21:08:16 -0700814}
815
816// Test that if the answerer rejects both audio and video m= sections, nothing
817// bad happens.
818// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
819// test anything but the fact that negotiation succeeds, which doesn't mean
820// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800821TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -0700822 ASSERT_TRUE(CreatePeerConnectionWrappers());
823 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800824 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200825 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800826 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
827 // will reject both audio and video m= sections.
828 PeerConnectionInterface::RTCOfferAnswerOptions options;
829 options.offer_to_receive_audio = 0;
830 options.offer_to_receive_video = 0;
831 callee()->SetOfferAnswerOptions(options);
832 } else {
833 callee()->SetRemoteOfferHandler([this] {
834 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +0100835 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200836 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800837 }
838 });
839 }
deadbeef1dcb1642017-03-29 21:08:16 -0700840 // Do offer/answer and wait for stable signaling state.
841 caller()->CreateAndSetAndSignalOffer();
842 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800843
deadbeef1dcb1642017-03-29 21:08:16 -0700844 // Sanity check that the callee's description has rejected m= sections.
845 ASSERT_NE(nullptr, callee()->pc()->local_description());
846 const ContentInfo* callee_audio_content =
847 GetFirstAudioContent(callee()->pc()->local_description()->description());
848 ASSERT_NE(nullptr, callee_audio_content);
849 EXPECT_TRUE(callee_audio_content->rejected);
850 const ContentInfo* callee_video_content =
851 GetFirstVideoContent(callee()->pc()->local_description()->description());
852 ASSERT_NE(nullptr, callee_video_content);
853 EXPECT_TRUE(callee_video_content->rejected);
854}
855
856// This test sets up an audio and video call between two parties. After the
857// call runs for a while, the caller sends an updated offer with video being
858// rejected. Once the re-negotiation is done, the video flow should stop and
859// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800860TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700861 ASSERT_TRUE(CreatePeerConnectionWrappers());
862 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800863 caller()->AddAudioVideoTracks();
864 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700865 caller()->CreateAndSetAndSignalOffer();
866 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800867 {
868 MediaExpectations media_expectations;
869 media_expectations.ExpectBidirectionalAudioAndVideo();
870 ASSERT_TRUE(ExpectNewFrames(media_expectations));
871 }
deadbeef1dcb1642017-03-29 21:08:16 -0700872 // Renegotiate, rejecting the video m= section.
Florent Castelli15a38de2022-04-06 00:38:21 +0200873 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800874 caller()->SetGeneratedSdpMunger(
875 [](cricket::SessionDescription* description) {
876 for (cricket::ContentInfo& content : description->contents()) {
877 if (cricket::IsVideoContent(&content)) {
878 content.rejected = true;
879 }
880 }
881 });
882 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200883 caller()
884 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
885 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800886 }
deadbeef1dcb1642017-03-29 21:08:16 -0700887 caller()->CreateAndSetAndSignalOffer();
888 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
889
890 // Sanity check that the caller's description has a rejected video section.
891 ASSERT_NE(nullptr, caller()->pc()->local_description());
892 const ContentInfo* caller_video_content =
893 GetFirstVideoContent(caller()->pc()->local_description()->description());
894 ASSERT_NE(nullptr, caller_video_content);
895 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -0700896 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800897 {
898 MediaExpectations media_expectations;
899 media_expectations.ExpectBidirectionalAudio();
900 media_expectations.ExpectNoVideo();
901 ASSERT_TRUE(ExpectNewFrames(media_expectations));
902 }
deadbeef1dcb1642017-03-29 21:08:16 -0700903}
904
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700905// Do one offer/answer with audio, another that disables it (rejecting the m=
906// section), and another that re-enables it. Regression test for:
907// bugs.webrtc.org/6023
908TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
909 ASSERT_TRUE(CreatePeerConnectionWrappers());
910 ConnectFakeSignaling();
911
912 // Add audio track, do normal offer/answer.
913 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
914 caller()->CreateLocalAudioTrack();
915 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
916 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
917 caller()->CreateAndSetAndSignalOffer();
918 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
919
920 // Remove audio track, and set offer_to_receive_audio to false to cause the
921 // m= section to be completely disabled, not just "recvonly".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000922 caller()->pc()->RemoveTrackOrError(sender);
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700923 PeerConnectionInterface::RTCOfferAnswerOptions options;
924 options.offer_to_receive_audio = 0;
925 caller()->SetOfferAnswerOptions(options);
926 caller()->CreateAndSetAndSignalOffer();
927 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
928
929 // Add the audio track again, expecting negotiation to succeed and frames to
930 // flow.
931 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
932 options.offer_to_receive_audio = 1;
933 caller()->SetOfferAnswerOptions(options);
934 caller()->CreateAndSetAndSignalOffer();
935 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
936
937 MediaExpectations media_expectations;
938 media_expectations.CalleeExpectsSomeAudio();
939 EXPECT_TRUE(ExpectNewFrames(media_expectations));
940}
941
deadbeef1dcb1642017-03-29 21:08:16 -0700942// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
943// is needed to support legacy endpoints.
944// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
945// add a test for an end-to-end test without MID signaling either (basically,
946// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800947TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -0700948 ASSERT_TRUE(CreatePeerConnectionWrappers());
949 ConnectFakeSignaling();
950 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -0800951 caller()->AddAudioVideoTracks();
952 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -0700953 // Remove SSRCs and MSIDs from the received offer SDP.
954 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -0700955 caller()->CreateAndSetAndSignalOffer();
956 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800957 MediaExpectations media_expectations;
958 media_expectations.ExpectBidirectionalAudioAndVideo();
959 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700960}
961
Seth Hampson5897a6e2018-04-03 11:16:33 -0700962// Basic end-to-end test, without SSRC signaling. This means that the track
963// was created properly and frames are delivered when the MSIDs are communicated
964// with a=msid lines and no a=ssrc lines.
965TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
966 EndToEndCallWithoutSsrcSignaling) {
967 const char kStreamId[] = "streamId";
968 ASSERT_TRUE(CreatePeerConnectionWrappers());
969 ConnectFakeSignaling();
970 // Add just audio tracks.
971 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
972 callee()->AddAudioTrack();
973
974 // Remove SSRCs from the received offer SDP.
975 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
976 caller()->CreateAndSetAndSignalOffer();
977 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
978 MediaExpectations media_expectations;
979 media_expectations.ExpectBidirectionalAudio();
980 ASSERT_TRUE(ExpectNewFrames(media_expectations));
981}
982
Johannes Kron3e983682020-03-29 22:17:00 +0200983TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
984 EndToEndCallAddReceiveVideoToSendOnlyCall) {
985 ASSERT_TRUE(CreatePeerConnectionWrappers());
986 ConnectFakeSignaling();
987 // Add one-directional video, from caller to callee.
988 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
989 caller()->CreateLocalVideoTrack();
990
991 RtpTransceiverInit video_transceiver_init;
992 video_transceiver_init.stream_ids = {"video1"};
993 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
994 auto video_sender =
995 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
996 caller()->CreateAndSetAndSignalOffer();
997 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
998
999 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +02001000 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02001001
1002 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
1003 callee()->CreateLocalVideoTrack();
1004
1005 callee()->AddTrack(callee_track);
1006 caller()->CreateAndSetAndSignalOffer();
1007 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1008 // Ensure that video frames are received end-to-end.
1009 MediaExpectations media_expectations;
1010 media_expectations.ExpectBidirectionalVideo();
1011 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1012}
1013
Steve Antondf527fd2018-04-27 15:52:03 -07001014// Tests that video flows between multiple video tracks when SSRCs are not
1015// signaled. This exercises the MID RTP header extension which is needed to
1016// demux the incoming video tracks.
1017TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1018 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
1019 ASSERT_TRUE(CreatePeerConnectionWrappers());
1020 ConnectFakeSignaling();
1021 caller()->AddVideoTrack();
1022 caller()->AddVideoTrack();
1023 callee()->AddVideoTrack();
1024 callee()->AddVideoTrack();
1025
1026 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1027 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1028 caller()->CreateAndSetAndSignalOffer();
1029 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1030 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1031 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1032
1033 // Expect video to be received in both directions on both tracks.
1034 MediaExpectations media_expectations;
1035 media_expectations.ExpectBidirectionalVideo();
1036 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1037}
1038
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07001039// Used for the test below.
1040void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
1041 RemoveSsrcsAndKeepMsids(desc);
1042 desc->RemoveGroupByName("BUNDLE");
1043 for (ContentInfo& content : desc->contents()) {
1044 cricket::MediaContentDescription* media = content.media_description();
1045 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1046 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1047 [](const RtpExtension& extension) {
1048 return extension.uri ==
1049 RtpExtension::kMidUri;
1050 }),
1051 extensions.end());
1052 media->set_rtp_header_extensions(extensions);
1053 }
1054}
1055
1056// Tests that video flows between multiple video tracks when BUNDLE is not used,
1057// SSRCs are not signaled and the MID RTP header extension is not used. This
1058// relies on demuxing by payload type, which normally doesn't work if you have
1059// multiple media sections using the same payload type, but which should work as
1060// long as the media sections aren't bundled.
1061// Regression test for: http://crbug.com/webrtc/12023
1062TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1063 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
1064 ASSERT_TRUE(CreatePeerConnectionWrappers());
1065 ConnectFakeSignaling();
1066 caller()->AddVideoTrack();
1067 caller()->AddVideoTrack();
1068 callee()->AddVideoTrack();
1069 callee()->AddVideoTrack();
1070 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1071 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1072 caller()->CreateAndSetAndSignalOffer();
1073 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1074 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1075 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1076 // Make sure we are not bundled.
1077 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
1078 caller()->pc()->GetSenders()[1]->dtls_transport());
1079
1080 // Expect video to be received in both directions on both tracks.
1081 MediaExpectations media_expectations;
1082 media_expectations.ExpectBidirectionalVideo();
1083 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1084}
1085
1086// Used for the test below.
1087void ModifyPayloadTypesAndRemoveMidExtension(
1088 cricket::SessionDescription* desc) {
1089 int pt = 96;
1090 for (ContentInfo& content : desc->contents()) {
1091 cricket::MediaContentDescription* media = content.media_description();
1092 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1093 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1094 [](const RtpExtension& extension) {
1095 return extension.uri ==
1096 RtpExtension::kMidUri;
1097 }),
1098 extensions.end());
1099 media->set_rtp_header_extensions(extensions);
1100 cricket::VideoContentDescription* video = media->as_video();
1101 ASSERT_TRUE(video != nullptr);
1102 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
1103 video->set_codecs(codecs);
1104 }
1105}
1106
1107// Tests that two video tracks can be demultiplexed by payload type alone, by
1108// using different payload types for the same codec in different m= sections.
1109// This practice is discouraged but historically has been supported.
1110// Regression test for: http://crbug.com/webrtc/12029
1111TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1112 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
1113 ASSERT_TRUE(CreatePeerConnectionWrappers());
1114 ConnectFakeSignaling();
1115 caller()->AddVideoTrack();
1116 caller()->AddVideoTrack();
1117 callee()->AddVideoTrack();
1118 callee()->AddVideoTrack();
1119 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1120 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1121 // We can't remove SSRCs from the generated SDP because then no send streams
1122 // would be created.
1123 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1124 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1125 caller()->CreateAndSetAndSignalOffer();
1126 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1127 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1128 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1129 // Make sure we are bundled.
1130 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
1131 caller()->pc()->GetSenders()[1]->dtls_transport());
1132
1133 // Expect video to be received in both directions on both tracks.
1134 MediaExpectations media_expectations;
1135 media_expectations.ExpectBidirectionalVideo();
1136 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1137}
1138
Henrik Boström5b147782018-12-04 11:25:05 +01001139TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
1140 ASSERT_TRUE(CreatePeerConnectionWrappers());
1141 ConnectFakeSignaling();
1142 caller()->AddAudioTrack();
1143 caller()->AddVideoTrack();
1144 caller()->CreateAndSetAndSignalOffer();
1145 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1146 auto callee_receivers = callee()->pc()->GetReceivers();
1147 ASSERT_EQ(2u, callee_receivers.size());
1148 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
1149 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
1150}
1151
1152TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
1153 ASSERT_TRUE(CreatePeerConnectionWrappers());
1154 ConnectFakeSignaling();
1155 caller()->AddAudioTrack();
1156 caller()->AddVideoTrack();
1157 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1158 caller()->CreateAndSetAndSignalOffer();
1159 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1160 auto callee_receivers = callee()->pc()->GetReceivers();
1161 ASSERT_EQ(2u, callee_receivers.size());
1162 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
1163 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
1164 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
1165 callee_receivers[1]->stream_ids()[0]);
1166 EXPECT_EQ(callee_receivers[0]->streams()[0],
1167 callee_receivers[1]->streams()[0]);
1168}
1169
deadbeef1dcb1642017-03-29 21:08:16 -07001170// Test that if two video tracks are sent (from caller to callee, in this test),
1171// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001172TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07001173 ASSERT_TRUE(CreatePeerConnectionWrappers());
1174 ConnectFakeSignaling();
1175 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08001176 caller()->AddAudioVideoTracks();
1177 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001178 caller()->CreateAndSetAndSignalOffer();
1179 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08001180 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001181
1182 MediaExpectations media_expectations;
1183 media_expectations.CalleeExpectsSomeAudioAndVideo();
1184 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001185}
1186
1187static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
1188 bool first = true;
1189 for (cricket::ContentInfo& content : desc->contents()) {
1190 if (first) {
1191 first = false;
1192 continue;
1193 }
1194 content.bundle_only = true;
1195 }
1196 first = true;
1197 for (cricket::TransportInfo& transport : desc->transport_infos()) {
1198 if (first) {
1199 first = false;
1200 continue;
1201 }
1202 transport.description.ice_ufrag.clear();
1203 transport.description.ice_pwd.clear();
1204 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
1205 transport.description.identity_fingerprint.reset(nullptr);
1206 }
1207}
1208
1209// Test that if applying a true "max bundle" offer, which uses ports of 0,
1210// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
1211// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
1212// successfully and media flows.
1213// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
1214// TODO(deadbeef): Won't need this test once we start generating actual
1215// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001216TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001217 EndToEndCallWithSpecCompliantMaxBundleOffer) {
1218 ASSERT_TRUE(CreatePeerConnectionWrappers());
1219 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001220 caller()->AddAudioVideoTracks();
1221 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001222 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
1223 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
1224 // but the first m= section.
1225 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
1226 caller()->CreateAndSetAndSignalOffer();
1227 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001228 MediaExpectations media_expectations;
1229 media_expectations.ExpectBidirectionalAudioAndVideo();
1230 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001231}
1232
1233// Test that we can receive the audio output level from a remote audio track.
1234// TODO(deadbeef): Use a fake audio source and verify that the output level is
1235// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001236TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001237 ASSERT_TRUE(CreatePeerConnectionWrappers());
1238 ConnectFakeSignaling();
1239 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001240 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001241 caller()->CreateAndSetAndSignalOffer();
1242 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1243
1244 // Get the audio output level stats. Note that the level is not available
1245 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07001246 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001247 kMaxWaitForFramesMs);
1248}
1249
1250// Test that an audio input level is reported.
1251// TODO(deadbeef): Use a fake audio source and verify that the input level is
1252// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001253TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001254 ASSERT_TRUE(CreatePeerConnectionWrappers());
1255 ConnectFakeSignaling();
1256 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001257 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001258 caller()->CreateAndSetAndSignalOffer();
1259 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1260
1261 // Get the audio input level stats. The level should be available very
1262 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07001263 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001264 kMaxWaitForStatsMs);
1265}
1266
1267// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001268TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001269 ASSERT_TRUE(CreatePeerConnectionWrappers());
1270 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001271 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001272 // Do offer/answer, wait for the callee to receive some frames.
1273 caller()->CreateAndSetAndSignalOffer();
1274 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001275
1276 MediaExpectations media_expectations;
1277 media_expectations.CalleeExpectsSomeAudioAndVideo();
1278 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001279
1280 // Get a handle to the remote tracks created, so they can be used as GetStats
1281 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01001282 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08001283 // We received frames, so we definitely should have nonzero "received bytes"
1284 // stats at this point.
Niels Möllerafb246b2022-04-20 14:26:50 +02001285 EXPECT_GT(
1286 callee()->OldGetStatsForTrack(receiver->track().get())->BytesReceived(),
1287 0);
Steve Anton15324772018-01-16 10:26:49 -08001288 }
deadbeef1dcb1642017-03-29 21:08:16 -07001289}
1290
1291// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001292TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001293 ASSERT_TRUE(CreatePeerConnectionWrappers());
1294 ConnectFakeSignaling();
1295 auto audio_track = caller()->CreateLocalAudioTrack();
1296 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08001297 caller()->AddTrack(audio_track);
1298 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07001299 // Do offer/answer, wait for the callee to receive some frames.
1300 caller()->CreateAndSetAndSignalOffer();
1301 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001302 MediaExpectations media_expectations;
1303 media_expectations.CalleeExpectsSomeAudioAndVideo();
1304 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001305
1306 // The callee received frames, so we definitely should have nonzero "sent
1307 // bytes" stats at this point.
Niels Möllerafb246b2022-04-20 14:26:50 +02001308 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track.get())->BytesSent(), 0);
1309 EXPECT_GT(caller()->OldGetStatsForTrack(video_track.get())->BytesSent(), 0);
deadbeefd8ad7882017-04-18 16:01:17 -07001310}
1311
Steve Antona41959e2018-11-28 11:15:33 -08001312// Test that the track ID is associated with all local and remote SSRC stats
1313// using the old GetStats() and more than 1 audio and more than 1 video track.
1314// This is a regression test for crbug.com/906988
1315TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1316 OldGetStatsAssociatesTrackIdForManyMediaSections) {
1317 ASSERT_TRUE(CreatePeerConnectionWrappers());
1318 ConnectFakeSignaling();
1319 auto audio_sender_1 = caller()->AddAudioTrack();
1320 auto video_sender_1 = caller()->AddVideoTrack();
1321 auto audio_sender_2 = caller()->AddAudioTrack();
1322 auto video_sender_2 = caller()->AddVideoTrack();
1323 caller()->CreateAndSetAndSignalOffer();
1324 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1325
1326 MediaExpectations media_expectations;
1327 media_expectations.CalleeExpectsSomeAudioAndVideo();
1328 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1329
1330 std::vector<std::string> track_ids = {
1331 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1332 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1333
1334 auto caller_stats = caller()->OldGetStats();
1335 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1336 auto callee_stats = callee()->OldGetStats();
1337 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1338}
1339
Steve Antonffa6ce42018-11-30 09:26:08 -08001340// Test that the new GetStats() returns stats for all outgoing/incoming streams
1341// with the correct track IDs if there are more than one audio and more than one
1342// video senders/receivers.
1343TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
1344 ASSERT_TRUE(CreatePeerConnectionWrappers());
1345 ConnectFakeSignaling();
1346 auto audio_sender_1 = caller()->AddAudioTrack();
1347 auto video_sender_1 = caller()->AddVideoTrack();
1348 auto audio_sender_2 = caller()->AddAudioTrack();
1349 auto video_sender_2 = caller()->AddVideoTrack();
1350 caller()->CreateAndSetAndSignalOffer();
1351 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1352
1353 MediaExpectations media_expectations;
1354 media_expectations.CalleeExpectsSomeAudioAndVideo();
1355 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1356
1357 std::vector<std::string> track_ids = {
1358 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1359 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1360
1361 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
1362 caller()->NewGetStats();
1363 ASSERT_TRUE(caller_report);
1364 auto outbound_stream_stats =
1365 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02001366 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08001367 std::vector<std::string> outbound_track_ids;
1368 for (const auto& stat : outbound_stream_stats) {
1369 ASSERT_TRUE(stat->bytes_sent.is_defined());
1370 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001371 if (*stat->kind == "video") {
1372 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
1373 EXPECT_GT(*stat->key_frames_encoded, 0u);
1374 ASSERT_TRUE(stat->frames_encoded.is_defined());
1375 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
1376 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001377 ASSERT_TRUE(stat->track_id.is_defined());
1378 const auto* track_stat =
1379 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1380 ASSERT_TRUE(track_stat);
1381 outbound_track_ids.push_back(*track_stat->track_identifier);
1382 }
1383 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
1384
1385 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
1386 callee()->NewGetStats();
1387 ASSERT_TRUE(callee_report);
1388 auto inbound_stream_stats =
1389 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1390 ASSERT_EQ(4u, inbound_stream_stats.size());
1391 std::vector<std::string> inbound_track_ids;
1392 for (const auto& stat : inbound_stream_stats) {
1393 ASSERT_TRUE(stat->bytes_received.is_defined());
1394 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001395 if (*stat->kind == "video") {
1396 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
1397 EXPECT_GT(*stat->key_frames_decoded, 0u);
1398 ASSERT_TRUE(stat->frames_decoded.is_defined());
1399 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
1400 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001401 ASSERT_TRUE(stat->track_id.is_defined());
1402 const auto* track_stat =
1403 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1404 ASSERT_TRUE(track_stat);
1405 inbound_track_ids.push_back(*track_stat->track_identifier);
1406 }
1407 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
1408}
1409
1410// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07001411// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
1412// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001413TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07001414 GetStatsForUnsignaledStreamWithNewStatsApi) {
1415 ASSERT_TRUE(CreatePeerConnectionWrappers());
1416 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001417 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07001418 // Remove SSRCs and MSIDs from the received offer SDP.
1419 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1420 caller()->CreateAndSetAndSignalOffer();
1421 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001422 MediaExpectations media_expectations;
1423 media_expectations.CalleeExpectsSomeAudio(1);
1424 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07001425
1426 // We received a frame, so we should have nonzero "bytes received" stats for
1427 // the unsignaled stream, if stats are working for it.
1428 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1429 callee()->NewGetStats();
1430 ASSERT_NE(nullptr, report);
1431 auto inbound_stream_stats =
1432 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1433 ASSERT_EQ(1U, inbound_stream_stats.size());
1434 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
1435 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07001436 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
1437}
1438
Taylor Brandstettera4653442018-06-19 09:44:26 -07001439// Same as above but for the legacy stats implementation.
1440TEST_P(PeerConnectionIntegrationTest,
1441 GetStatsForUnsignaledStreamWithOldStatsApi) {
1442 ASSERT_TRUE(CreatePeerConnectionWrappers());
1443 ConnectFakeSignaling();
1444 caller()->AddAudioTrack();
1445 // Remove SSRCs and MSIDs from the received offer SDP.
1446 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1447 caller()->CreateAndSetAndSignalOffer();
1448 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1449
1450 // Note that, since the old stats implementation associates SSRCs with tracks
1451 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
1452 // associated track ID. So we can't use the track "selector" argument.
1453 //
1454 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
1455 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001456 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07001457 kDefaultTimeout);
1458}
1459
zhihuangf8164932017-05-19 13:09:47 -07001460// Test that we can successfully get the media related stats (audio level
1461// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001462TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07001463 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
1464 ASSERT_TRUE(CreatePeerConnectionWrappers());
1465 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001466 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07001467 // Remove SSRCs and MSIDs from the received offer SDP.
1468 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1469 caller()->CreateAndSetAndSignalOffer();
1470 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001471 MediaExpectations media_expectations;
1472 media_expectations.CalleeExpectsSomeAudio(1);
1473 media_expectations.CalleeExpectsSomeVideo(1);
1474 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07001475
1476 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1477 callee()->NewGetStats();
1478 ASSERT_NE(nullptr, report);
1479
1480 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1481 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
1482 ASSERT_GE(audio_index, 0);
1483 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07001484}
1485
deadbeef4e2deab2017-09-20 13:56:21 -07001486// Helper for test below.
1487void ModifySsrcs(cricket::SessionDescription* desc) {
1488 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07001489 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08001490 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07001491 for (uint32_t& ssrc : stream.ssrcs) {
1492 ssrc = rtc::CreateRandomId();
1493 }
1494 }
1495 }
1496}
1497
1498// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
1499// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
1500// This should result in two "RTCInboundRTPStreamStats", but only one
1501// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
1502// being reset to 0 once the SSRC change occurs.
1503//
1504// Regression test for this bug:
1505// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
1506//
1507// The bug causes the track stats to only represent one of the two streams:
1508// whichever one has the higher SSRC. So with this bug, there was a 50% chance
1509// that the track stat counters would reset to 0 when the new stream is
1510// received, and a 50% chance that they'll stop updating (while
1511// "concealed_samples" continues increasing, due to silence being generated for
1512// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001513TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08001514 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07001515 ASSERT_TRUE(CreatePeerConnectionWrappers());
1516 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001517 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07001518 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
1519 // that doesn't signal SSRCs (from the callee's perspective).
1520 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1521 caller()->CreateAndSetAndSignalOffer();
1522 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1523 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001524 {
1525 MediaExpectations media_expectations;
1526 media_expectations.CalleeExpectsSomeAudio(50);
1527 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1528 }
deadbeef4e2deab2017-09-20 13:56:21 -07001529 // Some audio frames were received, so we should have nonzero "samples
1530 // received" for the track.
1531 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1532 callee()->NewGetStats();
1533 ASSERT_NE(nullptr, report);
1534 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1535 ASSERT_EQ(1U, track_stats.size());
1536 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1537 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
1538 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
1539
1540 // Create a new offer and munge it to cause the caller to use a new SSRC.
1541 caller()->SetGeneratedSdpMunger(ModifySsrcs);
1542 caller()->CreateAndSetAndSignalOffer();
1543 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1544 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
1545 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001546 {
1547 MediaExpectations media_expectations;
1548 media_expectations.CalleeExpectsSomeAudio(25);
1549 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1550 }
deadbeef4e2deab2017-09-20 13:56:21 -07001551
1552 report = callee()->NewGetStats();
1553 ASSERT_NE(nullptr, report);
1554 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1555 ASSERT_EQ(1U, track_stats.size());
1556 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1557 // The "total samples received" stat should only be greater than it was
1558 // before.
1559 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
1560 // Right now, the new SSRC will cause the counters to reset to 0.
1561 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
1562
1563 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08001564 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07001565 // good sign that we're seeing stats from the old stream that's no longer
1566 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08001567 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07001568 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
1569 EXPECT_LT(*track_stats[0]->concealed_samples,
1570 *track_stats[0]->total_samples_received *
1571 kAcceptableConcealedSamplesPercentage);
1572
1573 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
1574 // sanity check that the SSRC really changed.
1575 // TODO(deadbeef): This isn't working right now, because we're not returning
1576 // *any* stats for the inactive stream. Uncomment when the bug is completely
1577 // fixed.
1578 // auto inbound_stream_stats =
1579 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1580 // ASSERT_EQ(2U, inbound_stream_stats.size());
1581}
1582
deadbeef1dcb1642017-03-29 21:08:16 -07001583// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001584TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001585 PeerConnectionFactory::Options dtls_10_options;
1586 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1587 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1588 dtls_10_options));
1589 ConnectFakeSignaling();
1590 // Do normal offer/answer and wait for some frames to be received in each
1591 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001592 caller()->AddAudioVideoTracks();
1593 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001594 caller()->CreateAndSetAndSignalOffer();
1595 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001596 MediaExpectations media_expectations;
1597 media_expectations.ExpectBidirectionalAudioAndVideo();
1598 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001599}
1600
1601// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001602TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001603 PeerConnectionFactory::Options dtls_10_options;
1604 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1605 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1606 dtls_10_options));
1607 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001608 caller()->AddAudioVideoTracks();
1609 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001610 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001611 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001612 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001613 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001614 kDefaultTimeout);
1615 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001616 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001617 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001618 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1619 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1620 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001621}
1622
1623// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001624TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001625 PeerConnectionFactory::Options dtls_12_options;
1626 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1627 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
1628 dtls_12_options));
1629 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001630 caller()->AddAudioVideoTracks();
1631 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001632 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001633 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001634 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001635 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001636 kDefaultTimeout);
1637 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001638 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001639 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001640 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1641 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1642 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001643}
1644
1645// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
1646// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001647TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001648 PeerConnectionFactory::Options caller_options;
1649 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1650 PeerConnectionFactory::Options callee_options;
1651 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1652 ASSERT_TRUE(
1653 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1654 ConnectFakeSignaling();
1655 // Do normal offer/answer and wait for some frames to be received in each
1656 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001657 caller()->AddAudioVideoTracks();
1658 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001659 caller()->CreateAndSetAndSignalOffer();
1660 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001661 MediaExpectations media_expectations;
1662 media_expectations.ExpectBidirectionalAudioAndVideo();
1663 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001664}
1665
1666// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
1667// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001668TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07001669 PeerConnectionFactory::Options caller_options;
1670 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1671 PeerConnectionFactory::Options callee_options;
1672 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1673 ASSERT_TRUE(
1674 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1675 ConnectFakeSignaling();
1676 // Do normal offer/answer and wait for some frames to be received in each
1677 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001678 caller()->AddAudioVideoTracks();
1679 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001680 caller()->CreateAndSetAndSignalOffer();
1681 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001682 MediaExpectations media_expectations;
1683 media_expectations.ExpectBidirectionalAudioAndVideo();
1684 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001685}
1686
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001687// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
1688// works as expected; the cipher should only be used if enabled by both sides.
1689TEST_P(PeerConnectionIntegrationTest,
1690 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
1691 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001692 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001693 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001694 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1695 false;
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,
1702 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
1703 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001704 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1705 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001706 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001707 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001708 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001709 TestNegotiatedCipherSuite(caller_options, callee_options,
1710 expected_cipher_suite);
1711}
1712
1713TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
1714 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001715 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001716 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001717 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001718 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_32;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001719 TestNegotiatedCipherSuite(caller_options, callee_options,
1720 expected_cipher_suite);
1721}
1722
deadbeef1dcb1642017-03-29 21:08:16 -07001723// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001724TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001725 bool local_gcm_enabled = false;
1726 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001727 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07001728 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
1729 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001730 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001731}
1732
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001733// Test that a GCM cipher is used if both ends support it and non-GCM is
1734// disabled.
1735TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001736 bool local_gcm_enabled = true;
1737 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001738 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07001739 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
1740 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001741 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001742}
1743
deadbeef7914b8c2017-04-21 03:23:33 -07001744// Verify that media can be transmitted end-to-end when GCM crypto suites are
1745// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
1746// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
1747// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001748TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07001749 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001750 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001751 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07001752 ASSERT_TRUE(
1753 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
1754 ConnectFakeSignaling();
1755 // Do normal offer/answer and wait for some frames to be received in each
1756 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001757 caller()->AddAudioVideoTracks();
1758 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07001759 caller()->CreateAndSetAndSignalOffer();
1760 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001761 MediaExpectations media_expectations;
1762 media_expectations.ExpectBidirectionalAudioAndVideo();
1763 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07001764}
1765
deadbeef1dcb1642017-03-29 21:08:16 -07001766// Test that the ICE connection and gathering states eventually reach
1767// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08001768TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07001769 ASSERT_TRUE(CreatePeerConnectionWrappers());
1770 ConnectFakeSignaling();
1771 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001772 caller()->AddAudioVideoTracks();
1773 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001774 caller()->CreateAndSetAndSignalOffer();
1775 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1776 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1777 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
1778 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1779 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
1780 // After the best candidate pair is selected and all candidates are signaled,
1781 // the ICE connection state should reach "complete".
1782 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
1783 // answerer/"callee" by default) only reaches "connected". When this is
1784 // fixed, this test should be updated.
1785 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1786 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00001787 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1788 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001789}
1790
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001791constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1792 cricket::PORTALLOCATOR_DISABLE_RELAY |
1793 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001794
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001795// Use a mock resolver to resolve the hostname back to the original IP on both
1796// sides and check that the ICE connection connects.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001797TEST_P(PeerConnectionIntegrationTest,
Harald Alvestrand099ff622022-06-02 13:24:32 +00001798 IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001799 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001800 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001801 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001802 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001803 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1804 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001805
1806 // This also verifies that the injected AsyncResolverFactory is used by
1807 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001808 EXPECT_CALL(*caller_resolver_factory, Create())
1809 .WillOnce(Return(&caller_async_resolver));
1810 webrtc::PeerConnectionDependencies caller_deps(nullptr);
1811 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1812
1813 EXPECT_CALL(*callee_resolver_factory, Create())
1814 .WillOnce(Return(&callee_async_resolver));
1815 webrtc::PeerConnectionDependencies callee_deps(nullptr);
1816 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1817
1818 PeerConnectionInterface::RTCConfiguration config;
1819 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1820 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1821
1822 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1823 config, std::move(caller_deps), config, std::move(callee_deps)));
1824
1825 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1826 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1827
1828 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07001829 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001830 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07001831 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001832 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001833
1834 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001835
1836 ConnectFakeSignaling();
1837 caller()->AddAudioVideoTracks();
1838 callee()->AddAudioVideoTracks();
1839 caller()->CreateAndSetAndSignalOffer();
1840 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1841 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1842 caller()->ice_connection_state(), kDefaultTimeout);
1843 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1844 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08001845
Ying Wangef3998f2019-12-09 13:06:53 +01001846 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1847 "WebRTC.PeerConnection.CandidatePairType_UDP",
1848 webrtc::kIceCandidatePairHostNameHostName));
Harald Alvestrand4f7486a2022-06-02 11:35:49 +00001849 DestroyPeerConnections();
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001850}
1851
Steve Antonede9ca52017-10-16 13:04:27 -07001852// Test that firewalling the ICE connection causes the clients to identify the
1853// disconnected state and then removing the firewall causes them to reconnect.
1854class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08001855 : public PeerConnectionIntegrationBaseTest,
1856 public ::testing::WithParamInterface<
1857 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07001858 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001859 PeerConnectionIntegrationIceStatesTest()
1860 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1861 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07001862 }
1863
1864 void StartStunServer(const SocketAddress& server_address) {
1865 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01001866 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07001867 }
1868
1869 bool TestIPv6() {
1870 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1871 }
1872
1873 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001874 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1875 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07001876 }
1877
1878 std::vector<SocketAddress> CallerAddresses() {
1879 std::vector<SocketAddress> addresses;
1880 addresses.push_back(SocketAddress("1.1.1.1", 0));
1881 if (TestIPv6()) {
1882 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1883 }
1884 return addresses;
1885 }
1886
1887 std::vector<SocketAddress> CalleeAddresses() {
1888 std::vector<SocketAddress> addresses;
1889 addresses.push_back(SocketAddress("2.2.2.2", 0));
1890 if (TestIPv6()) {
1891 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1892 }
1893 return addresses;
1894 }
1895
1896 void SetUpNetworkInterfaces() {
1897 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07001898 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1899 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07001900
1901 // Add network addresses for test.
1902 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001903 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001904 }
1905 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001906 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001907 }
1908 }
1909
1910 private:
1911 uint32_t port_allocator_flags_;
1912 std::unique_ptr<cricket::TestStunServer> stun_server_;
1913};
1914
Yves Gerey100fe632020-01-17 19:15:53 +01001915// Ensure FakeClockForTest is constructed first (see class for rationale).
1916class PeerConnectionIntegrationIceStatesTestWithFakeClock
1917 : public FakeClockForTest,
1918 public PeerConnectionIntegrationIceStatesTest {};
1919
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001920#if !defined(THREAD_SANITIZER)
1921// This test provokes TSAN errors. bugs.webrtc.org/11282
1922
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001923// Tests that if the connection doesn't get set up properly we eventually reach
1924// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01001925TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
1926 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001927 // Block connections to/from the caller and wait for ICE to become
1928 // disconnected.
1929 for (const auto& caller_address : CallerAddresses()) {
1930 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
1931 }
1932
1933 ASSERT_TRUE(CreatePeerConnectionWrappers());
1934 ConnectFakeSignaling();
1935 SetPortAllocatorFlags();
1936 SetUpNetworkInterfaces();
1937 caller()->AddAudioVideoTracks();
1938 caller()->CreateAndSetAndSignalOffer();
1939
1940 // According to RFC7675, if there is no response within 30 seconds then the
1941 // peer should consider the other side to have rejected the connection. This
1942 // is signaled by the state transitioning to "failed".
1943 constexpr int kConsentTimeout = 30000;
1944 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
1945 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01001946 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07001947}
1948
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001949#endif // !defined(THREAD_SANITIZER)
1950
Steve Antonede9ca52017-10-16 13:04:27 -07001951// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
1952// and that the statistics in the metric observers are updated correctly.
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001953// TODO(bugs.webrtc.org/12591): Flaky on Windows.
1954#if defined(WEBRTC_WIN)
1955#define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
1956#else
1957#define MAYBE_VerifyBestConnection VerifyBestConnection
1958#endif
1959TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
Steve Antonede9ca52017-10-16 13:04:27 -07001960 ASSERT_TRUE(CreatePeerConnectionWrappers());
1961 ConnectFakeSignaling();
1962 SetPortAllocatorFlags();
1963 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08001964 caller()->AddAudioVideoTracks();
1965 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07001966 caller()->CreateAndSetAndSignalOffer();
1967
1968 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08001969 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1970 caller()->ice_connection_state(), kDefaultTimeout);
1971 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1972 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07001973
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001974 // TODO(bugs.webrtc.org/9456): Fix it.
1975 const int num_best_ipv4 = webrtc::metrics::NumEvents(
1976 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
1977 const int num_best_ipv6 = webrtc::metrics::NumEvents(
1978 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001979 if (TestIPv6()) {
1980 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
1981 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01001982 EXPECT_METRIC_EQ(0, num_best_ipv4);
1983 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001984 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01001985 EXPECT_METRIC_EQ(1, num_best_ipv4);
1986 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001987 }
1988
Ying Wangef3998f2019-12-09 13:06:53 +01001989 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
1990 "WebRTC.PeerConnection.CandidatePairType_UDP",
1991 webrtc::kIceCandidatePairHostHost));
1992 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1993 "WebRTC.PeerConnection.CandidatePairType_UDP",
1994 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07001995}
1996
1997constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
1998 cricket::PORTALLOCATOR_DISABLE_STUN |
1999 cricket::PORTALLOCATOR_DISABLE_RELAY;
2000constexpr uint32_t kFlagsIPv6NoStun =
2001 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
2002 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
2003constexpr uint32_t kFlagsIPv4Stun =
2004 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
2005
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002006INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002007 PeerConnectionIntegrationTest,
2008 PeerConnectionIntegrationIceStatesTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02002009 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Seth Hampson2f0d7022018-02-20 11:54:42 -08002010 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2011 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2012 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07002013
Yves Gerey100fe632020-01-17 19:15:53 +01002014INSTANTIATE_TEST_SUITE_P(
2015 PeerConnectionIntegrationTest,
2016 PeerConnectionIntegrationIceStatesTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02002017 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Yves Gerey100fe632020-01-17 19:15:53 +01002018 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2019 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2020 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2021
deadbeef1dcb1642017-03-29 21:08:16 -07002022// This test sets up a call between two parties with audio and video.
2023// During the call, the caller restarts ICE and the test verifies that
2024// new ICE candidates are generated and audio and video still can flow, and the
2025// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002026TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07002027 ASSERT_TRUE(CreatePeerConnectionWrappers());
2028 ConnectFakeSignaling();
2029 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08002030 caller()->AddAudioVideoTracks();
2031 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002032 caller()->CreateAndSetAndSignalOffer();
2033 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2034 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2035 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002036 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2037 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07002038
2039 // To verify that the ICE restart actually occurs, get
2040 // ufrag/password/candidates before and after restart.
2041 // Create an SDP string of the first audio candidate for both clients.
2042 const webrtc::IceCandidateCollection* audio_candidates_caller =
2043 caller()->pc()->local_description()->candidates(0);
2044 const webrtc::IceCandidateCollection* audio_candidates_callee =
2045 callee()->pc()->local_description()->candidates(0);
2046 ASSERT_GT(audio_candidates_caller->count(), 0u);
2047 ASSERT_GT(audio_candidates_callee->count(), 0u);
2048 std::string caller_candidate_pre_restart;
2049 ASSERT_TRUE(
2050 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2051 std::string callee_candidate_pre_restart;
2052 ASSERT_TRUE(
2053 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2054 const cricket::SessionDescription* desc =
2055 caller()->pc()->local_description()->description();
2056 std::string caller_ufrag_pre_restart =
2057 desc->transport_infos()[0].description.ice_ufrag;
2058 desc = callee()->pc()->local_description()->description();
2059 std::string callee_ufrag_pre_restart =
2060 desc->transport_infos()[0].description.ice_ufrag;
2061
Alex Drake00c7ecf2019-08-06 10:54:47 -07002062 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002063 // Have the caller initiate an ICE restart.
2064 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2065 caller()->CreateAndSetAndSignalOffer();
2066 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2067 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2068 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002069 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07002070 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2071
2072 // Grab the ufrags/candidates again.
2073 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2074 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2075 ASSERT_GT(audio_candidates_caller->count(), 0u);
2076 ASSERT_GT(audio_candidates_callee->count(), 0u);
2077 std::string caller_candidate_post_restart;
2078 ASSERT_TRUE(
2079 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2080 std::string callee_candidate_post_restart;
2081 ASSERT_TRUE(
2082 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2083 desc = caller()->pc()->local_description()->description();
2084 std::string caller_ufrag_post_restart =
2085 desc->transport_infos()[0].description.ice_ufrag;
2086 desc = callee()->pc()->local_description()->description();
2087 std::string callee_ufrag_post_restart =
2088 desc->transport_infos()[0].description.ice_ufrag;
2089 // Sanity check that an ICE restart was actually negotiated in SDP.
2090 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2091 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2092 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2093 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07002094 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002095
2096 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002097 MediaExpectations media_expectations;
2098 media_expectations.ExpectBidirectionalAudioAndVideo();
2099 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002100}
2101
2102// Verify that audio/video can be received end-to-end when ICE renomination is
2103// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002104TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07002105 PeerConnectionInterface::RTCConfiguration config;
2106 config.enable_ice_renomination = true;
2107 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2108 ConnectFakeSignaling();
2109 // Do normal offer/answer and wait for some frames to be received in each
2110 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002111 caller()->AddAudioVideoTracks();
2112 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002113 caller()->CreateAndSetAndSignalOffer();
2114 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2115 // Sanity check that ICE renomination was actually negotiated.
2116 const cricket::SessionDescription* desc =
2117 caller()->pc()->local_description()->description();
2118 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002119 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002120 }
2121 desc = callee()->pc()->local_description()->description();
2122 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002123 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002124 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08002125 MediaExpectations media_expectations;
2126 media_expectations.ExpectBidirectionalAudioAndVideo();
2127 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002128}
2129
Steve Anton6f25b092017-10-23 09:39:20 -07002130// With a max bundle policy and RTCP muxing, adding a new media description to
2131// the connection should not affect ICE at all because the new media will use
2132// the existing connection.
Rasmus Brandt685be142021-03-15 14:03:38 +01002133// TODO(bugs.webrtc.org/12538): Fails on tsan.
2134#if defined(THREAD_SANITIZER)
2135#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2136 DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2137#else
2138#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2139 AddMediaToConnectedBundleDoesNotRestartIce
2140#endif
Seth Hampson2f0d7022018-02-20 11:54:42 -08002141TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt685be142021-03-15 14:03:38 +01002142 MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07002143 PeerConnectionInterface::RTCConfiguration config;
2144 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2145 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2146 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2147 config, PeerConnectionInterface::RTCConfiguration()));
2148 ConnectFakeSignaling();
2149
Steve Anton15324772018-01-16 10:26:49 -08002150 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002151 caller()->CreateAndSetAndSignalOffer();
2152 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07002153 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2154 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07002155
2156 caller()->clear_ice_connection_state_history();
2157
Steve Anton15324772018-01-16 10:26:49 -08002158 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002159 caller()->CreateAndSetAndSignalOffer();
2160 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2161
2162 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2163}
2164
deadbeef1dcb1642017-03-29 21:08:16 -07002165// This test sets up a call between two parties with audio and video. It then
2166// renegotiates setting the video m-line to "port 0", then later renegotiates
2167// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002168TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002169 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2170 ASSERT_TRUE(CreatePeerConnectionWrappers());
2171 ConnectFakeSignaling();
2172
2173 // Do initial negotiation, only sending media from the caller. Will result in
2174 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08002175 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002176 caller()->CreateAndSetAndSignalOffer();
2177 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2178
2179 // Negotiate again, disabling the video "m=" section (the callee will set the
2180 // port to 0 due to offer_to_receive_video = 0).
Florent Castelli15a38de2022-04-06 00:38:21 +02002181 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002182 PeerConnectionInterface::RTCOfferAnswerOptions options;
2183 options.offer_to_receive_video = 0;
2184 callee()->SetOfferAnswerOptions(options);
2185 } else {
2186 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002187 callee()
2188 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2189 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002190 });
2191 }
deadbeef1dcb1642017-03-29 21:08:16 -07002192 caller()->CreateAndSetAndSignalOffer();
2193 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2194 // Sanity check that video "m=" section was actually rejected.
2195 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2196 callee()->pc()->local_description()->description());
2197 ASSERT_NE(nullptr, answer_video_content);
2198 ASSERT_TRUE(answer_video_content->rejected);
2199
2200 // Enable video and do negotiation again, making sure video is received
2201 // end-to-end, also adding media stream to callee.
Florent Castelli15a38de2022-04-06 00:38:21 +02002202 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002203 PeerConnectionInterface::RTCOfferAnswerOptions options;
2204 options.offer_to_receive_video = 1;
2205 callee()->SetOfferAnswerOptions(options);
2206 } else {
2207 // The caller's transceiver is stopped, so we need to add another track.
2208 auto caller_transceiver =
2209 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002210 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002211 caller()->AddVideoTrack();
2212 }
2213 callee()->AddVideoTrack();
2214 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07002215 caller()->CreateAndSetAndSignalOffer();
2216 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002217
deadbeef1dcb1642017-03-29 21:08:16 -07002218 // Verify the caller receives frames from the newly added stream, and the
2219 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002220 MediaExpectations media_expectations;
2221 media_expectations.CalleeExpectsSomeAudio();
2222 media_expectations.ExpectBidirectionalVideo();
2223 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002224}
2225
deadbeef1dcb1642017-03-29 21:08:16 -07002226// This tests that if we negotiate after calling CreateSender but before we
2227// have a track, then set a track later, frames from the newly-set track are
2228// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002229TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07002230 MediaFlowsAfterEarlyWarmupWithCreateSender) {
2231 ASSERT_TRUE(CreatePeerConnectionWrappers());
2232 ConnectFakeSignaling();
2233 auto caller_audio_sender =
2234 caller()->pc()->CreateSender("audio", "caller_stream");
2235 auto caller_video_sender =
2236 caller()->pc()->CreateSender("video", "caller_stream");
2237 auto callee_audio_sender =
2238 callee()->pc()->CreateSender("audio", "callee_stream");
2239 auto callee_video_sender =
2240 callee()->pc()->CreateSender("video", "callee_stream");
2241 caller()->CreateAndSetAndSignalOffer();
2242 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2243 // Wait for ICE to complete, without any tracks being set.
2244 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2245 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2246 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2247 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2248 // Now set the tracks, and expect frames to immediately start flowing.
Niels Möllerafb246b2022-04-20 14:26:50 +02002249 EXPECT_TRUE(
2250 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2251 EXPECT_TRUE(
2252 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2253 EXPECT_TRUE(
2254 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2255 EXPECT_TRUE(
2256 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002257 MediaExpectations media_expectations;
2258 media_expectations.ExpectBidirectionalAudioAndVideo();
2259 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2260}
2261
2262// This tests that if we negotiate after calling AddTransceiver but before we
2263// have a track, then set a track later, frames from the newly-set tracks are
2264// received end-to-end.
2265TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2266 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2267 ASSERT_TRUE(CreatePeerConnectionWrappers());
2268 ConnectFakeSignaling();
2269 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2270 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2271 auto caller_audio_sender = audio_result.MoveValue()->sender();
2272 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2273 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2274 auto caller_video_sender = video_result.MoveValue()->sender();
2275 callee()->SetRemoteOfferHandler([this] {
2276 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02002277 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002278 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002279 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002280 RtpTransceiverDirection::kSendRecv);
2281 });
2282 caller()->CreateAndSetAndSignalOffer();
2283 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2284 // Wait for ICE to complete, without any tracks being set.
2285 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2286 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2287 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2288 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2289 // Now set the tracks, and expect frames to immediately start flowing.
2290 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2291 auto callee_video_sender = callee()->pc()->GetSenders()[1];
Niels Möllerafb246b2022-04-20 14:26:50 +02002292 ASSERT_TRUE(
2293 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2294 ASSERT_TRUE(
2295 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2296 ASSERT_TRUE(
2297 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2298 ASSERT_TRUE(
2299 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002300 MediaExpectations media_expectations;
2301 media_expectations.ExpectBidirectionalAudioAndVideo();
2302 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002303}
2304
2305// This test verifies that a remote video track can be added via AddStream,
2306// and sent end-to-end. For this particular test, it's simply echoed back
2307// from the caller to the callee, rather than being forwarded to a third
2308// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002309TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07002310 ASSERT_TRUE(CreatePeerConnectionWrappers());
2311 ConnectFakeSignaling();
2312 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08002313 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002314 caller()->CreateAndSetAndSignalOffer();
2315 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002316 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07002317
2318 // Echo the stream back, and do a new offer/anwer (initiated by callee this
2319 // time).
2320 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2321 callee()->CreateAndSetAndSignalOffer();
2322 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2323
Seth Hampson2f0d7022018-02-20 11:54:42 -08002324 MediaExpectations media_expectations;
2325 media_expectations.ExpectBidirectionalVideo();
2326 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002327}
2328
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002329#if !defined(THREAD_SANITIZER)
2330// This test provokes TSAN errors. bugs.webrtc.org/11282
2331
deadbeef1dcb1642017-03-29 21:08:16 -07002332// Test that we achieve the expected end-to-end connection time, using a
2333// fake clock and simulated latency on the media and signaling paths.
2334// We use a TURN<->TURN connection because this is usually the quickest to
2335// set up initially, especially when we're confident the connection will work
2336// and can start sending media before we get a STUN response.
2337//
2338// With various optimizations enabled, here are the network delays we expect to
2339// be on the critical path:
2340// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2341// signaling answer (with DTLS fingerprint).
2342// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2343// using TURN<->TURN pair, and DTLS exchange is 4 packets,
2344// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01002345TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2346 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07002347 static constexpr int media_hop_delay_ms = 50;
2348 static constexpr int signaling_trip_delay_ms = 500;
2349 // For explanation of these values, see comment above.
2350 static constexpr int required_media_hops = 9;
2351 static constexpr int required_signaling_trips = 2;
2352 // For internal delays (such as posting an event asychronously).
2353 static constexpr int allowed_internal_delay_ms = 20;
2354 static constexpr int total_connection_time_ms =
2355 media_hop_delay_ms * required_media_hops +
2356 signaling_trip_delay_ms * required_signaling_trips +
2357 allowed_internal_delay_ms;
2358
2359 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2360 3478};
2361 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2362 0};
2363 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2364 3478};
2365 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2366 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002367 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2368 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002369
Seth Hampsonaed71642018-06-11 07:41:32 -07002370 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2371 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07002372 // Bypass permission check on received packets so media can be sent before
2373 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07002374 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
2375 turn_server_1->set_enable_permission_checks(false);
2376 });
2377 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
2378 turn_server_2->set_enable_permission_checks(false);
2379 });
deadbeef1dcb1642017-03-29 21:08:16 -07002380
2381 PeerConnectionInterface::RTCConfiguration client_1_config;
2382 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2383 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2384 ice_server_1.username = "test";
2385 ice_server_1.password = "test";
2386 client_1_config.servers.push_back(ice_server_1);
2387 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2388 client_1_config.presume_writable_when_fully_relayed = true;
2389
2390 PeerConnectionInterface::RTCConfiguration client_2_config;
2391 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2392 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2393 ice_server_2.username = "test";
2394 ice_server_2.password = "test";
2395 client_2_config.servers.push_back(ice_server_2);
2396 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2397 client_2_config.presume_writable_when_fully_relayed = true;
2398
2399 ASSERT_TRUE(
2400 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2401 // Set up the simulated delays.
2402 SetSignalingDelayMs(signaling_trip_delay_ms);
2403 ConnectFakeSignaling();
2404 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2405 virtual_socket_server()->UpdateDelayDistribution();
2406
2407 // Set "offer to receive audio/video" without adding any tracks, so we just
2408 // set up ICE/DTLS with no media.
2409 PeerConnectionInterface::RTCOfferAnswerOptions options;
2410 options.offer_to_receive_audio = 1;
2411 options.offer_to_receive_video = 1;
2412 caller()->SetOfferAnswerOptions(options);
2413 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07002414 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01002415 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002416 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2417 // If this is not done a DCHECK can be hit in ports.cc, because a large
2418 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07002419 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07002420}
2421
Philipp Hancke1fe14f22022-06-17 11:34:31 +02002422TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2423 OnIceCandidateFlushesGetStatsCache) {
2424 ASSERT_TRUE(CreatePeerConnectionWrappers());
2425 ConnectFakeSignaling();
2426 caller()->AddAudioTrack();
2427
2428 // Call getStats, assert there are no candidates.
2429 rtc::scoped_refptr<const webrtc::RTCStatsReport> first_report =
2430 caller()->NewGetStats();
2431 ASSERT_TRUE(first_report);
2432 auto first_candidate_stats =
2433 first_report->GetStatsOfType<webrtc::RTCLocalIceCandidateStats>();
2434 ASSERT_EQ(first_candidate_stats.size(), 0u);
2435
Philipp Hanckea09b9212022-06-22 07:41:22 +02002436 // Create an offer at the caller and set it as remote description on the
2437 // callee.
Philipp Hancke1fe14f22022-06-17 11:34:31 +02002438 caller()->CreateAndSetAndSignalOffer();
Philipp Hancke1fe14f22022-06-17 11:34:31 +02002439 // Call getStats again, assert there are candidates now.
2440 rtc::scoped_refptr<const webrtc::RTCStatsReport> second_report =
2441 caller()->NewGetStats();
2442 ASSERT_TRUE(second_report);
2443 auto second_candidate_stats =
2444 second_report->GetStatsOfType<webrtc::RTCLocalIceCandidateStats>();
2445 ASSERT_NE(second_candidate_stats.size(), 0u);
2446
2447 // The fake clock ensures that no time has passed so the cache must have been
2448 // explicitly invalidated.
2449 EXPECT_EQ(first_report->timestamp_us(), second_report->timestamp_us());
2450}
2451
Philipp Hanckea09b9212022-06-22 07:41:22 +02002452TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2453 AddIceCandidateFlushesGetStatsCache) {
2454 ASSERT_TRUE(CreatePeerConnectionWrappers());
2455 ConnectFakeSignalingForSdpOnly();
2456 caller()->AddAudioTrack();
2457
2458 // Start candidate gathering and wait for it to complete. Candidates are not
2459 // signalled.
2460 caller()->CreateAndSetAndSignalOffer();
2461 ASSERT_TRUE_SIMULATED_WAIT(caller()->IceGatheringStateComplete(),
2462 kDefaultTimeout, FakeClock());
2463
2464 // Call getStats, assert there are no candidates.
2465 rtc::scoped_refptr<const webrtc::RTCStatsReport> first_report =
2466 caller()->NewGetStats();
2467 ASSERT_TRUE(first_report);
2468 auto first_candidate_stats =
2469 first_report->GetStatsOfType<webrtc::RTCRemoteIceCandidateStats>();
2470 ASSERT_EQ(first_candidate_stats.size(), 0u);
2471
2472 // Add a "fake" candidate.
2473 absl::optional<RTCError> result;
2474 caller()->pc()->AddIceCandidate(
2475 absl::WrapUnique(webrtc::CreateIceCandidate(
2476 "", 0,
2477 "candidate:2214029314 1 udp 2122260223 127.0.0.1 49152 typ host",
2478 nullptr)),
2479 [&result](RTCError r) { result = r; });
2480 ASSERT_TRUE_WAIT(result.has_value(), kDefaultTimeout);
2481 ASSERT_TRUE(result.value().ok());
2482
2483 // Call getStats again, assert there is a remote candidate now.
2484 rtc::scoped_refptr<const webrtc::RTCStatsReport> second_report =
2485 caller()->NewGetStats();
2486 ASSERT_TRUE(second_report);
2487 auto second_candidate_stats =
2488 second_report->GetStatsOfType<webrtc::RTCRemoteIceCandidateStats>();
2489 ASSERT_EQ(second_candidate_stats.size(), 1u);
2490
2491 // The fake clock ensures that no time has passed so the cache must have been
2492 // explicitly invalidated.
2493 EXPECT_EQ(first_report->timestamp_us(), second_report->timestamp_us());
2494}
2495
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002496#endif // !defined(THREAD_SANITIZER)
2497
Jonas Orelandbdcee282017-10-10 14:01:40 +02002498// Verify that a TurnCustomizer passed in through RTCConfiguration
2499// is actually used by the underlying TURN candidate pair.
2500// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002501TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02002502 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2503 3478};
2504 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2505 0};
2506 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2507 3478};
2508 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2509 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002510 CreateTurnServer(turn_server_1_internal_address,
2511 turn_server_1_external_address);
2512 CreateTurnServer(turn_server_2_internal_address,
2513 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002514
2515 PeerConnectionInterface::RTCConfiguration client_1_config;
2516 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2517 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2518 ice_server_1.username = "test";
2519 ice_server_1.password = "test";
2520 client_1_config.servers.push_back(ice_server_1);
2521 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002522 auto* customizer1 = CreateTurnCustomizer();
2523 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002524
2525 PeerConnectionInterface::RTCConfiguration client_2_config;
2526 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2527 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2528 ice_server_2.username = "test";
2529 ice_server_2.password = "test";
2530 client_2_config.servers.push_back(ice_server_2);
2531 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002532 auto* customizer2 = CreateTurnCustomizer();
2533 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002534
2535 ASSERT_TRUE(
2536 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2537 ConnectFakeSignaling();
2538
2539 // Set "offer to receive audio/video" without adding any tracks, so we just
2540 // set up ICE/DTLS with no media.
2541 PeerConnectionInterface::RTCOfferAnswerOptions options;
2542 options.offer_to_receive_audio = 1;
2543 options.offer_to_receive_video = 1;
2544 caller()->SetOfferAnswerOptions(options);
2545 caller()->CreateAndSetAndSignalOffer();
2546 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2547
Seth Hampsonaed71642018-06-11 07:41:32 -07002548 ExpectTurnCustomizerCountersIncremented(customizer1);
2549 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002550}
2551
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002552// Verifies that you can use TCP instead of UDP to connect to a TURN server and
2553// send media between the caller and the callee.
2554TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2555 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2556 3478};
2557 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2558
2559 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07002560 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2561 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002562
2563 webrtc::PeerConnectionInterface::IceServer ice_server;
2564 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2565 ice_server.username = "test";
2566 ice_server.password = "test";
2567
2568 PeerConnectionInterface::RTCConfiguration client_1_config;
2569 client_1_config.servers.push_back(ice_server);
2570 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2571
2572 PeerConnectionInterface::RTCConfiguration client_2_config;
2573 client_2_config.servers.push_back(ice_server);
2574 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2575
2576 ASSERT_TRUE(
2577 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2578
2579 // Do normal offer/answer and wait for ICE to complete.
2580 ConnectFakeSignaling();
2581 caller()->AddAudioVideoTracks();
2582 callee()->AddAudioVideoTracks();
2583 caller()->CreateAndSetAndSignalOffer();
2584 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2585 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2586 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2587
2588 MediaExpectations media_expectations;
2589 media_expectations.ExpectBidirectionalAudioAndVideo();
2590 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2591}
2592
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002593// Verify that a SSLCertificateVerifier passed in through
2594// PeerConnectionDependencies is actually used by the underlying SSL
2595// implementation to determine whether a certificate presented by the TURN
2596// server is accepted by the client. Note that openssladapter_unittest.cc
2597// contains more detailed, lower-level tests.
2598TEST_P(PeerConnectionIntegrationTest,
2599 SSLCertificateVerifierUsedForTurnConnections) {
2600 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2601 3478};
2602 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2603
2604 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2605 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002606 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2607 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002608
2609 webrtc::PeerConnectionInterface::IceServer ice_server;
2610 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2611 ice_server.username = "test";
2612 ice_server.password = "test";
2613
2614 PeerConnectionInterface::RTCConfiguration client_1_config;
2615 client_1_config.servers.push_back(ice_server);
2616 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2617
2618 PeerConnectionInterface::RTCConfiguration client_2_config;
2619 client_2_config.servers.push_back(ice_server);
2620 // Setting the type to kRelay forces the connection to go through a TURN
2621 // server.
2622 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2623
2624 // Get a copy to the pointer so we can verify calls later.
2625 rtc::TestCertificateVerifier* client_1_cert_verifier =
2626 new rtc::TestCertificateVerifier();
2627 client_1_cert_verifier->verify_certificate_ = true;
2628 rtc::TestCertificateVerifier* client_2_cert_verifier =
2629 new rtc::TestCertificateVerifier();
2630 client_2_cert_verifier->verify_certificate_ = true;
2631
2632 // Create the dependencies with the test certificate verifier.
2633 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2634 client_1_deps.tls_cert_verifier =
2635 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2636 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2637 client_2_deps.tls_cert_verifier =
2638 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2639
2640 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2641 client_1_config, std::move(client_1_deps), client_2_config,
2642 std::move(client_2_deps)));
2643 ConnectFakeSignaling();
2644
2645 // Set "offer to receive audio/video" without adding any tracks, so we just
2646 // set up ICE/DTLS with no media.
2647 PeerConnectionInterface::RTCOfferAnswerOptions options;
2648 options.offer_to_receive_audio = 1;
2649 options.offer_to_receive_video = 1;
2650 caller()->SetOfferAnswerOptions(options);
2651 caller()->CreateAndSetAndSignalOffer();
2652 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2653
2654 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2655 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002656}
2657
Qingsi Wang25ec8882019-11-15 12:33:05 -08002658// Test that the injected ICE transport factory is used to create ICE transports
2659// for WebRTC connections.
2660TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2661 PeerConnectionInterface::RTCConfiguration default_config;
2662 PeerConnectionDependencies dependencies(nullptr);
2663 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2664 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2665 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02002666 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2667 std::move(dependencies), nullptr,
2668 /*reset_encoder_factory=*/false,
2669 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08002670 ASSERT_TRUE(wrapper);
2671 wrapper->CreateDataChannel();
Tommi87f70902021-04-27 14:43:08 +02002672 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02002673 wrapper->pc()->SetLocalDescription(observer.get(),
Qingsi Wang25ec8882019-11-15 12:33:05 -08002674 wrapper->CreateOfferAndWait().release());
2675}
2676
deadbeefc964d0b2017-04-03 10:03:35 -07002677// Test that audio and video flow end-to-end when codec names don't use the
2678// expected casing, given that they're supposed to be case insensitive. To test
2679// this, all but one codec is removed from each media description, and its
2680// casing is changed.
2681//
2682// In the past, this has regressed and caused crashes/black video, due to the
2683// fact that code at some layers was doing case-insensitive comparisons and
2684// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002685TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07002686 ASSERT_TRUE(CreatePeerConnectionWrappers());
2687 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002688 caller()->AddAudioVideoTracks();
2689 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07002690
2691 // Remove all but one audio/video codec (opus and VP8), and change the
2692 // casing of the caller's generated offer.
2693 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2694 cricket::AudioContentDescription* audio =
2695 GetFirstAudioContentDescription(description);
2696 ASSERT_NE(nullptr, audio);
2697 auto audio_codecs = audio->codecs();
2698 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2699 [](const cricket::AudioCodec& codec) {
2700 return codec.name != "opus";
2701 }),
2702 audio_codecs.end());
2703 ASSERT_EQ(1u, audio_codecs.size());
2704 audio_codecs[0].name = "OpUs";
2705 audio->set_codecs(audio_codecs);
2706
2707 cricket::VideoContentDescription* video =
2708 GetFirstVideoContentDescription(description);
2709 ASSERT_NE(nullptr, video);
2710 auto video_codecs = video->codecs();
2711 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2712 [](const cricket::VideoCodec& codec) {
2713 return codec.name != "VP8";
2714 }),
2715 video_codecs.end());
2716 ASSERT_EQ(1u, video_codecs.size());
2717 video_codecs[0].name = "vP8";
2718 video->set_codecs(video_codecs);
2719 });
2720
2721 caller()->CreateAndSetAndSignalOffer();
2722 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2723
2724 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002725 MediaExpectations media_expectations;
2726 media_expectations.ExpectBidirectionalAudioAndVideo();
2727 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07002728}
2729
Jonas Oreland49ac5952018-09-26 16:04:32 +02002730TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07002731 ASSERT_TRUE(CreatePeerConnectionWrappers());
2732 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002733 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07002734 caller()->CreateAndSetAndSignalOffer();
2735 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07002736 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002737 MediaExpectations media_expectations;
2738 media_expectations.CalleeExpectsSomeAudio(1);
2739 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02002740 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07002741 auto receiver = callee()->pc()->GetReceivers()[0];
2742 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002743 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07002744 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2745 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02002746 sources[0].source_id());
2747 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2748}
2749
2750TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2751 ASSERT_TRUE(CreatePeerConnectionWrappers());
2752 ConnectFakeSignaling();
2753 caller()->AddVideoTrack();
2754 caller()->CreateAndSetAndSignalOffer();
2755 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2756 // Wait for one video frame to be received by the callee.
2757 MediaExpectations media_expectations;
2758 media_expectations.CalleeExpectsSomeVideo(1);
2759 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2760 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2761 auto receiver = callee()->pc()->GetReceivers()[0];
2762 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2763 auto sources = receiver->GetSources();
2764 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02002765 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002766 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2767 sources[0].source_id());
2768 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07002769}
2770
deadbeef2f425aa2017-04-14 10:41:32 -07002771// Test that if a track is removed and added again with a different stream ID,
2772// the new stream ID is successfully communicated in SDP and media continues to
2773// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002774// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2775// it will not reuse a transceiver that has already been sending. After creating
2776// a new transceiver it tries to create an offer with two senders of the same
2777// track ids and it fails.
2778TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07002779 ASSERT_TRUE(CreatePeerConnectionWrappers());
2780 ConnectFakeSignaling();
2781
deadbeef2f425aa2017-04-14 10:41:32 -07002782 // Add track using stream 1, do offer/answer.
2783 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2784 caller()->CreateLocalAudioTrack();
2785 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07002786 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07002787 caller()->CreateAndSetAndSignalOffer();
2788 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002789 {
2790 MediaExpectations media_expectations;
2791 media_expectations.CalleeExpectsSomeAudio(1);
2792 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2793 }
deadbeef2f425aa2017-04-14 10:41:32 -07002794 // Remove the sender, and create a new one with the new stream.
Harald Alvestrand93dd7632022-01-19 12:28:45 +00002795 caller()->pc()->RemoveTrackOrError(sender);
Steve Antond78323f2018-07-11 11:13:44 -07002796 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07002797 caller()->CreateAndSetAndSignalOffer();
2798 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2799 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002800 {
2801 MediaExpectations media_expectations;
2802 media_expectations.CalleeExpectsSomeAudio();
2803 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2804 }
deadbeef2f425aa2017-04-14 10:41:32 -07002805}
2806
Seth Hampson2f0d7022018-02-20 11:54:42 -08002807TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02002808 ASSERT_TRUE(CreatePeerConnectionWrappers());
2809 ConnectFakeSignaling();
2810
Mirko Bonadei317a1f02019-09-17 17:06:18 +02002811 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002812 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
Ali Tofighb7821ce2022-07-12 16:08:13 +02002813 ON_CALL(*output, Write(::testing::A<absl::string_view>()))
Björn Terelius63299a32022-07-05 10:58:52 +02002814 .WillByDefault(::testing::Return(true));
Ali Tofighb7821ce2022-07-12 16:08:13 +02002815 EXPECT_CALL(*output, Write(::testing::A<absl::string_view>()))
Björn Terelius63299a32022-07-05 10:58:52 +02002816 .Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01002817 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2818 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02002819
Steve Anton15324772018-01-16 10:26:49 -08002820 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02002821 caller()->CreateAndSetAndSignalOffer();
2822 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2823}
2824
Steve Antonede9ca52017-10-16 13:04:27 -07002825// Test that if candidates are only signaled by applying full session
2826// descriptions (instead of using AddIceCandidate), the peers can connect to
2827// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002828TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07002829 ASSERT_TRUE(CreatePeerConnectionWrappers());
2830 // Each side will signal the session descriptions but not candidates.
2831 ConnectFakeSignalingForSdpOnly();
2832
2833 // Add audio video track and exchange the initial offer/answer with media
2834 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08002835 caller()->AddAudioVideoTracks();
2836 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002837 caller()->CreateAndSetAndSignalOffer();
2838
2839 // Wait for all candidates to be gathered on both the caller and callee.
2840 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2841 caller()->ice_gathering_state(), kDefaultTimeout);
2842 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2843 callee()->ice_gathering_state(), kDefaultTimeout);
2844
2845 // The candidates will now be included in the session description, so
2846 // signaling them will start the ICE connection.
2847 caller()->CreateAndSetAndSignalOffer();
2848 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2849
2850 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002851 MediaExpectations media_expectations;
2852 media_expectations.ExpectBidirectionalAudioAndVideo();
2853 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07002854}
2855
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002856#if !defined(THREAD_SANITIZER)
2857// These tests provokes TSAN errors. See bugs.webrtc.org/11305.
2858
henrika5f6bf242017-11-01 11:06:56 +01002859// Test that SetAudioPlayout can be used to disable audio playout from the
2860// start, then later enable it. This may be useful, for example, if the caller
2861// needs to play a local ringtone until some event occurs, after which it
2862// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002863TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01002864 ASSERT_TRUE(CreatePeerConnectionWrappers());
2865 ConnectFakeSignaling();
2866
2867 // Set up audio-only call where audio playout is disabled on caller's side.
2868 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08002869 caller()->AddAudioTrack();
2870 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002871 caller()->CreateAndSetAndSignalOffer();
2872 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2873
2874 // Pump messages for a second.
2875 WAIT(false, 1000);
2876 // Since audio playout is disabled, the caller shouldn't have received
2877 // anything (at the playout level, at least).
2878 EXPECT_EQ(0, caller()->audio_frames_received());
2879 // As a sanity check, make sure the callee (for which playout isn't disabled)
2880 // did still see frames on its audio level.
2881 ASSERT_GT(callee()->audio_frames_received(), 0);
2882
2883 // Enable playout again, and ensure audio starts flowing.
2884 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002885 MediaExpectations media_expectations;
2886 media_expectations.ExpectBidirectionalAudio();
2887 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01002888}
2889
Harald Alvestrand39993842021-02-17 09:05:31 +00002890double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
henrika5f6bf242017-11-01 11:06:56 +01002891 auto report = pc->NewGetStats();
2892 auto track_stats_list =
2893 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2894 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
2895 for (const auto* track_stats : track_stats_list) {
2896 if (track_stats->remote_source.is_defined() &&
2897 *track_stats->remote_source) {
2898 remote_track_stats = track_stats;
2899 break;
2900 }
2901 }
2902
2903 if (!remote_track_stats->total_audio_energy.is_defined()) {
2904 return 0.0;
2905 }
2906 return *remote_track_stats->total_audio_energy;
2907}
2908
2909// Test that if audio playout is disabled via the SetAudioPlayout() method, then
2910// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002911TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01002912 DisableAudioPlayoutStillGeneratesAudioStats) {
2913 ASSERT_TRUE(CreatePeerConnectionWrappers());
2914 ConnectFakeSignaling();
2915
2916 // Set up audio-only call where playout is disabled but audio-processing is
2917 // still active.
Steve Anton15324772018-01-16 10:26:49 -08002918 caller()->AddAudioTrack();
2919 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002920 caller()->pc()->SetAudioPlayout(false);
2921
2922 caller()->CreateAndSetAndSignalOffer();
2923 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2924
2925 // Wait for the callee to receive audio stats.
2926 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
2927}
2928
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002929#endif // !defined(THREAD_SANITIZER)
2930
henrika4f167df2017-11-01 14:45:55 +01002931// Test that SetAudioRecording can be used to disable audio recording from the
2932// start, then later enable it. This may be useful, for example, if the caller
2933// wants to ensure that no audio resources are active before a certain state
2934// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002935TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01002936 ASSERT_TRUE(CreatePeerConnectionWrappers());
2937 ConnectFakeSignaling();
2938
2939 // Set up audio-only call where audio recording is disabled on caller's side.
2940 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08002941 caller()->AddAudioTrack();
2942 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01002943 caller()->CreateAndSetAndSignalOffer();
2944 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2945
2946 // Pump messages for a second.
2947 WAIT(false, 1000);
2948 // Since caller has disabled audio recording, the callee shouldn't have
2949 // received anything.
2950 EXPECT_EQ(0, callee()->audio_frames_received());
2951 // As a sanity check, make sure the caller did still see frames on its
2952 // audio level since audio recording is enabled on the calle side.
2953 ASSERT_GT(caller()->audio_frames_received(), 0);
2954
2955 // Enable audio recording again, and ensure audio starts flowing.
2956 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002957 MediaExpectations media_expectations;
2958 media_expectations.ExpectBidirectionalAudio();
2959 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01002960}
2961
Qingsi Wang7685e862018-06-11 20:15:46 -07002962TEST_P(PeerConnectionIntegrationTest,
2963 IceEventsGeneratedAndLoggedInRtcEventLog) {
2964 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
2965 ConnectFakeSignaling();
2966 PeerConnectionInterface::RTCOfferAnswerOptions options;
2967 options.offer_to_receive_audio = 1;
2968 caller()->SetOfferAnswerOptions(options);
2969 caller()->CreateAndSetAndSignalOffer();
2970 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2971 ASSERT_NE(nullptr, caller()->event_log_factory());
2972 ASSERT_NE(nullptr, callee()->event_log_factory());
2973 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002974 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002975 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002976 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002977 ASSERT_NE(nullptr, caller_event_log);
2978 ASSERT_NE(nullptr, callee_event_log);
2979 int caller_ice_config_count = caller_event_log->GetEventCount(
2980 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2981 int caller_ice_event_count = caller_event_log->GetEventCount(
2982 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2983 int callee_ice_config_count = callee_event_log->GetEventCount(
2984 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2985 int callee_ice_event_count = callee_event_log->GetEventCount(
2986 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2987 EXPECT_LT(0, caller_ice_config_count);
2988 EXPECT_LT(0, caller_ice_event_count);
2989 EXPECT_LT(0, callee_ice_config_count);
2990 EXPECT_LT(0, callee_ice_event_count);
2991}
2992
Qingsi Wangc129c352019-04-18 10:41:58 -07002993TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07002994 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2995 3478};
2996 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2997
2998 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
2999
3000 webrtc::PeerConnectionInterface::IceServer ice_server;
3001 ice_server.urls.push_back("turn:88.88.88.0:3478");
3002 ice_server.username = "test";
3003 ice_server.password = "test";
3004
3005 PeerConnectionInterface::RTCConfiguration caller_config;
3006 caller_config.servers.push_back(ice_server);
3007 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3008 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003009 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003010
3011 PeerConnectionInterface::RTCConfiguration callee_config;
3012 callee_config.servers.push_back(ice_server);
3013 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3014 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003015 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003016
3017 ASSERT_TRUE(
3018 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3019
3020 // Do normal offer/answer and wait for ICE to complete.
3021 ConnectFakeSignaling();
3022 caller()->AddAudioVideoTracks();
3023 callee()->AddAudioVideoTracks();
3024 caller()->CreateAndSetAndSignalOffer();
3025 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3026 // Since we are doing continual gathering, the ICE transport does not reach
3027 // kIceGatheringComplete (see
3028 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
3029 // kIceConnectionComplete.
3030 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3031 caller()->ice_connection_state(), kDefaultTimeout);
3032 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3033 callee()->ice_connection_state(), kDefaultTimeout);
3034 // Note that we cannot use the metric
Artem Titovcfea2182021-08-10 01:22:31 +02003035 // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
Qingsi Wangc129c352019-04-18 10:41:58 -07003036 // metric is only populated when we reach kIceConnectionComplete in the
3037 // current implementation.
3038 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3039 caller()->last_candidate_gathered().type());
3040 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3041 callee()->last_candidate_gathered().type());
3042
3043 // Loosen the caller's candidate filter.
3044 caller_config = caller()->pc()->GetConfiguration();
3045 caller_config.type = webrtc::PeerConnectionInterface::kAll;
3046 caller()->pc()->SetConfiguration(caller_config);
3047 // We should have gathered a new host candidate.
3048 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3049 caller()->last_candidate_gathered().type(), kDefaultTimeout);
3050
3051 // Loosen the callee's candidate filter.
3052 callee_config = callee()->pc()->GetConfiguration();
3053 callee_config.type = webrtc::PeerConnectionInterface::kAll;
3054 callee()->pc()->SetConfiguration(callee_config);
3055 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3056 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02003057
3058 // Create an offer and verify that it does not contain an ICE restart (i.e new
3059 // ice credentials).
3060 std::string caller_ufrag_pre_offer = caller()
3061 ->pc()
3062 ->local_description()
3063 ->description()
3064 ->transport_infos()[0]
3065 .description.ice_ufrag;
3066 caller()->CreateAndSetAndSignalOffer();
3067 std::string caller_ufrag_post_offer = caller()
3068 ->pc()
3069 ->local_description()
3070 ->description()
3071 ->transport_infos()[0]
3072 .description.ice_ufrag;
3073 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07003074}
3075
Eldar Relloda13ea22019-06-01 12:23:43 +03003076TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03003077 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3078 3478};
3079 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3080
3081 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3082
3083 webrtc::PeerConnectionInterface::IceServer ice_server;
3084 ice_server.urls.push_back("turn:88.88.88.0:3478");
3085 ice_server.username = "test";
3086 ice_server.password = "123";
3087
3088 PeerConnectionInterface::RTCConfiguration caller_config;
3089 caller_config.servers.push_back(ice_server);
3090 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3091 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3092
3093 PeerConnectionInterface::RTCConfiguration callee_config;
3094 callee_config.servers.push_back(ice_server);
3095 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3096 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3097
3098 ASSERT_TRUE(
3099 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3100
3101 // Do normal offer/answer and wait for ICE to complete.
3102 ConnectFakeSignaling();
3103 caller()->AddAudioVideoTracks();
3104 callee()->AddAudioVideoTracks();
3105 caller()->CreateAndSetAndSignalOffer();
3106 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3107 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3108 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3109 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02003110 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03003111}
3112
Eldar Rellofa8019c2020-05-14 11:59:33 +03003113TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3114 webrtc::PeerConnectionInterface::IceServer ice_server;
3115 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3116 ice_server.username = "test";
3117 ice_server.password = "test";
3118
3119 PeerConnectionInterface::RTCConfiguration caller_config;
3120 caller_config.servers.push_back(ice_server);
3121 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3122 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3123
3124 PeerConnectionInterface::RTCConfiguration callee_config;
3125 callee_config.servers.push_back(ice_server);
3126 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3127 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3128
3129 ASSERT_TRUE(
3130 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3131
3132 // Do normal offer/answer and wait for ICE to complete.
3133 ConnectFakeSignaling();
3134 caller()->AddAudioVideoTracks();
3135 callee()->AddAudioVideoTracks();
3136 caller()->CreateAndSetAndSignalOffer();
3137 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3138 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3139 EXPECT_EQ(caller()->error_event().address, "");
3140}
3141
Eldar Rello5ab79e62019-10-09 18:29:44 +03003142TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3143 AudioKeepsFlowingAfterImplicitRollback) {
3144 PeerConnectionInterface::RTCConfiguration config;
3145 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3146 config.enable_implicit_rollback = true;
3147 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3148 ConnectFakeSignaling();
3149 caller()->AddAudioTrack();
3150 callee()->AddAudioTrack();
3151 caller()->CreateAndSetAndSignalOffer();
3152 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3153 MediaExpectations media_expectations;
3154 media_expectations.ExpectBidirectionalAudio();
3155 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3156 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
3157 caller()->AddVideoTrack();
3158 callee()->AddVideoTrack();
Tommi87f70902021-04-27 14:43:08 +02003159 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003160 callee()->pc()->SetLocalDescription(observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003161 callee()->CreateOfferAndWait().release());
3162 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3163 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
3164 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3165 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3166}
3167
3168TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3169 ImplicitRollbackVisitsStableState) {
3170 RTCConfiguration config;
3171 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3172 config.enable_implicit_rollback = true;
3173
3174 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3175
Tommi87f70902021-04-27 14:43:08 +02003176 auto sld_observer =
3177 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003178 callee()->pc()->SetLocalDescription(sld_observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003179 callee()->CreateOfferAndWait().release());
3180 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3181 EXPECT_EQ(sld_observer->error(), "");
3182
Tommi87f70902021-04-27 14:43:08 +02003183 auto srd_observer =
3184 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003185 callee()->pc()->SetRemoteDescription(
Niels Möllerafb246b2022-04-20 14:26:50 +02003186 srd_observer.get(), caller()->CreateOfferAndWait().release());
Eldar Rello5ab79e62019-10-09 18:29:44 +03003187 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3188 EXPECT_EQ(srd_observer->error(), "");
3189
3190 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3191 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3192 PeerConnectionInterface::kStable,
3193 PeerConnectionInterface::kHaveRemoteOffer));
3194}
3195
Eldar Rellobd9c33a2020-10-01 17:52:45 +03003196TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3197 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3198 ASSERT_TRUE(CreatePeerConnectionWrappers());
3199 ConnectFakeSignaling();
3200 caller()->AddVideoTrack();
3201 callee()->AddVideoTrack();
3202 auto munger = [](cricket::SessionDescription* desc) {
3203 cricket::VideoContentDescription* video =
3204 GetFirstVideoContentDescription(desc);
3205 auto codecs = video->codecs();
3206 for (auto&& codec : codecs) {
3207 if (codec.name == "H264") {
3208 std::string value;
3209 // The parameter is not supposed to be present in SDP by default.
3210 EXPECT_FALSE(
3211 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3212 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3213 std::string(""));
3214 }
3215 }
3216 video->set_codecs(codecs);
3217 };
3218 // Munge local offer for SLD.
3219 caller()->SetGeneratedSdpMunger(munger);
3220 // Munge remote answer for SRD.
3221 caller()->SetReceivedSdpMunger(munger);
3222 caller()->CreateAndSetAndSignalOffer();
3223 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3224 // Observe that after munging the parameter is present in generated SDP.
3225 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3226 cricket::VideoContentDescription* video =
3227 GetFirstVideoContentDescription(desc);
3228 for (auto&& codec : video->codecs()) {
3229 if (codec.name == "H264") {
3230 std::string value;
3231 EXPECT_TRUE(
3232 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3233 }
3234 }
3235 });
3236 caller()->CreateOfferAndWait();
3237}
3238
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003239TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00003240 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003241 PeerConnectionInterface::RTCConfiguration config;
3242 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3243 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3244 ConnectFakeSignaling();
3245 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3246
3247 caller()->CreateAndSetAndSignalOffer();
3248 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3249 int current_size = caller()->pc()->GetTransceivers().size();
3250 // Add more tracks until we get close to having issues.
3251 // Issues have been seen at:
3252 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003253 // - 16 tracks on android_arm_dbg (flaky)
3254 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003255 // Double the number of tracks
3256 for (int i = 0; i < current_size; i++) {
3257 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3258 }
3259 current_size = caller()->pc()->GetTransceivers().size();
3260 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3261 auto start_time_ms = rtc::TimeMillis();
3262 caller()->CreateAndSetAndSignalOffer();
3263 // We want to stop when the time exceeds one second.
3264 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3265 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3266 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3267 ASSERT_GT(1000, elapsed_time_ms)
3268 << "Audio transceivers: Negotiation took too long after "
3269 << current_size << " tracks added";
3270 }
3271}
3272
3273TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3274 RenegotiateManyVideoTransceivers) {
3275 PeerConnectionInterface::RTCConfiguration config;
3276 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3277 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3278 ConnectFakeSignaling();
3279 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3280
3281 caller()->CreateAndSetAndSignalOffer();
3282 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3283 int current_size = caller()->pc()->GetTransceivers().size();
3284 // Add more tracks until we get close to having issues.
3285 // Issues have been seen at:
3286 // - 96 on a Linux workstation
3287 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3288 // - 32 on android_arm64_rel and linux_dbg bots
Harald Alvestrand785e23b2021-03-15 21:26:27 +00003289 // - 16 on Android 64 (Nexus 5x)
3290 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003291 // Double the number of tracks
3292 for (int i = 0; i < current_size; i++) {
3293 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3294 }
3295 current_size = caller()->pc()->GetTransceivers().size();
3296 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3297 auto start_time_ms = rtc::TimeMillis();
3298 caller()->CreateAndSetAndSignalOffer();
3299 // We want to stop when the time exceeds one second.
3300 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3301 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3302 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3303 ASSERT_GT(1000, elapsed_time_ms)
3304 << "Video transceivers: Negotiation took too long after "
3305 << current_size << " tracks added";
3306 }
3307}
3308
Harald Alvestrand94324f22021-01-13 12:31:53 +00003309TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3310 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3311 PeerConnectionInterface::RTCConfiguration config;
3312 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3313 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3314 ConnectFakeSignaling();
3315 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003316 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003317 caller()->CreateAndSetAndSignalOffer();
3318 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3319 // Wait until we can see the audio flowing.
3320 MediaExpectations media_expectations;
3321 media_expectations.CalleeExpectsSomeAudio();
3322 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3323
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003324 // Get the baseline numbers for audio_packets and audio_delay
3325 // in both directions.
3326 caller()->StartWatchingDelayStats();
3327 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003328
3329 int current_size = caller()->pc()->GetTransceivers().size();
3330 // Add more tracks until we get close to having issues.
3331 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003332 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00003333 // Double the number of tracks
3334 for (int i = 0; i < current_size; i++) {
3335 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3336 }
3337 current_size = caller()->pc()->GetTransceivers().size();
3338 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3339 auto start_time_ms = rtc::TimeMillis();
3340 caller()->CreateAndSetAndSignalOffer();
3341 // We want to stop when the time exceeds one second.
3342 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3343 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3344 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3345 // This is a guard against the test using excessive amounts of time.
3346 ASSERT_GT(5000, elapsed_time_ms)
3347 << "Video transceivers: Negotiation took too long after "
3348 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003349 caller()->UpdateDelayStats("caller reception", current_size);
3350 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00003351 }
3352}
3353
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003354INSTANTIATE_TEST_SUITE_P(
3355 PeerConnectionIntegrationTest,
3356 PeerConnectionIntegrationTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003357 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003358 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3359 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3360 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Steve Antond3679212018-01-17 17:41:02 -08003361
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003362INSTANTIATE_TEST_SUITE_P(
3363 PeerConnectionIntegrationTest,
3364 PeerConnectionIntegrationTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02003365 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003366 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3367 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3368 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Yves Gerey100fe632020-01-17 19:15:53 +01003369
Steve Anton74255ff2018-01-24 18:32:57 -08003370// Tests that verify interoperability between Plan B and Unified Plan
3371// PeerConnections.
3372class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003373 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08003374 public ::testing::WithParamInterface<
3375 std::tuple<SdpSemantics, SdpSemantics>> {
3376 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003377 // Setting the SdpSemantics for the base test to kDefault does not matter
3378 // because we specify not to use the test semantics when creating
Harald Alvestrand39993842021-02-17 09:05:31 +00003379 // PeerConnectionIntegrationWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08003380 PeerConnectionIntegrationInteropTest()
Florent Castelli15a38de2022-04-06 00:38:21 +02003381 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED),
Seth Hampson2f0d7022018-02-20 11:54:42 -08003382 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08003383 callee_semantics_(std::get<1>(GetParam())) {}
3384
3385 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07003386 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3387 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08003388 }
3389
3390 const SdpSemantics caller_semantics_;
3391 const SdpSemantics callee_semantics_;
3392};
3393
3394TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3395 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3396 ConnectFakeSignaling();
3397
3398 caller()->CreateAndSetAndSignalOffer();
3399 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3400}
3401
3402TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3403 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3404 ConnectFakeSignaling();
3405 auto audio_sender = caller()->AddAudioTrack();
3406
3407 caller()->CreateAndSetAndSignalOffer();
3408 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3409
3410 // Verify that one audio receiver has been created on the remote and that it
3411 // has the same track ID as the sending track.
3412 auto receivers = callee()->pc()->GetReceivers();
3413 ASSERT_EQ(1u, receivers.size());
3414 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3415 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3416
Seth Hampson2f0d7022018-02-20 11:54:42 -08003417 MediaExpectations media_expectations;
3418 media_expectations.CalleeExpectsSomeAudio();
3419 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003420}
3421
3422TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3423 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3424 ConnectFakeSignaling();
3425 auto video_sender = caller()->AddVideoTrack();
3426 auto audio_sender = caller()->AddAudioTrack();
3427
3428 caller()->CreateAndSetAndSignalOffer();
3429 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3430
3431 // Verify that one audio and one video receiver have been created on the
3432 // remote and that they have the same track IDs as the sending tracks.
3433 auto audio_receivers =
3434 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3435 ASSERT_EQ(1u, audio_receivers.size());
3436 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3437 auto video_receivers =
3438 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3439 ASSERT_EQ(1u, video_receivers.size());
3440 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3441
Seth Hampson2f0d7022018-02-20 11:54:42 -08003442 MediaExpectations media_expectations;
3443 media_expectations.CalleeExpectsSomeAudioAndVideo();
3444 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003445}
3446
3447TEST_P(PeerConnectionIntegrationInteropTest,
3448 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3449 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3450 ConnectFakeSignaling();
3451 caller()->AddAudioVideoTracks();
3452 callee()->AddAudioVideoTracks();
3453
3454 caller()->CreateAndSetAndSignalOffer();
3455 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3456
Seth Hampson2f0d7022018-02-20 11:54:42 -08003457 MediaExpectations media_expectations;
3458 media_expectations.ExpectBidirectionalAudioAndVideo();
3459 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003460}
3461
3462TEST_P(PeerConnectionIntegrationInteropTest,
3463 ReverseRolesOneAudioLocalToOneVideoRemote) {
3464 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3465 ConnectFakeSignaling();
3466 caller()->AddAudioTrack();
3467 callee()->AddVideoTrack();
3468
3469 caller()->CreateAndSetAndSignalOffer();
3470 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3471
3472 // Verify that only the audio track has been negotiated.
3473 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3474 // Might also check that the callee's NegotiationNeeded flag is set.
3475
3476 // Reverse roles.
3477 callee()->CreateAndSetAndSignalOffer();
3478 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3479
Seth Hampson2f0d7022018-02-20 11:54:42 -08003480 MediaExpectations media_expectations;
3481 media_expectations.CallerExpectsSomeVideo();
3482 media_expectations.CalleeExpectsSomeAudio();
3483 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003484}
3485
Taylor Brandstetter1c7ecef2021-08-11 12:38:35 -07003486TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3487 ASSERT_TRUE(CreatePeerConnectionWrappers());
3488 ConnectFakeSignaling();
3489 caller()->AddAudioVideoTracks();
3490 caller()->CreateAndSetAndSignalOffer();
3491 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3492 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3493 caller()->ExpectCandidates(0);
3494 callee()->ExpectCandidates(0);
3495 caller()->AddAudioTrack();
3496 caller()->CreateAndSetAndSignalOffer();
3497 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3498}
3499
Harald Alvestrand35ba0c52022-05-05 07:37:41 +00003500TEST_P(PeerConnectionIntegrationTest, MediaCallWithoutMediaEngineFails) {
3501 ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
3502 // AddTrack should fail.
3503 EXPECT_FALSE(
3504 caller()->pc()->AddTrack(caller()->CreateLocalAudioTrack(), {}).ok());
3505}
3506
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003507INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07003508 PeerConnectionIntegrationTest,
3509 PeerConnectionIntegrationInteropTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003510 Values(std::make_tuple(SdpSemantics::kPlanB_DEPRECATED,
3511 SdpSemantics::kUnifiedPlan),
3512 std::make_tuple(SdpSemantics::kUnifiedPlan,
3513 SdpSemantics::kPlanB_DEPRECATED)));
Steve Antonba42e992018-04-09 14:10:01 -07003514
3515// Test that if the Unified Plan side offers two video tracks then the Plan B
3516// side will only see the first one and ignore the second.
3517TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07003518 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
Florent Castelli15a38de2022-04-06 00:38:21 +02003519 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB_DEPRECATED));
Steve Anton74255ff2018-01-24 18:32:57 -08003520 ConnectFakeSignaling();
3521 auto first_sender = caller()->AddVideoTrack();
3522 caller()->AddVideoTrack();
3523
3524 caller()->CreateAndSetAndSignalOffer();
3525 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3526
3527 // Verify that there is only one receiver and it corresponds to the first
3528 // added track.
3529 auto receivers = callee()->pc()->GetReceivers();
3530 ASSERT_EQ(1u, receivers.size());
3531 EXPECT_TRUE(receivers[0]->track()->enabled());
3532 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3533
Seth Hampson2f0d7022018-02-20 11:54:42 -08003534 MediaExpectations media_expectations;
3535 media_expectations.CalleeExpectsSomeVideo();
3536 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003537}
3538
Steve Anton2bed3972019-01-04 17:04:30 -08003539// Test that if the initial offer tagged BUNDLE section is rejected due to its
3540// associated RtpTransceiver being stopped and another transceiver is added,
3541// then renegotiation causes the callee to receive the new video track without
3542// error.
3543// This is a regression test for bugs.webrtc.org/9954
3544TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3545 ReOfferWithStoppedBundleTaggedTransceiver) {
3546 RTCConfiguration config;
3547 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3548 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3549 ConnectFakeSignaling();
3550 auto audio_transceiver_or_error =
3551 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3552 ASSERT_TRUE(audio_transceiver_or_error.ok());
3553 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3554
3555 caller()->CreateAndSetAndSignalOffer();
3556 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3557 {
3558 MediaExpectations media_expectations;
3559 media_expectations.CalleeExpectsSomeAudio();
3560 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3561 }
3562
Harald Alvestrand6060df52020-08-11 09:54:02 +02003563 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08003564 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3565
3566 caller()->CreateAndSetAndSignalOffer();
3567 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3568 {
3569 MediaExpectations media_expectations;
3570 media_expectations.CalleeExpectsSomeVideo();
3571 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3572 }
3573}
3574
Harald Alvestrandbedb6052020-08-20 14:50:10 +02003575TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3576 StopTransceiverRemovesDtlsTransports) {
3577 RTCConfiguration config;
3578 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3579 ConnectFakeSignaling();
3580 auto audio_transceiver_or_error =
3581 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3582 ASSERT_TRUE(audio_transceiver_or_error.ok());
3583 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3584
3585 caller()->CreateAndSetAndSignalOffer();
3586 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3587
3588 audio_transceiver->StopStandard();
3589 caller()->CreateAndSetAndSignalOffer();
3590 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3591 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3592 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3593 caller()->pc()->ice_gathering_state());
3594 EXPECT_THAT(caller()->ice_gathering_state_history(),
3595 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3596 PeerConnectionInterface::kIceGatheringComplete,
3597 PeerConnectionInterface::kIceGatheringNew));
3598}
3599
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003600TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00003601 StopTransceiverStopsAndRemovesTransceivers) {
3602 RTCConfiguration config;
3603 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3604 ConnectFakeSignaling();
3605 auto audio_transceiver_or_error =
3606 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3607 ASSERT_TRUE(audio_transceiver_or_error.ok());
3608 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3609
3610 caller()->CreateAndSetAndSignalOffer();
3611 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3612 caller_transceiver->StopStandard();
3613
3614 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3615 caller()->CreateAndSetAndSignalOffer();
3616 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3617 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3618 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3619 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3620 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3621 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3622 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3623 EXPECT_TRUE(caller_transceiver->stopped());
3624 EXPECT_TRUE(callee_transceiver->stopped());
3625}
3626
3627TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003628 StopTransceiverEndsIncomingAudioTrack) {
3629 RTCConfiguration config;
3630 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3631 ConnectFakeSignaling();
3632 auto audio_transceiver_or_error =
3633 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3634 ASSERT_TRUE(audio_transceiver_or_error.ok());
3635 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3636
3637 caller()->CreateAndSetAndSignalOffer();
3638 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3639 auto caller_track = audio_transceiver->receiver()->track();
3640 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3641 audio_transceiver->StopStandard();
3642 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3643 caller_track->state());
3644 caller()->CreateAndSetAndSignalOffer();
3645 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3646 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3647 callee_track->state());
3648}
3649
3650TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3651 StopTransceiverEndsIncomingVideoTrack) {
3652 RTCConfiguration config;
3653 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3654 ConnectFakeSignaling();
3655 auto audio_transceiver_or_error =
3656 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3657 ASSERT_TRUE(audio_transceiver_or_error.ok());
3658 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3659
3660 caller()->CreateAndSetAndSignalOffer();
3661 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3662 auto caller_track = audio_transceiver->receiver()->track();
3663 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3664 audio_transceiver->StopStandard();
3665 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3666 caller_track->state());
3667 caller()->CreateAndSetAndSignalOffer();
3668 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3669 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3670 callee_track->state());
3671}
3672
Jonas Oreland65455162022-06-08 11:25:46 +02003673TEST_P(PeerConnectionIntegrationTest, EndToEndRtpSenderVideoEncoderSelector) {
3674 ASSERT_TRUE(
3675 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
3676 ConnectFakeSignaling();
3677 // Add one-directional video, from caller to callee.
3678 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
3679 caller()->CreateLocalVideoTrack();
3680 auto sender = caller()->AddTrack(caller_track);
3681 PeerConnectionInterface::RTCOfferAnswerOptions options;
3682 options.offer_to_receive_video = 0;
3683 caller()->SetOfferAnswerOptions(options);
3684 caller()->CreateAndSetAndSignalOffer();
3685 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3686 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
3687
3688 std::unique_ptr<MockEncoderSelector> encoder_selector =
3689 std::make_unique<MockEncoderSelector>();
3690 EXPECT_CALL(*encoder_selector, OnCurrentEncoder);
3691
3692 sender->SetEncoderSelector(std::move(encoder_selector));
3693
3694 // Expect video to be received in one direction.
3695 MediaExpectations media_expectations;
3696 media_expectations.CallerExpectsNoVideo();
3697 media_expectations.CalleeExpectsSomeVideo();
3698
3699 EXPECT_TRUE(ExpectNewFrames(media_expectations));
3700}
3701
Harald Alvestrand89c40e22021-02-17 08:58:35 +00003702} // namespace
Harald Alvestrand39993842021-02-17 09:05:31 +00003703
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01003704} // namespace webrtc