blob: d6ac0c82c98222d09010d087046777e43bdfed8b [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"
Harald Alvestrandf8f7b702022-05-05 13:21:19 +000028#include "absl/strings/string_view.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000029#include "absl/types/optional.h"
30#include "api/async_resolver_factory.h"
31#include "api/candidate.h"
32#include "api/crypto/crypto_options.h"
33#include "api/dtmf_sender_interface.h"
34#include "api/ice_transport_interface.h"
35#include "api/jsep.h"
Steve Anton10542f22019-01-11 09:11:00 -080036#include "api/media_stream_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000037#include "api/media_types.h"
Steve Anton10542f22019-01-11 09:11:00 -080038#include "api/peer_connection_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000039#include "api/rtc_error.h"
40#include "api/rtc_event_log/rtc_event.h"
41#include "api/rtc_event_log/rtc_event_log.h"
42#include "api/rtc_event_log_output.h"
43#include "api/rtp_parameters.h"
Steve Anton10542f22019-01-11 09:11:00 -080044#include "api/rtp_receiver_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000045#include "api/rtp_sender_interface.h"
46#include "api/rtp_transceiver_direction.h"
47#include "api/rtp_transceiver_interface.h"
48#include "api/scoped_refptr.h"
49#include "api/stats/rtc_stats.h"
50#include "api/stats/rtc_stats_report.h"
51#include "api/stats/rtcstats_objects.h"
Jonas Oreland65455162022-06-08 11:25:46 +020052#include "api/test/mock_encoder_selector.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000053#include "api/transport/rtp/rtp_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080054#include "api/uma_metrics.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000055#include "api/units/time_delta.h"
56#include "api/video/video_rotation.h"
57#include "logging/rtc_event_log/fake_rtc_event_log.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070058#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000059#include "media/base/codec.h"
60#include "media/base/media_constants.h"
61#include "media/base/stream_params.h"
Steve Anton10542f22019-01-11 09:11:00 -080062#include "p2p/base/mock_async_resolver.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000063#include "p2p/base/port.h"
64#include "p2p/base/port_allocator.h"
Steve Anton10542f22019-01-11 09:11:00 -080065#include "p2p/base/port_interface.h"
66#include "p2p/base/test_stun_server.h"
67#include "p2p/base/test_turn_customizer.h"
68#include "p2p/base/test_turn_server.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000069#include "p2p/base/transport_description.h"
70#include "p2p/base/transport_info.h"
Steve Anton10542f22019-01-11 09:11:00 -080071#include "pc/media_session.h"
72#include "pc/peer_connection.h"
73#include "pc/peer_connection_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080074#include "pc/session_description.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000075#include "pc/test/fake_periodic_video_source.h"
76#include "pc/test/integration_test_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080077#include "pc/test/mock_peer_connection_observers.h"
Jonas Olssonb75d9e92019-02-22 10:33:29 +010078#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070079#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080080#include "rtc_base/fake_network.h"
81#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020082#include "rtc_base/gunit.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000083#include "rtc_base/helpers.h"
84#include "rtc_base/location.h"
85#include "rtc_base/logging.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000086#include "rtc_base/socket_address.h"
87#include "rtc_base/ssl_certificate.h"
88#include "rtc_base/ssl_fingerprint.h"
89#include "rtc_base/ssl_identity.h"
90#include "rtc_base/ssl_stream_adapter.h"
Steve Anton10542f22019-01-11 09:11:00 -080091#include "rtc_base/test_certificate_verifier.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000092#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080093#include "rtc_base/time_utils.h"
94#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020095#include "system_wrappers/include/metrics.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000096#include "test/gmock.h"
97#include "test/gtest.h"
deadbeef1dcb1642017-03-29 21:08:16 -070098
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010099namespace webrtc {
Harald Alvestrand39993842021-02-17 09:05:31 +0000100
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +0100101namespace {
102
Seth Hampson2f0d7022018-02-20 11:54:42 -0800103class PeerConnectionIntegrationTest
104 : public PeerConnectionIntegrationBaseTest,
Evan Shrubsole7619b7c2022-03-01 10:42:44 +0100105 public ::testing::WithParamInterface<
106 std::tuple<SdpSemantics, std::string>> {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800107 protected:
108 PeerConnectionIntegrationTest()
Evan Shrubsole7619b7c2022-03-01 10:42:44 +0100109 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam()),
110 std::get<1>(GetParam())) {}
Seth Hampson2f0d7022018-02-20 11:54:42 -0800111};
112
Yves Gerey100fe632020-01-17 19:15:53 +0100113// Fake clock must be set before threads are started to prevent race on
114// Set/GetClockForTesting().
115// To achieve that, multiple inheritance is used as a mixin pattern
116// where order of construction is finely controlled.
117// This also ensures peerconnection is closed before switching back to non-fake
118// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
119class FakeClockForTest : public rtc::ScopedFakeClock {
120 protected:
121 FakeClockForTest() {
122 // Some things use a time of "0" as a special value, so we need to start out
123 // the fake clock at a nonzero time.
124 // TODO(deadbeef): Fix this.
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100125 AdvanceTime(webrtc::TimeDelta::Seconds(1));
Yves Gerey100fe632020-01-17 19:15:53 +0100126 }
127
128 // Explicit handle.
129 ScopedFakeClock& FakeClock() { return *this; }
130};
131
132// Ensure FakeClockForTest is constructed first (see class for rationale).
133class PeerConnectionIntegrationTestWithFakeClock
134 : public FakeClockForTest,
135 public PeerConnectionIntegrationTest {};
136
Seth Hampson2f0d7022018-02-20 11:54:42 -0800137class PeerConnectionIntegrationTestPlanB
138 : public PeerConnectionIntegrationBaseTest {
139 protected:
140 PeerConnectionIntegrationTestPlanB()
Florent Castelli15a38de2022-04-06 00:38:21 +0200141 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
Seth Hampson2f0d7022018-02-20 11:54:42 -0800142};
143
144class PeerConnectionIntegrationTestUnifiedPlan
145 : public PeerConnectionIntegrationBaseTest {
146 protected:
147 PeerConnectionIntegrationTestUnifiedPlan()
148 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
149};
150
deadbeef1dcb1642017-03-29 21:08:16 -0700151// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
152// includes testing that the callback is invoked if an observer is connected
153// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800154TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700155 RtpReceiverObserverOnFirstPacketReceived) {
156 ASSERT_TRUE(CreatePeerConnectionWrappers());
157 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800158 caller()->AddAudioVideoTracks();
159 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700160 // Start offer/answer exchange and wait for it to complete.
161 caller()->CreateAndSetAndSignalOffer();
162 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
163 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200164 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
165 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700166 // Wait for all "first packet received" callbacks to be fired.
167 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800168 absl::c_all_of(caller()->rtp_receiver_observers(),
169 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
170 return o->first_packet_received();
171 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700172 kMaxWaitForFramesMs);
173 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800174 absl::c_all_of(callee()->rtp_receiver_observers(),
175 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
176 return o->first_packet_received();
177 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700178 kMaxWaitForFramesMs);
179 // If new observers are set after the first packet was already received, the
180 // callback should still be invoked.
181 caller()->ResetRtpReceiverObservers();
182 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200183 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
184 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700185 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800186 absl::c_all_of(caller()->rtp_receiver_observers(),
187 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
188 return o->first_packet_received();
189 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700190 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800191 absl::c_all_of(callee()->rtp_receiver_observers(),
192 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
193 return o->first_packet_received();
194 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700195}
196
197class DummyDtmfObserver : public DtmfSenderObserverInterface {
198 public:
199 DummyDtmfObserver() : completed_(false) {}
200
201 // Implements DtmfSenderObserverInterface.
202 void OnToneChange(const std::string& tone) override {
203 tones_.push_back(tone);
204 if (tone.empty()) {
205 completed_ = true;
206 }
207 }
208
209 const std::vector<std::string>& tones() const { return tones_; }
210 bool completed() const { return completed_; }
211
212 private:
213 bool completed_;
214 std::vector<std::string> tones_;
215};
216
Artem Titov880fa812021-07-30 22:30:23 +0200217// Assumes `sender` already has an audio track added and the offer/answer
deadbeef1dcb1642017-03-29 21:08:16 -0700218// exchange is done.
Harald Alvestrand39993842021-02-17 09:05:31 +0000219void TestDtmfFromSenderToReceiver(PeerConnectionIntegrationWrapper* sender,
220 PeerConnectionIntegrationWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -0800221 // We should be able to get a DTMF sender from the local sender.
222 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
223 sender->pc()->GetSenders().at(0)->GetDtmfSender();
224 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -0700225 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -0700226 dtmf_sender->RegisterObserver(&observer);
227
228 // Test the DtmfSender object just created.
229 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
230 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
231
232 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
233 std::vector<std::string> tones = {"1", "a", ""};
234 EXPECT_EQ(tones, observer.tones());
235 dtmf_sender->UnregisterObserver();
236 // TODO(deadbeef): Verify the tones were actually received end-to-end.
237}
238
239// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
240// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800241TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -0700242 ASSERT_TRUE(CreatePeerConnectionWrappers());
243 ConnectFakeSignaling();
244 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -0800245 caller()->AddAudioTrack();
246 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700247 caller()->CreateAndSetAndSignalOffer();
248 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -0700249 // DTLS must finish before the DTMF sender can be used reliably.
250 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -0700251 TestDtmfFromSenderToReceiver(caller(), callee());
252 TestDtmfFromSenderToReceiver(callee(), caller());
253}
254
255// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
256// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800257TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -0700258 ASSERT_TRUE(CreatePeerConnectionWrappers());
259 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +0100260
deadbeef1dcb1642017-03-29 21:08:16 -0700261 // Do normal offer/answer and wait for some frames to be received in each
262 // direction.
Steve Anton15324772018-01-16 10:26:49 -0800263 caller()->AddAudioVideoTracks();
264 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700265 caller()->CreateAndSetAndSignalOffer();
266 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800267 MediaExpectations media_expectations;
268 media_expectations.ExpectBidirectionalAudioAndVideo();
269 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +0100270 EXPECT_METRIC_LE(
271 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
272 webrtc::kEnumCounterKeyProtocolDtls));
273 EXPECT_METRIC_EQ(
274 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
275 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -0700276}
277
Harald Alvestrandca327932022-04-04 15:37:31 +0000278#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06 +0000279// Uses SDES instead of DTLS for key agreement.
280TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
281 PeerConnectionInterface::RTCConfiguration sdes_config;
282 sdes_config.enable_dtls_srtp.emplace(false);
283 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
284 ConnectFakeSignaling();
285
286 // Do normal offer/answer and wait for some frames to be received in each
287 // direction.
288 caller()->AddAudioVideoTracks();
289 callee()->AddAudioVideoTracks();
290 caller()->CreateAndSetAndSignalOffer();
291 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
292 MediaExpectations media_expectations;
293 media_expectations.ExpectBidirectionalAudioAndVideo();
294 ASSERT_TRUE(ExpectNewFrames(media_expectations));
295 EXPECT_METRIC_LE(
296 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
297 webrtc::kEnumCounterKeyProtocolSdes));
298 EXPECT_METRIC_EQ(
299 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
300 webrtc::kEnumCounterKeyProtocolDtls));
301}
Harald Alvestrandca327932022-04-04 15:37:31 +0000302#endif
Harald Alvestrand50b95522021-11-18 10:01:06 +0000303
Artem Titov880fa812021-07-30 22:30:23 +0200304// Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions`
Steve Anton9a44b2d2019-07-12 12:58:30 -0700305// option to offer encrypted versions of all header extensions alongside the
306// unencrypted versions.
307TEST_P(PeerConnectionIntegrationTest,
308 EndToEndCallWithEncryptedRtpHeaderExtensions) {
309 CryptoOptions crypto_options;
310 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
311 PeerConnectionInterface::RTCConfiguration config;
312 config.crypto_options = crypto_options;
313 // Note: This allows offering >14 RTP header extensions.
314 config.offer_extmap_allow_mixed = true;
315 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
316 ConnectFakeSignaling();
317
318 // Do normal offer/answer and wait for some frames to be received in each
319 // direction.
320 caller()->AddAudioVideoTracks();
321 callee()->AddAudioVideoTracks();
322 caller()->CreateAndSetAndSignalOffer();
323 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
324 MediaExpectations media_expectations;
325 media_expectations.ExpectBidirectionalAudioAndVideo();
326 ASSERT_TRUE(ExpectNewFrames(media_expectations));
327}
328
deadbeef1dcb1642017-03-29 21:08:16 -0700329// This test sets up a call between two parties with a source resolution of
330// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800331TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700332 Send1280By720ResolutionAndReceive16To9AspectRatio) {
333 ASSERT_TRUE(CreatePeerConnectionWrappers());
334 ConnectFakeSignaling();
335
Niels Möller5c7efe72018-05-11 10:34:46 +0200336 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
337 webrtc::FakePeriodicVideoSource::Config config;
338 config.width = 1280;
339 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +0200340 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200341 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
342 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -0700343
344 // Do normal offer/answer and wait for at least one frame to be received in
345 // each direction.
346 caller()->CreateAndSetAndSignalOffer();
347 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
348 callee()->min_video_frames_received_per_track() > 0,
349 kMaxWaitForFramesMs);
350
351 // Check rendered aspect ratio.
352 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
353 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
354 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
355 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
356}
357
358// This test sets up an one-way call, with media only from caller to
359// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800360TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -0700361 ASSERT_TRUE(CreatePeerConnectionWrappers());
362 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800363 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700364 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800365 MediaExpectations media_expectations;
366 media_expectations.CalleeExpectsSomeAudioAndVideo();
367 media_expectations.CallerExpectsNoAudio();
368 media_expectations.CallerExpectsNoVideo();
369 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700370}
371
Johannes Kron3e983682020-03-29 22:17:00 +0200372// Tests that send only works without the caller having a decoder factory and
373// the callee having an encoder factory.
374TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
375 ASSERT_TRUE(
376 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
377 ConnectFakeSignaling();
378 // Add one-directional video, from caller to callee.
379 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
380 caller()->CreateLocalVideoTrack();
381 caller()->AddTrack(caller_track);
382 PeerConnectionInterface::RTCOfferAnswerOptions options;
383 options.offer_to_receive_video = 0;
384 caller()->SetOfferAnswerOptions(options);
385 caller()->CreateAndSetAndSignalOffer();
386 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
387 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
388
389 // Expect video to be received in one direction.
390 MediaExpectations media_expectations;
391 media_expectations.CallerExpectsNoVideo();
392 media_expectations.CalleeExpectsSomeVideo();
393
394 EXPECT_TRUE(ExpectNewFrames(media_expectations));
395}
396
397// Tests that receive only works without the caller having an encoder factory
398// and the callee having a decoder factory.
399TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
400 ASSERT_TRUE(
401 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
402 ConnectFakeSignaling();
403 // Add one-directional video, from callee to caller.
404 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
405 callee()->CreateLocalVideoTrack();
406 callee()->AddTrack(callee_track);
407 PeerConnectionInterface::RTCOfferAnswerOptions options;
408 options.offer_to_receive_video = 1;
409 caller()->SetOfferAnswerOptions(options);
410 caller()->CreateAndSetAndSignalOffer();
411 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
412 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
413
414 // Expect video to be received in one direction.
415 MediaExpectations media_expectations;
416 media_expectations.CallerExpectsSomeVideo();
417 media_expectations.CalleeExpectsNoVideo();
418
419 EXPECT_TRUE(ExpectNewFrames(media_expectations));
420}
421
422TEST_P(PeerConnectionIntegrationTest,
423 EndToEndCallAddReceiveVideoToSendOnlyCall) {
424 ASSERT_TRUE(CreatePeerConnectionWrappers());
425 ConnectFakeSignaling();
426 // Add one-directional video, from caller to callee.
427 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
428 caller()->CreateLocalVideoTrack();
429 caller()->AddTrack(caller_track);
430 caller()->CreateAndSetAndSignalOffer();
431 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
432
433 // Add receive video.
434 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
435 callee()->CreateLocalVideoTrack();
436 callee()->AddTrack(callee_track);
437 caller()->CreateAndSetAndSignalOffer();
438 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
439
440 // Ensure that video frames are received end-to-end.
441 MediaExpectations media_expectations;
442 media_expectations.ExpectBidirectionalVideo();
443 ASSERT_TRUE(ExpectNewFrames(media_expectations));
444}
445
446TEST_P(PeerConnectionIntegrationTest,
447 EndToEndCallAddSendVideoToReceiveOnlyCall) {
448 ASSERT_TRUE(CreatePeerConnectionWrappers());
449 ConnectFakeSignaling();
450 // Add one-directional video, from callee to caller.
451 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
452 callee()->CreateLocalVideoTrack();
453 callee()->AddTrack(callee_track);
454 caller()->CreateAndSetAndSignalOffer();
455 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
456
457 // Add send video.
458 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
459 caller()->CreateLocalVideoTrack();
460 caller()->AddTrack(caller_track);
461 caller()->CreateAndSetAndSignalOffer();
462 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
463
464 // Expect video to be received in one direction.
465 MediaExpectations media_expectations;
466 media_expectations.ExpectBidirectionalVideo();
467 ASSERT_TRUE(ExpectNewFrames(media_expectations));
468}
469
470TEST_P(PeerConnectionIntegrationTest,
471 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
472 ASSERT_TRUE(CreatePeerConnectionWrappers());
473 ConnectFakeSignaling();
474 // Add send video, from caller to callee.
475 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
476 caller()->CreateLocalVideoTrack();
477 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
478 caller()->AddTrack(caller_track);
479 // Add receive video, from callee to caller.
480 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
481 callee()->CreateLocalVideoTrack();
482
483 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
484 callee()->AddTrack(callee_track);
485 caller()->CreateAndSetAndSignalOffer();
486 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
487
488 // Remove receive video (i.e., callee sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000489 callee()->pc()->RemoveTrackOrError(callee_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200490
491 caller()->CreateAndSetAndSignalOffer();
492 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
493
494 // Expect one-directional video.
495 MediaExpectations media_expectations;
496 media_expectations.CallerExpectsNoVideo();
497 media_expectations.CalleeExpectsSomeVideo();
498
499 ASSERT_TRUE(ExpectNewFrames(media_expectations));
500}
501
502TEST_P(PeerConnectionIntegrationTest,
503 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
504 ASSERT_TRUE(CreatePeerConnectionWrappers());
505 ConnectFakeSignaling();
506 // Add send video, from caller to callee.
507 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
508 caller()->CreateLocalVideoTrack();
509 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
510 caller()->AddTrack(caller_track);
511 // Add receive video, from callee to caller.
512 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
513 callee()->CreateLocalVideoTrack();
514
515 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
516 callee()->AddTrack(callee_track);
517 caller()->CreateAndSetAndSignalOffer();
518 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
519
520 // Remove send video (i.e., caller sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000521 caller()->pc()->RemoveTrackOrError(caller_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200522
523 caller()->CreateAndSetAndSignalOffer();
524 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
525
526 // Expect one-directional video.
527 MediaExpectations media_expectations;
528 media_expectations.CalleeExpectsNoVideo();
529 media_expectations.CallerExpectsSomeVideo();
530
531 ASSERT_TRUE(ExpectNewFrames(media_expectations));
532}
533
deadbeef1dcb1642017-03-29 21:08:16 -0700534// This test sets up a audio call initially, with the callee rejecting video
535// initially. Then later the callee decides to upgrade to audio/video, and
536// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800537TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -0700538 ASSERT_TRUE(CreatePeerConnectionWrappers());
539 ConnectFakeSignaling();
540 // Initially, offer an audio/video stream from the caller, but refuse to
541 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -0800542 caller()->AddAudioVideoTracks();
543 callee()->AddAudioTrack();
Florent Castelli15a38de2022-04-06 00:38:21 +0200544 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800545 PeerConnectionInterface::RTCOfferAnswerOptions options;
546 options.offer_to_receive_video = 0;
547 callee()->SetOfferAnswerOptions(options);
548 } else {
549 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200550 callee()
551 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
552 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800553 });
554 }
deadbeef1dcb1642017-03-29 21:08:16 -0700555 // Do offer/answer and make sure audio is still received end-to-end.
556 caller()->CreateAndSetAndSignalOffer();
557 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800558 {
559 MediaExpectations media_expectations;
560 media_expectations.ExpectBidirectionalAudio();
561 media_expectations.ExpectNoVideo();
562 ASSERT_TRUE(ExpectNewFrames(media_expectations));
563 }
deadbeef1dcb1642017-03-29 21:08:16 -0700564 // Sanity check that the callee's description has a rejected video section.
565 ASSERT_NE(nullptr, callee()->pc()->local_description());
566 const ContentInfo* callee_video_content =
567 GetFirstVideoContent(callee()->pc()->local_description()->description());
568 ASSERT_NE(nullptr, callee_video_content);
569 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800570
deadbeef1dcb1642017-03-29 21:08:16 -0700571 // Now negotiate with video and ensure negotiation succeeds, with video
572 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -0800573 callee()->AddVideoTrack();
Florent Castelli15a38de2022-04-06 00:38:21 +0200574 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800575 PeerConnectionInterface::RTCOfferAnswerOptions options;
576 options.offer_to_receive_video = 1;
577 callee()->SetOfferAnswerOptions(options);
578 } else {
579 callee()->SetRemoteOfferHandler(nullptr);
580 caller()->SetRemoteOfferHandler([this] {
581 // The caller creates a new transceiver to receive video on when receiving
582 // the offer, but by default it is send only.
583 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200584 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800585 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +0200586 transceivers[1]->receiver()->media_type());
Niels Möllerafb246b2022-04-20 14:26:50 +0200587 transceivers[1]->sender()->SetTrack(
588 caller()->CreateLocalVideoTrack().get());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200589 transceivers[1]->SetDirectionWithError(
590 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800591 });
592 }
deadbeef1dcb1642017-03-29 21:08:16 -0700593 callee()->CreateAndSetAndSignalOffer();
594 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800595 {
596 // Expect additional audio frames to be received after the upgrade.
597 MediaExpectations media_expectations;
598 media_expectations.ExpectBidirectionalAudioAndVideo();
599 ASSERT_TRUE(ExpectNewFrames(media_expectations));
600 }
deadbeef1dcb1642017-03-29 21:08:16 -0700601}
602
deadbeef4389b4d2017-09-07 09:07:36 -0700603// Simpler than the above test; just add an audio track to an established
604// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800605TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -0700606 ASSERT_TRUE(CreatePeerConnectionWrappers());
607 ConnectFakeSignaling();
608 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -0800609 caller()->AddVideoTrack();
610 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700611 caller()->CreateAndSetAndSignalOffer();
612 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
613 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -0800614 caller()->AddAudioTrack();
615 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700616 caller()->CreateAndSetAndSignalOffer();
617 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
618 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800619 MediaExpectations media_expectations;
620 media_expectations.ExpectBidirectionalAudioAndVideo();
621 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -0700622}
623
deadbeef1dcb1642017-03-29 21:08:16 -0700624// This test sets up a non-bundled call and negotiates bundling at the same
625// time as starting an ICE restart. When bundling is in effect in the restart,
626// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800627TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -0700628 ASSERT_TRUE(CreatePeerConnectionWrappers());
629 ConnectFakeSignaling();
630
Steve Anton15324772018-01-16 10:26:49 -0800631 caller()->AddAudioVideoTracks();
632 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700633 // Remove the bundle group from the SDP received by the callee.
634 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
635 desc->RemoveGroupByName("BUNDLE");
636 });
637 caller()->CreateAndSetAndSignalOffer();
638 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800639 {
640 MediaExpectations media_expectations;
641 media_expectations.ExpectBidirectionalAudioAndVideo();
642 ASSERT_TRUE(ExpectNewFrames(media_expectations));
643 }
deadbeef1dcb1642017-03-29 21:08:16 -0700644 // Now stop removing the BUNDLE group, and trigger an ICE restart.
645 callee()->SetReceivedSdpMunger(nullptr);
646 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
647 caller()->CreateAndSetAndSignalOffer();
648 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
649
650 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800651 {
652 MediaExpectations media_expectations;
653 media_expectations.ExpectBidirectionalAudioAndVideo();
654 ASSERT_TRUE(ExpectNewFrames(media_expectations));
655 }
deadbeef1dcb1642017-03-29 21:08:16 -0700656}
657
658// Test CVO (Coordination of Video Orientation). If a video source is rotated
659// and both peers support the CVO RTP header extension, the actual video frames
660// don't need to be encoded in different resolutions, since the rotation is
661// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800662TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700663 ASSERT_TRUE(CreatePeerConnectionWrappers());
664 ConnectFakeSignaling();
665 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800666 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700667 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800668 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700669 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
670
671 // Wait for video frames to be received by both sides.
672 caller()->CreateAndSetAndSignalOffer();
673 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
674 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
675 callee()->min_video_frames_received_per_track() > 0,
676 kMaxWaitForFramesMs);
677
678 // Ensure that the aspect ratio is unmodified.
679 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
680 // not just assumed.
681 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
682 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
683 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
684 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
685 // Ensure that the CVO bits were surfaced to the renderer.
686 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
687 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
688}
689
690// Test that when the CVO extension isn't supported, video is rotated the
691// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800692TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700693 ASSERT_TRUE(CreatePeerConnectionWrappers());
694 ConnectFakeSignaling();
695 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800696 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700697 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800698 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700699 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
700
701 // Remove the CVO extension from the offered SDP.
702 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
703 cricket::VideoContentDescription* video =
704 GetFirstVideoContentDescription(desc);
705 video->ClearRtpHeaderExtensions();
706 });
707 // Wait for video frames to be received by both sides.
708 caller()->CreateAndSetAndSignalOffer();
709 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
710 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
711 callee()->min_video_frames_received_per_track() > 0,
712 kMaxWaitForFramesMs);
713
714 // Expect that the aspect ratio is inversed to account for the 90/270 degree
715 // rotation.
716 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
717 // not just assumed.
718 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
719 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
720 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
721 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
722 // Expect that each endpoint is unaware of the rotation of the other endpoint.
723 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
724 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
725}
726
deadbeef1dcb1642017-03-29 21:08:16 -0700727// Test that if the answerer rejects the audio m= section, no audio is sent or
728// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800729TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700730 ASSERT_TRUE(CreatePeerConnectionWrappers());
731 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800732 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200733 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800734 // Only add video track for callee, and set offer_to_receive_audio to 0, so
735 // it will reject the audio m= section completely.
736 PeerConnectionInterface::RTCOfferAnswerOptions options;
737 options.offer_to_receive_audio = 0;
738 callee()->SetOfferAnswerOptions(options);
739 } else {
740 // Stopping the audio RtpTransceiver will cause the media section to be
741 // rejected in the answer.
742 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200743 callee()
744 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
745 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800746 });
747 }
Steve Anton15324772018-01-16 10:26:49 -0800748 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700749 // Do offer/answer and wait for successful end-to-end video frames.
750 caller()->CreateAndSetAndSignalOffer();
751 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800752 MediaExpectations media_expectations;
753 media_expectations.ExpectBidirectionalVideo();
754 media_expectations.ExpectNoAudio();
755 ASSERT_TRUE(ExpectNewFrames(media_expectations));
756
deadbeef1dcb1642017-03-29 21:08:16 -0700757 // Sanity check that the callee's description has a rejected audio section.
758 ASSERT_NE(nullptr, callee()->pc()->local_description());
759 const ContentInfo* callee_audio_content =
760 GetFirstAudioContent(callee()->pc()->local_description()->description());
761 ASSERT_NE(nullptr, callee_audio_content);
762 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800763 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200764 // The caller's transceiver should have stopped after receiving the answer,
765 // and thus no longer listed in transceivers.
766 EXPECT_EQ(nullptr,
767 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800768 }
deadbeef1dcb1642017-03-29 21:08:16 -0700769}
770
771// Test that if the answerer rejects the video m= section, no video is sent or
772// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800773TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700774 ASSERT_TRUE(CreatePeerConnectionWrappers());
775 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800776 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200777 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800778 // Only add audio track for callee, and set offer_to_receive_video to 0, so
779 // it will reject the video m= section completely.
780 PeerConnectionInterface::RTCOfferAnswerOptions options;
781 options.offer_to_receive_video = 0;
782 callee()->SetOfferAnswerOptions(options);
783 } else {
784 // Stopping the video RtpTransceiver will cause the media section to be
785 // rejected in the answer.
786 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200787 callee()
788 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
789 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800790 });
791 }
Steve Anton15324772018-01-16 10:26:49 -0800792 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700793 // Do offer/answer and wait for successful end-to-end audio frames.
794 caller()->CreateAndSetAndSignalOffer();
795 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800796 MediaExpectations media_expectations;
797 media_expectations.ExpectBidirectionalAudio();
798 media_expectations.ExpectNoVideo();
799 ASSERT_TRUE(ExpectNewFrames(media_expectations));
800
deadbeef1dcb1642017-03-29 21:08:16 -0700801 // Sanity check that the callee's description has a rejected video section.
802 ASSERT_NE(nullptr, callee()->pc()->local_description());
803 const ContentInfo* callee_video_content =
804 GetFirstVideoContent(callee()->pc()->local_description()->description());
805 ASSERT_NE(nullptr, callee_video_content);
806 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800807 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200808 // The caller's transceiver should have stopped after receiving the answer,
809 // and thus is no longer present.
810 EXPECT_EQ(nullptr,
811 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800812 }
deadbeef1dcb1642017-03-29 21:08:16 -0700813}
814
815// Test that if the answerer rejects both audio and video m= sections, nothing
816// bad happens.
817// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
818// test anything but the fact that negotiation succeeds, which doesn't mean
819// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800820TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -0700821 ASSERT_TRUE(CreatePeerConnectionWrappers());
822 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800823 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200824 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800825 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
826 // will reject both audio and video m= sections.
827 PeerConnectionInterface::RTCOfferAnswerOptions options;
828 options.offer_to_receive_audio = 0;
829 options.offer_to_receive_video = 0;
830 callee()->SetOfferAnswerOptions(options);
831 } else {
832 callee()->SetRemoteOfferHandler([this] {
833 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +0100834 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200835 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800836 }
837 });
838 }
deadbeef1dcb1642017-03-29 21:08:16 -0700839 // Do offer/answer and wait for stable signaling state.
840 caller()->CreateAndSetAndSignalOffer();
841 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800842
deadbeef1dcb1642017-03-29 21:08:16 -0700843 // Sanity check that the callee's description has rejected m= sections.
844 ASSERT_NE(nullptr, callee()->pc()->local_description());
845 const ContentInfo* callee_audio_content =
846 GetFirstAudioContent(callee()->pc()->local_description()->description());
847 ASSERT_NE(nullptr, callee_audio_content);
848 EXPECT_TRUE(callee_audio_content->rejected);
849 const ContentInfo* callee_video_content =
850 GetFirstVideoContent(callee()->pc()->local_description()->description());
851 ASSERT_NE(nullptr, callee_video_content);
852 EXPECT_TRUE(callee_video_content->rejected);
853}
854
855// This test sets up an audio and video call between two parties. After the
856// call runs for a while, the caller sends an updated offer with video being
857// rejected. Once the re-negotiation is done, the video flow should stop and
858// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800859TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700860 ASSERT_TRUE(CreatePeerConnectionWrappers());
861 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800862 caller()->AddAudioVideoTracks();
863 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700864 caller()->CreateAndSetAndSignalOffer();
865 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800866 {
867 MediaExpectations media_expectations;
868 media_expectations.ExpectBidirectionalAudioAndVideo();
869 ASSERT_TRUE(ExpectNewFrames(media_expectations));
870 }
deadbeef1dcb1642017-03-29 21:08:16 -0700871 // Renegotiate, rejecting the video m= section.
Florent Castelli15a38de2022-04-06 00:38:21 +0200872 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800873 caller()->SetGeneratedSdpMunger(
874 [](cricket::SessionDescription* description) {
875 for (cricket::ContentInfo& content : description->contents()) {
876 if (cricket::IsVideoContent(&content)) {
877 content.rejected = true;
878 }
879 }
880 });
881 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200882 caller()
883 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
884 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800885 }
deadbeef1dcb1642017-03-29 21:08:16 -0700886 caller()->CreateAndSetAndSignalOffer();
887 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
888
889 // Sanity check that the caller's description has a rejected video section.
890 ASSERT_NE(nullptr, caller()->pc()->local_description());
891 const ContentInfo* caller_video_content =
892 GetFirstVideoContent(caller()->pc()->local_description()->description());
893 ASSERT_NE(nullptr, caller_video_content);
894 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -0700895 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800896 {
897 MediaExpectations media_expectations;
898 media_expectations.ExpectBidirectionalAudio();
899 media_expectations.ExpectNoVideo();
900 ASSERT_TRUE(ExpectNewFrames(media_expectations));
901 }
deadbeef1dcb1642017-03-29 21:08:16 -0700902}
903
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700904// Do one offer/answer with audio, another that disables it (rejecting the m=
905// section), and another that re-enables it. Regression test for:
906// bugs.webrtc.org/6023
907TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
908 ASSERT_TRUE(CreatePeerConnectionWrappers());
909 ConnectFakeSignaling();
910
911 // Add audio track, do normal offer/answer.
912 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
913 caller()->CreateLocalAudioTrack();
914 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
915 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
916 caller()->CreateAndSetAndSignalOffer();
917 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
918
919 // Remove audio track, and set offer_to_receive_audio to false to cause the
920 // m= section to be completely disabled, not just "recvonly".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000921 caller()->pc()->RemoveTrackOrError(sender);
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700922 PeerConnectionInterface::RTCOfferAnswerOptions options;
923 options.offer_to_receive_audio = 0;
924 caller()->SetOfferAnswerOptions(options);
925 caller()->CreateAndSetAndSignalOffer();
926 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
927
928 // Add the audio track again, expecting negotiation to succeed and frames to
929 // flow.
930 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
931 options.offer_to_receive_audio = 1;
932 caller()->SetOfferAnswerOptions(options);
933 caller()->CreateAndSetAndSignalOffer();
934 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
935
936 MediaExpectations media_expectations;
937 media_expectations.CalleeExpectsSomeAudio();
938 EXPECT_TRUE(ExpectNewFrames(media_expectations));
939}
940
deadbeef1dcb1642017-03-29 21:08:16 -0700941// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
942// is needed to support legacy endpoints.
943// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
944// add a test for an end-to-end test without MID signaling either (basically,
945// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800946TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -0700947 ASSERT_TRUE(CreatePeerConnectionWrappers());
948 ConnectFakeSignaling();
949 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -0800950 caller()->AddAudioVideoTracks();
951 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -0700952 // Remove SSRCs and MSIDs from the received offer SDP.
953 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -0700954 caller()->CreateAndSetAndSignalOffer();
955 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800956 MediaExpectations media_expectations;
957 media_expectations.ExpectBidirectionalAudioAndVideo();
958 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700959}
960
Seth Hampson5897a6e2018-04-03 11:16:33 -0700961// Basic end-to-end test, without SSRC signaling. This means that the track
962// was created properly and frames are delivered when the MSIDs are communicated
963// with a=msid lines and no a=ssrc lines.
964TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
965 EndToEndCallWithoutSsrcSignaling) {
966 const char kStreamId[] = "streamId";
967 ASSERT_TRUE(CreatePeerConnectionWrappers());
968 ConnectFakeSignaling();
969 // Add just audio tracks.
970 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
971 callee()->AddAudioTrack();
972
973 // Remove SSRCs from the received offer SDP.
974 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
975 caller()->CreateAndSetAndSignalOffer();
976 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
977 MediaExpectations media_expectations;
978 media_expectations.ExpectBidirectionalAudio();
979 ASSERT_TRUE(ExpectNewFrames(media_expectations));
980}
981
Johannes Kron3e983682020-03-29 22:17:00 +0200982TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
983 EndToEndCallAddReceiveVideoToSendOnlyCall) {
984 ASSERT_TRUE(CreatePeerConnectionWrappers());
985 ConnectFakeSignaling();
986 // Add one-directional video, from caller to callee.
987 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
988 caller()->CreateLocalVideoTrack();
989
990 RtpTransceiverInit video_transceiver_init;
991 video_transceiver_init.stream_ids = {"video1"};
992 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
993 auto video_sender =
994 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
995 caller()->CreateAndSetAndSignalOffer();
996 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
997
998 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +0200999 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02001000
1001 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
1002 callee()->CreateLocalVideoTrack();
1003
1004 callee()->AddTrack(callee_track);
1005 caller()->CreateAndSetAndSignalOffer();
1006 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1007 // Ensure that video frames are received end-to-end.
1008 MediaExpectations media_expectations;
1009 media_expectations.ExpectBidirectionalVideo();
1010 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1011}
1012
Steve Antondf527fd2018-04-27 15:52:03 -07001013// Tests that video flows between multiple video tracks when SSRCs are not
1014// signaled. This exercises the MID RTP header extension which is needed to
1015// demux the incoming video tracks.
1016TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1017 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
1018 ASSERT_TRUE(CreatePeerConnectionWrappers());
1019 ConnectFakeSignaling();
1020 caller()->AddVideoTrack();
1021 caller()->AddVideoTrack();
1022 callee()->AddVideoTrack();
1023 callee()->AddVideoTrack();
1024
1025 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1026 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1027 caller()->CreateAndSetAndSignalOffer();
1028 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1029 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1030 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1031
1032 // Expect video to be received in both directions on both tracks.
1033 MediaExpectations media_expectations;
1034 media_expectations.ExpectBidirectionalVideo();
1035 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1036}
1037
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07001038// Used for the test below.
1039void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
1040 RemoveSsrcsAndKeepMsids(desc);
1041 desc->RemoveGroupByName("BUNDLE");
1042 for (ContentInfo& content : desc->contents()) {
1043 cricket::MediaContentDescription* media = content.media_description();
1044 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1045 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1046 [](const RtpExtension& extension) {
1047 return extension.uri ==
1048 RtpExtension::kMidUri;
1049 }),
1050 extensions.end());
1051 media->set_rtp_header_extensions(extensions);
1052 }
1053}
1054
1055// Tests that video flows between multiple video tracks when BUNDLE is not used,
1056// SSRCs are not signaled and the MID RTP header extension is not used. This
1057// relies on demuxing by payload type, which normally doesn't work if you have
1058// multiple media sections using the same payload type, but which should work as
1059// long as the media sections aren't bundled.
1060// Regression test for: http://crbug.com/webrtc/12023
1061TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1062 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
1063 ASSERT_TRUE(CreatePeerConnectionWrappers());
1064 ConnectFakeSignaling();
1065 caller()->AddVideoTrack();
1066 caller()->AddVideoTrack();
1067 callee()->AddVideoTrack();
1068 callee()->AddVideoTrack();
1069 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1070 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1071 caller()->CreateAndSetAndSignalOffer();
1072 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1073 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1074 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1075 // Make sure we are not bundled.
1076 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
1077 caller()->pc()->GetSenders()[1]->dtls_transport());
1078
1079 // Expect video to be received in both directions on both tracks.
1080 MediaExpectations media_expectations;
1081 media_expectations.ExpectBidirectionalVideo();
1082 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1083}
1084
1085// Used for the test below.
1086void ModifyPayloadTypesAndRemoveMidExtension(
1087 cricket::SessionDescription* desc) {
1088 int pt = 96;
1089 for (ContentInfo& content : desc->contents()) {
1090 cricket::MediaContentDescription* media = content.media_description();
1091 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1092 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1093 [](const RtpExtension& extension) {
1094 return extension.uri ==
1095 RtpExtension::kMidUri;
1096 }),
1097 extensions.end());
1098 media->set_rtp_header_extensions(extensions);
1099 cricket::VideoContentDescription* video = media->as_video();
1100 ASSERT_TRUE(video != nullptr);
1101 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
1102 video->set_codecs(codecs);
1103 }
1104}
1105
1106// Tests that two video tracks can be demultiplexed by payload type alone, by
1107// using different payload types for the same codec in different m= sections.
1108// This practice is discouraged but historically has been supported.
1109// Regression test for: http://crbug.com/webrtc/12029
1110TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1111 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
1112 ASSERT_TRUE(CreatePeerConnectionWrappers());
1113 ConnectFakeSignaling();
1114 caller()->AddVideoTrack();
1115 caller()->AddVideoTrack();
1116 callee()->AddVideoTrack();
1117 callee()->AddVideoTrack();
1118 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1119 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1120 // We can't remove SSRCs from the generated SDP because then no send streams
1121 // would be created.
1122 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1123 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1124 caller()->CreateAndSetAndSignalOffer();
1125 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1126 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1127 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1128 // Make sure we are bundled.
1129 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
1130 caller()->pc()->GetSenders()[1]->dtls_transport());
1131
1132 // Expect video to be received in both directions on both tracks.
1133 MediaExpectations media_expectations;
1134 media_expectations.ExpectBidirectionalVideo();
1135 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1136}
1137
Henrik Boström5b147782018-12-04 11:25:05 +01001138TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
1139 ASSERT_TRUE(CreatePeerConnectionWrappers());
1140 ConnectFakeSignaling();
1141 caller()->AddAudioTrack();
1142 caller()->AddVideoTrack();
1143 caller()->CreateAndSetAndSignalOffer();
1144 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1145 auto callee_receivers = callee()->pc()->GetReceivers();
1146 ASSERT_EQ(2u, callee_receivers.size());
1147 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
1148 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
1149}
1150
1151TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
1152 ASSERT_TRUE(CreatePeerConnectionWrappers());
1153 ConnectFakeSignaling();
1154 caller()->AddAudioTrack();
1155 caller()->AddVideoTrack();
1156 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1157 caller()->CreateAndSetAndSignalOffer();
1158 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1159 auto callee_receivers = callee()->pc()->GetReceivers();
1160 ASSERT_EQ(2u, callee_receivers.size());
1161 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
1162 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
1163 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
1164 callee_receivers[1]->stream_ids()[0]);
1165 EXPECT_EQ(callee_receivers[0]->streams()[0],
1166 callee_receivers[1]->streams()[0]);
1167}
1168
deadbeef1dcb1642017-03-29 21:08:16 -07001169// Test that if two video tracks are sent (from caller to callee, in this test),
1170// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001171TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07001172 ASSERT_TRUE(CreatePeerConnectionWrappers());
1173 ConnectFakeSignaling();
1174 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08001175 caller()->AddAudioVideoTracks();
1176 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001177 caller()->CreateAndSetAndSignalOffer();
1178 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08001179 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001180
1181 MediaExpectations media_expectations;
1182 media_expectations.CalleeExpectsSomeAudioAndVideo();
1183 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001184}
1185
1186static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
1187 bool first = true;
1188 for (cricket::ContentInfo& content : desc->contents()) {
1189 if (first) {
1190 first = false;
1191 continue;
1192 }
1193 content.bundle_only = true;
1194 }
1195 first = true;
1196 for (cricket::TransportInfo& transport : desc->transport_infos()) {
1197 if (first) {
1198 first = false;
1199 continue;
1200 }
1201 transport.description.ice_ufrag.clear();
1202 transport.description.ice_pwd.clear();
1203 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
1204 transport.description.identity_fingerprint.reset(nullptr);
1205 }
1206}
1207
1208// Test that if applying a true "max bundle" offer, which uses ports of 0,
1209// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
1210// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
1211// successfully and media flows.
1212// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
1213// TODO(deadbeef): Won't need this test once we start generating actual
1214// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001215TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001216 EndToEndCallWithSpecCompliantMaxBundleOffer) {
1217 ASSERT_TRUE(CreatePeerConnectionWrappers());
1218 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001219 caller()->AddAudioVideoTracks();
1220 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001221 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
1222 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
1223 // but the first m= section.
1224 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
1225 caller()->CreateAndSetAndSignalOffer();
1226 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001227 MediaExpectations media_expectations;
1228 media_expectations.ExpectBidirectionalAudioAndVideo();
1229 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001230}
1231
1232// Test that we can receive the audio output level from a remote audio track.
1233// TODO(deadbeef): Use a fake audio source and verify that the output level is
1234// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001235TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001236 ASSERT_TRUE(CreatePeerConnectionWrappers());
1237 ConnectFakeSignaling();
1238 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001239 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001240 caller()->CreateAndSetAndSignalOffer();
1241 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1242
1243 // Get the audio output level stats. Note that the level is not available
1244 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07001245 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001246 kMaxWaitForFramesMs);
1247}
1248
1249// Test that an audio input level is reported.
1250// TODO(deadbeef): Use a fake audio source and verify that the input level is
1251// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001252TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001253 ASSERT_TRUE(CreatePeerConnectionWrappers());
1254 ConnectFakeSignaling();
1255 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001256 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001257 caller()->CreateAndSetAndSignalOffer();
1258 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1259
1260 // Get the audio input level stats. The level should be available very
1261 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07001262 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001263 kMaxWaitForStatsMs);
1264}
1265
1266// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001267TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001268 ASSERT_TRUE(CreatePeerConnectionWrappers());
1269 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001270 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001271 // Do offer/answer, wait for the callee to receive some frames.
1272 caller()->CreateAndSetAndSignalOffer();
1273 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001274
1275 MediaExpectations media_expectations;
1276 media_expectations.CalleeExpectsSomeAudioAndVideo();
1277 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001278
1279 // Get a handle to the remote tracks created, so they can be used as GetStats
1280 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01001281 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08001282 // We received frames, so we definitely should have nonzero "received bytes"
1283 // stats at this point.
Niels Möllerafb246b2022-04-20 14:26:50 +02001284 EXPECT_GT(
1285 callee()->OldGetStatsForTrack(receiver->track().get())->BytesReceived(),
1286 0);
Steve Anton15324772018-01-16 10:26:49 -08001287 }
deadbeef1dcb1642017-03-29 21:08:16 -07001288}
1289
1290// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001291TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001292 ASSERT_TRUE(CreatePeerConnectionWrappers());
1293 ConnectFakeSignaling();
1294 auto audio_track = caller()->CreateLocalAudioTrack();
1295 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08001296 caller()->AddTrack(audio_track);
1297 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07001298 // Do offer/answer, wait for the callee to receive some frames.
1299 caller()->CreateAndSetAndSignalOffer();
1300 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001301 MediaExpectations media_expectations;
1302 media_expectations.CalleeExpectsSomeAudioAndVideo();
1303 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001304
1305 // The callee received frames, so we definitely should have nonzero "sent
1306 // bytes" stats at this point.
Niels Möllerafb246b2022-04-20 14:26:50 +02001307 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track.get())->BytesSent(), 0);
1308 EXPECT_GT(caller()->OldGetStatsForTrack(video_track.get())->BytesSent(), 0);
deadbeefd8ad7882017-04-18 16:01:17 -07001309}
1310
Steve Antona41959e2018-11-28 11:15:33 -08001311// Test that the track ID is associated with all local and remote SSRC stats
1312// using the old GetStats() and more than 1 audio and more than 1 video track.
1313// This is a regression test for crbug.com/906988
1314TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1315 OldGetStatsAssociatesTrackIdForManyMediaSections) {
1316 ASSERT_TRUE(CreatePeerConnectionWrappers());
1317 ConnectFakeSignaling();
1318 auto audio_sender_1 = caller()->AddAudioTrack();
1319 auto video_sender_1 = caller()->AddVideoTrack();
1320 auto audio_sender_2 = caller()->AddAudioTrack();
1321 auto video_sender_2 = caller()->AddVideoTrack();
1322 caller()->CreateAndSetAndSignalOffer();
1323 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1324
1325 MediaExpectations media_expectations;
1326 media_expectations.CalleeExpectsSomeAudioAndVideo();
1327 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1328
1329 std::vector<std::string> track_ids = {
1330 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1331 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1332
1333 auto caller_stats = caller()->OldGetStats();
1334 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1335 auto callee_stats = callee()->OldGetStats();
1336 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1337}
1338
Steve Antonffa6ce42018-11-30 09:26:08 -08001339// Test that the new GetStats() returns stats for all outgoing/incoming streams
1340// with the correct track IDs if there are more than one audio and more than one
1341// video senders/receivers.
1342TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
1343 ASSERT_TRUE(CreatePeerConnectionWrappers());
1344 ConnectFakeSignaling();
1345 auto audio_sender_1 = caller()->AddAudioTrack();
1346 auto video_sender_1 = caller()->AddVideoTrack();
1347 auto audio_sender_2 = caller()->AddAudioTrack();
1348 auto video_sender_2 = caller()->AddVideoTrack();
1349 caller()->CreateAndSetAndSignalOffer();
1350 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1351
1352 MediaExpectations media_expectations;
1353 media_expectations.CalleeExpectsSomeAudioAndVideo();
1354 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1355
1356 std::vector<std::string> track_ids = {
1357 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1358 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1359
1360 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
1361 caller()->NewGetStats();
1362 ASSERT_TRUE(caller_report);
1363 auto outbound_stream_stats =
1364 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02001365 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08001366 std::vector<std::string> outbound_track_ids;
1367 for (const auto& stat : outbound_stream_stats) {
1368 ASSERT_TRUE(stat->bytes_sent.is_defined());
1369 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001370 if (*stat->kind == "video") {
1371 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
1372 EXPECT_GT(*stat->key_frames_encoded, 0u);
1373 ASSERT_TRUE(stat->frames_encoded.is_defined());
1374 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
1375 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001376 ASSERT_TRUE(stat->track_id.is_defined());
1377 const auto* track_stat =
1378 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1379 ASSERT_TRUE(track_stat);
1380 outbound_track_ids.push_back(*track_stat->track_identifier);
1381 }
1382 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
1383
1384 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
1385 callee()->NewGetStats();
1386 ASSERT_TRUE(callee_report);
1387 auto inbound_stream_stats =
1388 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1389 ASSERT_EQ(4u, inbound_stream_stats.size());
1390 std::vector<std::string> inbound_track_ids;
1391 for (const auto& stat : inbound_stream_stats) {
1392 ASSERT_TRUE(stat->bytes_received.is_defined());
1393 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001394 if (*stat->kind == "video") {
1395 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
1396 EXPECT_GT(*stat->key_frames_decoded, 0u);
1397 ASSERT_TRUE(stat->frames_decoded.is_defined());
1398 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
1399 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001400 ASSERT_TRUE(stat->track_id.is_defined());
1401 const auto* track_stat =
1402 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1403 ASSERT_TRUE(track_stat);
1404 inbound_track_ids.push_back(*track_stat->track_identifier);
1405 }
1406 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
1407}
1408
1409// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07001410// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
1411// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001412TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07001413 GetStatsForUnsignaledStreamWithNewStatsApi) {
1414 ASSERT_TRUE(CreatePeerConnectionWrappers());
1415 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001416 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07001417 // Remove SSRCs and MSIDs from the received offer SDP.
1418 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1419 caller()->CreateAndSetAndSignalOffer();
1420 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001421 MediaExpectations media_expectations;
1422 media_expectations.CalleeExpectsSomeAudio(1);
1423 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07001424
1425 // We received a frame, so we should have nonzero "bytes received" stats for
1426 // the unsignaled stream, if stats are working for it.
1427 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1428 callee()->NewGetStats();
1429 ASSERT_NE(nullptr, report);
1430 auto inbound_stream_stats =
1431 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1432 ASSERT_EQ(1U, inbound_stream_stats.size());
1433 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
1434 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07001435 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
1436}
1437
Taylor Brandstettera4653442018-06-19 09:44:26 -07001438// Same as above but for the legacy stats implementation.
1439TEST_P(PeerConnectionIntegrationTest,
1440 GetStatsForUnsignaledStreamWithOldStatsApi) {
1441 ASSERT_TRUE(CreatePeerConnectionWrappers());
1442 ConnectFakeSignaling();
1443 caller()->AddAudioTrack();
1444 // Remove SSRCs and MSIDs from the received offer SDP.
1445 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1446 caller()->CreateAndSetAndSignalOffer();
1447 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1448
1449 // Note that, since the old stats implementation associates SSRCs with tracks
1450 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
1451 // associated track ID. So we can't use the track "selector" argument.
1452 //
1453 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
1454 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001455 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07001456 kDefaultTimeout);
1457}
1458
zhihuangf8164932017-05-19 13:09:47 -07001459// Test that we can successfully get the media related stats (audio level
1460// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001461TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07001462 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
1463 ASSERT_TRUE(CreatePeerConnectionWrappers());
1464 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001465 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07001466 // Remove SSRCs and MSIDs from the received offer SDP.
1467 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1468 caller()->CreateAndSetAndSignalOffer();
1469 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001470 MediaExpectations media_expectations;
1471 media_expectations.CalleeExpectsSomeAudio(1);
1472 media_expectations.CalleeExpectsSomeVideo(1);
1473 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07001474
1475 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1476 callee()->NewGetStats();
1477 ASSERT_NE(nullptr, report);
1478
1479 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1480 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
1481 ASSERT_GE(audio_index, 0);
1482 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07001483}
1484
deadbeef4e2deab2017-09-20 13:56:21 -07001485// Helper for test below.
1486void ModifySsrcs(cricket::SessionDescription* desc) {
1487 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07001488 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08001489 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07001490 for (uint32_t& ssrc : stream.ssrcs) {
1491 ssrc = rtc::CreateRandomId();
1492 }
1493 }
1494 }
1495}
1496
1497// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
1498// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
1499// This should result in two "RTCInboundRTPStreamStats", but only one
1500// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
1501// being reset to 0 once the SSRC change occurs.
1502//
1503// Regression test for this bug:
1504// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
1505//
1506// The bug causes the track stats to only represent one of the two streams:
1507// whichever one has the higher SSRC. So with this bug, there was a 50% chance
1508// that the track stat counters would reset to 0 when the new stream is
1509// received, and a 50% chance that they'll stop updating (while
1510// "concealed_samples" continues increasing, due to silence being generated for
1511// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001512TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08001513 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07001514 ASSERT_TRUE(CreatePeerConnectionWrappers());
1515 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001516 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07001517 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
1518 // that doesn't signal SSRCs (from the callee's perspective).
1519 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1520 caller()->CreateAndSetAndSignalOffer();
1521 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1522 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001523 {
1524 MediaExpectations media_expectations;
1525 media_expectations.CalleeExpectsSomeAudio(50);
1526 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1527 }
deadbeef4e2deab2017-09-20 13:56:21 -07001528 // Some audio frames were received, so we should have nonzero "samples
1529 // received" for the track.
1530 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1531 callee()->NewGetStats();
1532 ASSERT_NE(nullptr, report);
1533 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1534 ASSERT_EQ(1U, track_stats.size());
1535 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1536 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
1537 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
1538
1539 // Create a new offer and munge it to cause the caller to use a new SSRC.
1540 caller()->SetGeneratedSdpMunger(ModifySsrcs);
1541 caller()->CreateAndSetAndSignalOffer();
1542 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1543 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
1544 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001545 {
1546 MediaExpectations media_expectations;
1547 media_expectations.CalleeExpectsSomeAudio(25);
1548 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1549 }
deadbeef4e2deab2017-09-20 13:56:21 -07001550
1551 report = callee()->NewGetStats();
1552 ASSERT_NE(nullptr, report);
1553 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1554 ASSERT_EQ(1U, track_stats.size());
1555 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1556 // The "total samples received" stat should only be greater than it was
1557 // before.
1558 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
1559 // Right now, the new SSRC will cause the counters to reset to 0.
1560 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
1561
1562 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08001563 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07001564 // good sign that we're seeing stats from the old stream that's no longer
1565 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08001566 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07001567 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
1568 EXPECT_LT(*track_stats[0]->concealed_samples,
1569 *track_stats[0]->total_samples_received *
1570 kAcceptableConcealedSamplesPercentage);
1571
1572 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
1573 // sanity check that the SSRC really changed.
1574 // TODO(deadbeef): This isn't working right now, because we're not returning
1575 // *any* stats for the inactive stream. Uncomment when the bug is completely
1576 // fixed.
1577 // auto inbound_stream_stats =
1578 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1579 // ASSERT_EQ(2U, inbound_stream_stats.size());
1580}
1581
deadbeef1dcb1642017-03-29 21:08:16 -07001582// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001583TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001584 PeerConnectionFactory::Options dtls_10_options;
1585 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1586 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1587 dtls_10_options));
1588 ConnectFakeSignaling();
1589 // Do normal offer/answer and wait for some frames to be received in each
1590 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001591 caller()->AddAudioVideoTracks();
1592 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001593 caller()->CreateAndSetAndSignalOffer();
1594 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001595 MediaExpectations media_expectations;
1596 media_expectations.ExpectBidirectionalAudioAndVideo();
1597 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001598}
1599
1600// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001601TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001602 PeerConnectionFactory::Options dtls_10_options;
1603 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1604 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1605 dtls_10_options));
1606 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001607 caller()->AddAudioVideoTracks();
1608 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001609 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001610 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001611 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001612 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001613 kDefaultTimeout);
1614 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001615 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001616 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001617 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1618 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1619 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001620}
1621
1622// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001623TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001624 PeerConnectionFactory::Options dtls_12_options;
1625 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1626 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
1627 dtls_12_options));
1628 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001629 caller()->AddAudioVideoTracks();
1630 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001631 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001632 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001633 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001634 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001635 kDefaultTimeout);
1636 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001637 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001638 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001639 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1640 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1641 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001642}
1643
1644// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
1645// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001646TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001647 PeerConnectionFactory::Options caller_options;
1648 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1649 PeerConnectionFactory::Options callee_options;
1650 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1651 ASSERT_TRUE(
1652 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1653 ConnectFakeSignaling();
1654 // Do normal offer/answer and wait for some frames to be received in each
1655 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001656 caller()->AddAudioVideoTracks();
1657 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001658 caller()->CreateAndSetAndSignalOffer();
1659 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001660 MediaExpectations media_expectations;
1661 media_expectations.ExpectBidirectionalAudioAndVideo();
1662 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001663}
1664
1665// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
1666// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001667TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07001668 PeerConnectionFactory::Options caller_options;
1669 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1670 PeerConnectionFactory::Options callee_options;
1671 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1672 ASSERT_TRUE(
1673 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1674 ConnectFakeSignaling();
1675 // Do normal offer/answer and wait for some frames to be received in each
1676 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001677 caller()->AddAudioVideoTracks();
1678 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001679 caller()->CreateAndSetAndSignalOffer();
1680 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001681 MediaExpectations media_expectations;
1682 media_expectations.ExpectBidirectionalAudioAndVideo();
1683 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001684}
1685
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001686// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
1687// works as expected; the cipher should only be used if enabled by both sides.
1688TEST_P(PeerConnectionIntegrationTest,
1689 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
1690 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001691 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001692 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001693 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1694 false;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001695 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001696 TestNegotiatedCipherSuite(caller_options, callee_options,
1697 expected_cipher_suite);
1698}
1699
1700TEST_P(PeerConnectionIntegrationTest,
1701 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
1702 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001703 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1704 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001705 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001706 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001707 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001708 TestNegotiatedCipherSuite(caller_options, callee_options,
1709 expected_cipher_suite);
1710}
1711
1712TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
1713 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001714 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001715 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001716 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001717 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_32;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001718 TestNegotiatedCipherSuite(caller_options, callee_options,
1719 expected_cipher_suite);
1720}
1721
deadbeef1dcb1642017-03-29 21:08:16 -07001722// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001723TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001724 bool local_gcm_enabled = false;
1725 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001726 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07001727 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
1728 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001729 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001730}
1731
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001732// Test that a GCM cipher is used if both ends support it and non-GCM is
1733// disabled.
1734TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001735 bool local_gcm_enabled = true;
1736 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001737 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07001738 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
1739 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001740 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001741}
1742
deadbeef7914b8c2017-04-21 03:23:33 -07001743// Verify that media can be transmitted end-to-end when GCM crypto suites are
1744// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
1745// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
1746// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001747TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07001748 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001749 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001750 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07001751 ASSERT_TRUE(
1752 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
1753 ConnectFakeSignaling();
1754 // Do normal offer/answer and wait for some frames to be received in each
1755 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001756 caller()->AddAudioVideoTracks();
1757 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07001758 caller()->CreateAndSetAndSignalOffer();
1759 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001760 MediaExpectations media_expectations;
1761 media_expectations.ExpectBidirectionalAudioAndVideo();
1762 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07001763}
1764
deadbeef1dcb1642017-03-29 21:08:16 -07001765// Test that the ICE connection and gathering states eventually reach
1766// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08001767TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07001768 ASSERT_TRUE(CreatePeerConnectionWrappers());
1769 ConnectFakeSignaling();
1770 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001771 caller()->AddAudioVideoTracks();
1772 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001773 caller()->CreateAndSetAndSignalOffer();
1774 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1775 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1776 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
1777 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1778 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
1779 // After the best candidate pair is selected and all candidates are signaled,
1780 // the ICE connection state should reach "complete".
1781 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
1782 // answerer/"callee" by default) only reaches "connected". When this is
1783 // fixed, this test should be updated.
1784 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1785 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00001786 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1787 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001788}
1789
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001790constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1791 cricket::PORTALLOCATOR_DISABLE_RELAY |
1792 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001793
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001794// Use a mock resolver to resolve the hostname back to the original IP on both
1795// sides and check that the ICE connection connects.
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001796TEST_P(PeerConnectionIntegrationTest,
Harald Alvestrand099ff622022-06-02 13:24:32 +00001797 IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001798 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001799 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001800 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001801 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001802 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1803 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001804
1805 // This also verifies that the injected AsyncResolverFactory is used by
1806 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001807 EXPECT_CALL(*caller_resolver_factory, Create())
1808 .WillOnce(Return(&caller_async_resolver));
1809 webrtc::PeerConnectionDependencies caller_deps(nullptr);
1810 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1811
1812 EXPECT_CALL(*callee_resolver_factory, Create())
1813 .WillOnce(Return(&callee_async_resolver));
1814 webrtc::PeerConnectionDependencies callee_deps(nullptr);
1815 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1816
1817 PeerConnectionInterface::RTCConfiguration config;
1818 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1819 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1820
1821 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1822 config, std::move(caller_deps), config, std::move(callee_deps)));
1823
1824 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1825 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1826
1827 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07001828 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001829 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07001830 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001831 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001832
1833 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001834
1835 ConnectFakeSignaling();
1836 caller()->AddAudioVideoTracks();
1837 callee()->AddAudioVideoTracks();
1838 caller()->CreateAndSetAndSignalOffer();
1839 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1840 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1841 caller()->ice_connection_state(), kDefaultTimeout);
1842 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1843 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08001844
Ying Wangef3998f2019-12-09 13:06:53 +01001845 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1846 "WebRTC.PeerConnection.CandidatePairType_UDP",
1847 webrtc::kIceCandidatePairHostNameHostName));
Harald Alvestrand4f7486a2022-06-02 11:35:49 +00001848 DestroyPeerConnections();
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001849}
1850
Steve Antonede9ca52017-10-16 13:04:27 -07001851// Test that firewalling the ICE connection causes the clients to identify the
1852// disconnected state and then removing the firewall causes them to reconnect.
1853class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08001854 : public PeerConnectionIntegrationBaseTest,
1855 public ::testing::WithParamInterface<
1856 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07001857 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001858 PeerConnectionIntegrationIceStatesTest()
1859 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1860 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07001861 }
1862
1863 void StartStunServer(const SocketAddress& server_address) {
1864 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01001865 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07001866 }
1867
1868 bool TestIPv6() {
1869 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1870 }
1871
1872 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001873 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1874 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07001875 }
1876
1877 std::vector<SocketAddress> CallerAddresses() {
1878 std::vector<SocketAddress> addresses;
1879 addresses.push_back(SocketAddress("1.1.1.1", 0));
1880 if (TestIPv6()) {
1881 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1882 }
1883 return addresses;
1884 }
1885
1886 std::vector<SocketAddress> CalleeAddresses() {
1887 std::vector<SocketAddress> addresses;
1888 addresses.push_back(SocketAddress("2.2.2.2", 0));
1889 if (TestIPv6()) {
1890 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1891 }
1892 return addresses;
1893 }
1894
1895 void SetUpNetworkInterfaces() {
1896 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07001897 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1898 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07001899
1900 // Add network addresses for test.
1901 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001902 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001903 }
1904 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001905 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001906 }
1907 }
1908
1909 private:
1910 uint32_t port_allocator_flags_;
1911 std::unique_ptr<cricket::TestStunServer> stun_server_;
1912};
1913
Yves Gerey100fe632020-01-17 19:15:53 +01001914// Ensure FakeClockForTest is constructed first (see class for rationale).
1915class PeerConnectionIntegrationIceStatesTestWithFakeClock
1916 : public FakeClockForTest,
1917 public PeerConnectionIntegrationIceStatesTest {};
1918
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001919#if !defined(THREAD_SANITIZER)
1920// This test provokes TSAN errors. bugs.webrtc.org/11282
1921
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001922// Tests that if the connection doesn't get set up properly we eventually reach
1923// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01001924TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
1925 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001926 // Block connections to/from the caller and wait for ICE to become
1927 // disconnected.
1928 for (const auto& caller_address : CallerAddresses()) {
1929 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
1930 }
1931
1932 ASSERT_TRUE(CreatePeerConnectionWrappers());
1933 ConnectFakeSignaling();
1934 SetPortAllocatorFlags();
1935 SetUpNetworkInterfaces();
1936 caller()->AddAudioVideoTracks();
1937 caller()->CreateAndSetAndSignalOffer();
1938
1939 // According to RFC7675, if there is no response within 30 seconds then the
1940 // peer should consider the other side to have rejected the connection. This
1941 // is signaled by the state transitioning to "failed".
1942 constexpr int kConsentTimeout = 30000;
1943 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
1944 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01001945 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07001946}
1947
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001948#endif // !defined(THREAD_SANITIZER)
1949
Steve Antonede9ca52017-10-16 13:04:27 -07001950// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
1951// and that the statistics in the metric observers are updated correctly.
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001952// TODO(bugs.webrtc.org/12591): Flaky on Windows.
1953#if defined(WEBRTC_WIN)
1954#define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
1955#else
1956#define MAYBE_VerifyBestConnection VerifyBestConnection
1957#endif
1958TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
Steve Antonede9ca52017-10-16 13:04:27 -07001959 ASSERT_TRUE(CreatePeerConnectionWrappers());
1960 ConnectFakeSignaling();
1961 SetPortAllocatorFlags();
1962 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08001963 caller()->AddAudioVideoTracks();
1964 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07001965 caller()->CreateAndSetAndSignalOffer();
1966
1967 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08001968 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1969 caller()->ice_connection_state(), kDefaultTimeout);
1970 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1971 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07001972
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001973 // TODO(bugs.webrtc.org/9456): Fix it.
1974 const int num_best_ipv4 = webrtc::metrics::NumEvents(
1975 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
1976 const int num_best_ipv6 = webrtc::metrics::NumEvents(
1977 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001978 if (TestIPv6()) {
1979 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
1980 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01001981 EXPECT_METRIC_EQ(0, num_best_ipv4);
1982 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001983 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01001984 EXPECT_METRIC_EQ(1, num_best_ipv4);
1985 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001986 }
1987
Ying Wangef3998f2019-12-09 13:06:53 +01001988 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
1989 "WebRTC.PeerConnection.CandidatePairType_UDP",
1990 webrtc::kIceCandidatePairHostHost));
1991 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1992 "WebRTC.PeerConnection.CandidatePairType_UDP",
1993 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07001994}
1995
1996constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
1997 cricket::PORTALLOCATOR_DISABLE_STUN |
1998 cricket::PORTALLOCATOR_DISABLE_RELAY;
1999constexpr uint32_t kFlagsIPv6NoStun =
2000 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
2001 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
2002constexpr uint32_t kFlagsIPv4Stun =
2003 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
2004
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002005INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002006 PeerConnectionIntegrationTest,
2007 PeerConnectionIntegrationIceStatesTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02002008 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Seth Hampson2f0d7022018-02-20 11:54:42 -08002009 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2010 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2011 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07002012
Yves Gerey100fe632020-01-17 19:15:53 +01002013INSTANTIATE_TEST_SUITE_P(
2014 PeerConnectionIntegrationTest,
2015 PeerConnectionIntegrationIceStatesTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02002016 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Yves Gerey100fe632020-01-17 19:15:53 +01002017 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2018 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2019 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2020
deadbeef1dcb1642017-03-29 21:08:16 -07002021// This test sets up a call between two parties with audio and video.
2022// During the call, the caller restarts ICE and the test verifies that
2023// new ICE candidates are generated and audio and video still can flow, and the
2024// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002025TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07002026 ASSERT_TRUE(CreatePeerConnectionWrappers());
2027 ConnectFakeSignaling();
2028 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08002029 caller()->AddAudioVideoTracks();
2030 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002031 caller()->CreateAndSetAndSignalOffer();
2032 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2033 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2034 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002035 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2036 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07002037
2038 // To verify that the ICE restart actually occurs, get
2039 // ufrag/password/candidates before and after restart.
2040 // Create an SDP string of the first audio candidate for both clients.
2041 const webrtc::IceCandidateCollection* audio_candidates_caller =
2042 caller()->pc()->local_description()->candidates(0);
2043 const webrtc::IceCandidateCollection* audio_candidates_callee =
2044 callee()->pc()->local_description()->candidates(0);
2045 ASSERT_GT(audio_candidates_caller->count(), 0u);
2046 ASSERT_GT(audio_candidates_callee->count(), 0u);
2047 std::string caller_candidate_pre_restart;
2048 ASSERT_TRUE(
2049 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2050 std::string callee_candidate_pre_restart;
2051 ASSERT_TRUE(
2052 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2053 const cricket::SessionDescription* desc =
2054 caller()->pc()->local_description()->description();
2055 std::string caller_ufrag_pre_restart =
2056 desc->transport_infos()[0].description.ice_ufrag;
2057 desc = callee()->pc()->local_description()->description();
2058 std::string callee_ufrag_pre_restart =
2059 desc->transport_infos()[0].description.ice_ufrag;
2060
Alex Drake00c7ecf2019-08-06 10:54:47 -07002061 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002062 // Have the caller initiate an ICE restart.
2063 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2064 caller()->CreateAndSetAndSignalOffer();
2065 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2066 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2067 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002068 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07002069 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2070
2071 // Grab the ufrags/candidates again.
2072 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2073 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2074 ASSERT_GT(audio_candidates_caller->count(), 0u);
2075 ASSERT_GT(audio_candidates_callee->count(), 0u);
2076 std::string caller_candidate_post_restart;
2077 ASSERT_TRUE(
2078 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2079 std::string callee_candidate_post_restart;
2080 ASSERT_TRUE(
2081 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2082 desc = caller()->pc()->local_description()->description();
2083 std::string caller_ufrag_post_restart =
2084 desc->transport_infos()[0].description.ice_ufrag;
2085 desc = callee()->pc()->local_description()->description();
2086 std::string callee_ufrag_post_restart =
2087 desc->transport_infos()[0].description.ice_ufrag;
2088 // Sanity check that an ICE restart was actually negotiated in SDP.
2089 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2090 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2091 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2092 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07002093 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002094
2095 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002096 MediaExpectations media_expectations;
2097 media_expectations.ExpectBidirectionalAudioAndVideo();
2098 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002099}
2100
2101// Verify that audio/video can be received end-to-end when ICE renomination is
2102// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002103TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07002104 PeerConnectionInterface::RTCConfiguration config;
2105 config.enable_ice_renomination = true;
2106 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2107 ConnectFakeSignaling();
2108 // Do normal offer/answer and wait for some frames to be received in each
2109 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002110 caller()->AddAudioVideoTracks();
2111 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002112 caller()->CreateAndSetAndSignalOffer();
2113 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2114 // Sanity check that ICE renomination was actually negotiated.
2115 const cricket::SessionDescription* desc =
2116 caller()->pc()->local_description()->description();
2117 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002118 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002119 }
2120 desc = callee()->pc()->local_description()->description();
2121 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002122 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002123 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08002124 MediaExpectations media_expectations;
2125 media_expectations.ExpectBidirectionalAudioAndVideo();
2126 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002127}
2128
Steve Anton6f25b092017-10-23 09:39:20 -07002129// With a max bundle policy and RTCP muxing, adding a new media description to
2130// the connection should not affect ICE at all because the new media will use
2131// the existing connection.
Rasmus Brandt685be142021-03-15 14:03:38 +01002132// TODO(bugs.webrtc.org/12538): Fails on tsan.
2133#if defined(THREAD_SANITIZER)
2134#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2135 DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2136#else
2137#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2138 AddMediaToConnectedBundleDoesNotRestartIce
2139#endif
Seth Hampson2f0d7022018-02-20 11:54:42 -08002140TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt685be142021-03-15 14:03:38 +01002141 MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07002142 PeerConnectionInterface::RTCConfiguration config;
2143 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2144 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2145 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2146 config, PeerConnectionInterface::RTCConfiguration()));
2147 ConnectFakeSignaling();
2148
Steve Anton15324772018-01-16 10:26:49 -08002149 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002150 caller()->CreateAndSetAndSignalOffer();
2151 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07002152 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2153 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07002154
2155 caller()->clear_ice_connection_state_history();
2156
Steve Anton15324772018-01-16 10:26:49 -08002157 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002158 caller()->CreateAndSetAndSignalOffer();
2159 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2160
2161 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2162}
2163
deadbeef1dcb1642017-03-29 21:08:16 -07002164// This test sets up a call between two parties with audio and video. It then
2165// renegotiates setting the video m-line to "port 0", then later renegotiates
2166// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002167TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002168 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2169 ASSERT_TRUE(CreatePeerConnectionWrappers());
2170 ConnectFakeSignaling();
2171
2172 // Do initial negotiation, only sending media from the caller. Will result in
2173 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08002174 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002175 caller()->CreateAndSetAndSignalOffer();
2176 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2177
2178 // Negotiate again, disabling the video "m=" section (the callee will set the
2179 // port to 0 due to offer_to_receive_video = 0).
Florent Castelli15a38de2022-04-06 00:38:21 +02002180 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002181 PeerConnectionInterface::RTCOfferAnswerOptions options;
2182 options.offer_to_receive_video = 0;
2183 callee()->SetOfferAnswerOptions(options);
2184 } else {
2185 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002186 callee()
2187 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2188 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002189 });
2190 }
deadbeef1dcb1642017-03-29 21:08:16 -07002191 caller()->CreateAndSetAndSignalOffer();
2192 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2193 // Sanity check that video "m=" section was actually rejected.
2194 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2195 callee()->pc()->local_description()->description());
2196 ASSERT_NE(nullptr, answer_video_content);
2197 ASSERT_TRUE(answer_video_content->rejected);
2198
2199 // Enable video and do negotiation again, making sure video is received
2200 // end-to-end, also adding media stream to callee.
Florent Castelli15a38de2022-04-06 00:38:21 +02002201 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002202 PeerConnectionInterface::RTCOfferAnswerOptions options;
2203 options.offer_to_receive_video = 1;
2204 callee()->SetOfferAnswerOptions(options);
2205 } else {
2206 // The caller's transceiver is stopped, so we need to add another track.
2207 auto caller_transceiver =
2208 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002209 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002210 caller()->AddVideoTrack();
2211 }
2212 callee()->AddVideoTrack();
2213 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07002214 caller()->CreateAndSetAndSignalOffer();
2215 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002216
deadbeef1dcb1642017-03-29 21:08:16 -07002217 // Verify the caller receives frames from the newly added stream, and the
2218 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002219 MediaExpectations media_expectations;
2220 media_expectations.CalleeExpectsSomeAudio();
2221 media_expectations.ExpectBidirectionalVideo();
2222 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002223}
2224
deadbeef1dcb1642017-03-29 21:08:16 -07002225// This tests that if we negotiate after calling CreateSender but before we
2226// have a track, then set a track later, frames from the newly-set track are
2227// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002228TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07002229 MediaFlowsAfterEarlyWarmupWithCreateSender) {
2230 ASSERT_TRUE(CreatePeerConnectionWrappers());
2231 ConnectFakeSignaling();
2232 auto caller_audio_sender =
2233 caller()->pc()->CreateSender("audio", "caller_stream");
2234 auto caller_video_sender =
2235 caller()->pc()->CreateSender("video", "caller_stream");
2236 auto callee_audio_sender =
2237 callee()->pc()->CreateSender("audio", "callee_stream");
2238 auto callee_video_sender =
2239 callee()->pc()->CreateSender("video", "callee_stream");
2240 caller()->CreateAndSetAndSignalOffer();
2241 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2242 // Wait for ICE to complete, without any tracks being set.
2243 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2244 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2245 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2246 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2247 // Now set the tracks, and expect frames to immediately start flowing.
Niels Möllerafb246b2022-04-20 14:26:50 +02002248 EXPECT_TRUE(
2249 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2250 EXPECT_TRUE(
2251 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2252 EXPECT_TRUE(
2253 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2254 EXPECT_TRUE(
2255 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002256 MediaExpectations media_expectations;
2257 media_expectations.ExpectBidirectionalAudioAndVideo();
2258 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2259}
2260
2261// This tests that if we negotiate after calling AddTransceiver but before we
2262// have a track, then set a track later, frames from the newly-set tracks are
2263// received end-to-end.
2264TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2265 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2266 ASSERT_TRUE(CreatePeerConnectionWrappers());
2267 ConnectFakeSignaling();
2268 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2269 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2270 auto caller_audio_sender = audio_result.MoveValue()->sender();
2271 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2272 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2273 auto caller_video_sender = video_result.MoveValue()->sender();
2274 callee()->SetRemoteOfferHandler([this] {
2275 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02002276 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002277 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002278 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002279 RtpTransceiverDirection::kSendRecv);
2280 });
2281 caller()->CreateAndSetAndSignalOffer();
2282 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2283 // Wait for ICE to complete, without any tracks being set.
2284 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2285 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2286 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2287 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2288 // Now set the tracks, and expect frames to immediately start flowing.
2289 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2290 auto callee_video_sender = callee()->pc()->GetSenders()[1];
Niels Möllerafb246b2022-04-20 14:26:50 +02002291 ASSERT_TRUE(
2292 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2293 ASSERT_TRUE(
2294 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2295 ASSERT_TRUE(
2296 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2297 ASSERT_TRUE(
2298 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002299 MediaExpectations media_expectations;
2300 media_expectations.ExpectBidirectionalAudioAndVideo();
2301 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002302}
2303
2304// This test verifies that a remote video track can be added via AddStream,
2305// and sent end-to-end. For this particular test, it's simply echoed back
2306// from the caller to the callee, rather than being forwarded to a third
2307// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002308TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07002309 ASSERT_TRUE(CreatePeerConnectionWrappers());
2310 ConnectFakeSignaling();
2311 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08002312 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002313 caller()->CreateAndSetAndSignalOffer();
2314 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002315 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07002316
2317 // Echo the stream back, and do a new offer/anwer (initiated by callee this
2318 // time).
2319 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2320 callee()->CreateAndSetAndSignalOffer();
2321 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2322
Seth Hampson2f0d7022018-02-20 11:54:42 -08002323 MediaExpectations media_expectations;
2324 media_expectations.ExpectBidirectionalVideo();
2325 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002326}
2327
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002328#if !defined(THREAD_SANITIZER)
2329// This test provokes TSAN errors. bugs.webrtc.org/11282
2330
deadbeef1dcb1642017-03-29 21:08:16 -07002331// Test that we achieve the expected end-to-end connection time, using a
2332// fake clock and simulated latency on the media and signaling paths.
2333// We use a TURN<->TURN connection because this is usually the quickest to
2334// set up initially, especially when we're confident the connection will work
2335// and can start sending media before we get a STUN response.
2336//
2337// With various optimizations enabled, here are the network delays we expect to
2338// be on the critical path:
2339// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2340// signaling answer (with DTLS fingerprint).
2341// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2342// using TURN<->TURN pair, and DTLS exchange is 4 packets,
2343// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01002344TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2345 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07002346 static constexpr int media_hop_delay_ms = 50;
2347 static constexpr int signaling_trip_delay_ms = 500;
2348 // For explanation of these values, see comment above.
2349 static constexpr int required_media_hops = 9;
2350 static constexpr int required_signaling_trips = 2;
2351 // For internal delays (such as posting an event asychronously).
2352 static constexpr int allowed_internal_delay_ms = 20;
2353 static constexpr int total_connection_time_ms =
2354 media_hop_delay_ms * required_media_hops +
2355 signaling_trip_delay_ms * required_signaling_trips +
2356 allowed_internal_delay_ms;
2357
2358 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2359 3478};
2360 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2361 0};
2362 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2363 3478};
2364 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2365 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002366 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2367 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002368
Seth Hampsonaed71642018-06-11 07:41:32 -07002369 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2370 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07002371 // Bypass permission check on received packets so media can be sent before
2372 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07002373 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
2374 turn_server_1->set_enable_permission_checks(false);
2375 });
2376 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
2377 turn_server_2->set_enable_permission_checks(false);
2378 });
deadbeef1dcb1642017-03-29 21:08:16 -07002379
2380 PeerConnectionInterface::RTCConfiguration client_1_config;
2381 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2382 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2383 ice_server_1.username = "test";
2384 ice_server_1.password = "test";
2385 client_1_config.servers.push_back(ice_server_1);
2386 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2387 client_1_config.presume_writable_when_fully_relayed = true;
2388
2389 PeerConnectionInterface::RTCConfiguration client_2_config;
2390 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2391 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2392 ice_server_2.username = "test";
2393 ice_server_2.password = "test";
2394 client_2_config.servers.push_back(ice_server_2);
2395 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2396 client_2_config.presume_writable_when_fully_relayed = true;
2397
2398 ASSERT_TRUE(
2399 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2400 // Set up the simulated delays.
2401 SetSignalingDelayMs(signaling_trip_delay_ms);
2402 ConnectFakeSignaling();
2403 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2404 virtual_socket_server()->UpdateDelayDistribution();
2405
2406 // Set "offer to receive audio/video" without adding any tracks, so we just
2407 // set up ICE/DTLS with no media.
2408 PeerConnectionInterface::RTCOfferAnswerOptions options;
2409 options.offer_to_receive_audio = 1;
2410 options.offer_to_receive_video = 1;
2411 caller()->SetOfferAnswerOptions(options);
2412 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07002413 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01002414 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002415 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2416 // If this is not done a DCHECK can be hit in ports.cc, because a large
2417 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07002418 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07002419}
2420
Philipp Hancke1fe14f22022-06-17 11:34:31 +02002421TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2422 OnIceCandidateFlushesGetStatsCache) {
2423 ASSERT_TRUE(CreatePeerConnectionWrappers());
2424 ConnectFakeSignaling();
2425 caller()->AddAudioTrack();
2426
2427 // Call getStats, assert there are no candidates.
2428 rtc::scoped_refptr<const webrtc::RTCStatsReport> first_report =
2429 caller()->NewGetStats();
2430 ASSERT_TRUE(first_report);
2431 auto first_candidate_stats =
2432 first_report->GetStatsOfType<webrtc::RTCLocalIceCandidateStats>();
2433 ASSERT_EQ(first_candidate_stats.size(), 0u);
2434
2435 // Start candidate gathering and wait for it to complete.
2436 caller()->CreateAndSetAndSignalOffer();
2437 ASSERT_TRUE_SIMULATED_WAIT(caller()->IceGatheringStateComplete(),
2438 kDefaultTimeout, FakeClock());
2439
2440 // Call getStats again, assert there are candidates now.
2441 rtc::scoped_refptr<const webrtc::RTCStatsReport> second_report =
2442 caller()->NewGetStats();
2443 ASSERT_TRUE(second_report);
2444 auto second_candidate_stats =
2445 second_report->GetStatsOfType<webrtc::RTCLocalIceCandidateStats>();
2446 ASSERT_NE(second_candidate_stats.size(), 0u);
2447
2448 // The fake clock ensures that no time has passed so the cache must have been
2449 // explicitly invalidated.
2450 EXPECT_EQ(first_report->timestamp_us(), second_report->timestamp_us());
2451}
2452
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002453#endif // !defined(THREAD_SANITIZER)
2454
Jonas Orelandbdcee282017-10-10 14:01:40 +02002455// Verify that a TurnCustomizer passed in through RTCConfiguration
2456// is actually used by the underlying TURN candidate pair.
2457// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002458TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02002459 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2460 3478};
2461 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2462 0};
2463 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2464 3478};
2465 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2466 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002467 CreateTurnServer(turn_server_1_internal_address,
2468 turn_server_1_external_address);
2469 CreateTurnServer(turn_server_2_internal_address,
2470 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002471
2472 PeerConnectionInterface::RTCConfiguration client_1_config;
2473 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2474 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2475 ice_server_1.username = "test";
2476 ice_server_1.password = "test";
2477 client_1_config.servers.push_back(ice_server_1);
2478 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002479 auto* customizer1 = CreateTurnCustomizer();
2480 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002481
2482 PeerConnectionInterface::RTCConfiguration client_2_config;
2483 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2484 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2485 ice_server_2.username = "test";
2486 ice_server_2.password = "test";
2487 client_2_config.servers.push_back(ice_server_2);
2488 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002489 auto* customizer2 = CreateTurnCustomizer();
2490 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002491
2492 ASSERT_TRUE(
2493 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2494 ConnectFakeSignaling();
2495
2496 // Set "offer to receive audio/video" without adding any tracks, so we just
2497 // set up ICE/DTLS with no media.
2498 PeerConnectionInterface::RTCOfferAnswerOptions options;
2499 options.offer_to_receive_audio = 1;
2500 options.offer_to_receive_video = 1;
2501 caller()->SetOfferAnswerOptions(options);
2502 caller()->CreateAndSetAndSignalOffer();
2503 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2504
Seth Hampsonaed71642018-06-11 07:41:32 -07002505 ExpectTurnCustomizerCountersIncremented(customizer1);
2506 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002507}
2508
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002509// Verifies that you can use TCP instead of UDP to connect to a TURN server and
2510// send media between the caller and the callee.
2511TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2512 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2513 3478};
2514 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2515
2516 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07002517 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2518 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002519
2520 webrtc::PeerConnectionInterface::IceServer ice_server;
2521 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2522 ice_server.username = "test";
2523 ice_server.password = "test";
2524
2525 PeerConnectionInterface::RTCConfiguration client_1_config;
2526 client_1_config.servers.push_back(ice_server);
2527 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2528
2529 PeerConnectionInterface::RTCConfiguration client_2_config;
2530 client_2_config.servers.push_back(ice_server);
2531 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2532
2533 ASSERT_TRUE(
2534 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2535
2536 // Do normal offer/answer and wait for ICE to complete.
2537 ConnectFakeSignaling();
2538 caller()->AddAudioVideoTracks();
2539 callee()->AddAudioVideoTracks();
2540 caller()->CreateAndSetAndSignalOffer();
2541 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2542 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2543 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2544
2545 MediaExpectations media_expectations;
2546 media_expectations.ExpectBidirectionalAudioAndVideo();
2547 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2548}
2549
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002550// Verify that a SSLCertificateVerifier passed in through
2551// PeerConnectionDependencies is actually used by the underlying SSL
2552// implementation to determine whether a certificate presented by the TURN
2553// server is accepted by the client. Note that openssladapter_unittest.cc
2554// contains more detailed, lower-level tests.
2555TEST_P(PeerConnectionIntegrationTest,
2556 SSLCertificateVerifierUsedForTurnConnections) {
2557 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2558 3478};
2559 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2560
2561 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2562 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002563 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2564 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002565
2566 webrtc::PeerConnectionInterface::IceServer ice_server;
2567 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2568 ice_server.username = "test";
2569 ice_server.password = "test";
2570
2571 PeerConnectionInterface::RTCConfiguration client_1_config;
2572 client_1_config.servers.push_back(ice_server);
2573 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2574
2575 PeerConnectionInterface::RTCConfiguration client_2_config;
2576 client_2_config.servers.push_back(ice_server);
2577 // Setting the type to kRelay forces the connection to go through a TURN
2578 // server.
2579 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2580
2581 // Get a copy to the pointer so we can verify calls later.
2582 rtc::TestCertificateVerifier* client_1_cert_verifier =
2583 new rtc::TestCertificateVerifier();
2584 client_1_cert_verifier->verify_certificate_ = true;
2585 rtc::TestCertificateVerifier* client_2_cert_verifier =
2586 new rtc::TestCertificateVerifier();
2587 client_2_cert_verifier->verify_certificate_ = true;
2588
2589 // Create the dependencies with the test certificate verifier.
2590 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2591 client_1_deps.tls_cert_verifier =
2592 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2593 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2594 client_2_deps.tls_cert_verifier =
2595 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2596
2597 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2598 client_1_config, std::move(client_1_deps), client_2_config,
2599 std::move(client_2_deps)));
2600 ConnectFakeSignaling();
2601
2602 // Set "offer to receive audio/video" without adding any tracks, so we just
2603 // set up ICE/DTLS with no media.
2604 PeerConnectionInterface::RTCOfferAnswerOptions options;
2605 options.offer_to_receive_audio = 1;
2606 options.offer_to_receive_video = 1;
2607 caller()->SetOfferAnswerOptions(options);
2608 caller()->CreateAndSetAndSignalOffer();
2609 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2610
2611 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2612 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002613}
2614
Qingsi Wang25ec8882019-11-15 12:33:05 -08002615// Test that the injected ICE transport factory is used to create ICE transports
2616// for WebRTC connections.
2617TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2618 PeerConnectionInterface::RTCConfiguration default_config;
2619 PeerConnectionDependencies dependencies(nullptr);
2620 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2621 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2622 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02002623 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2624 std::move(dependencies), nullptr,
2625 /*reset_encoder_factory=*/false,
2626 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08002627 ASSERT_TRUE(wrapper);
2628 wrapper->CreateDataChannel();
Tommi87f70902021-04-27 14:43:08 +02002629 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02002630 wrapper->pc()->SetLocalDescription(observer.get(),
Qingsi Wang25ec8882019-11-15 12:33:05 -08002631 wrapper->CreateOfferAndWait().release());
2632}
2633
deadbeefc964d0b2017-04-03 10:03:35 -07002634// Test that audio and video flow end-to-end when codec names don't use the
2635// expected casing, given that they're supposed to be case insensitive. To test
2636// this, all but one codec is removed from each media description, and its
2637// casing is changed.
2638//
2639// In the past, this has regressed and caused crashes/black video, due to the
2640// fact that code at some layers was doing case-insensitive comparisons and
2641// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002642TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07002643 ASSERT_TRUE(CreatePeerConnectionWrappers());
2644 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002645 caller()->AddAudioVideoTracks();
2646 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07002647
2648 // Remove all but one audio/video codec (opus and VP8), and change the
2649 // casing of the caller's generated offer.
2650 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2651 cricket::AudioContentDescription* audio =
2652 GetFirstAudioContentDescription(description);
2653 ASSERT_NE(nullptr, audio);
2654 auto audio_codecs = audio->codecs();
2655 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2656 [](const cricket::AudioCodec& codec) {
2657 return codec.name != "opus";
2658 }),
2659 audio_codecs.end());
2660 ASSERT_EQ(1u, audio_codecs.size());
2661 audio_codecs[0].name = "OpUs";
2662 audio->set_codecs(audio_codecs);
2663
2664 cricket::VideoContentDescription* video =
2665 GetFirstVideoContentDescription(description);
2666 ASSERT_NE(nullptr, video);
2667 auto video_codecs = video->codecs();
2668 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2669 [](const cricket::VideoCodec& codec) {
2670 return codec.name != "VP8";
2671 }),
2672 video_codecs.end());
2673 ASSERT_EQ(1u, video_codecs.size());
2674 video_codecs[0].name = "vP8";
2675 video->set_codecs(video_codecs);
2676 });
2677
2678 caller()->CreateAndSetAndSignalOffer();
2679 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2680
2681 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002682 MediaExpectations media_expectations;
2683 media_expectations.ExpectBidirectionalAudioAndVideo();
2684 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07002685}
2686
Jonas Oreland49ac5952018-09-26 16:04:32 +02002687TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07002688 ASSERT_TRUE(CreatePeerConnectionWrappers());
2689 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002690 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07002691 caller()->CreateAndSetAndSignalOffer();
2692 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07002693 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002694 MediaExpectations media_expectations;
2695 media_expectations.CalleeExpectsSomeAudio(1);
2696 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02002697 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07002698 auto receiver = callee()->pc()->GetReceivers()[0];
2699 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002700 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07002701 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2702 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02002703 sources[0].source_id());
2704 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2705}
2706
2707TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2708 ASSERT_TRUE(CreatePeerConnectionWrappers());
2709 ConnectFakeSignaling();
2710 caller()->AddVideoTrack();
2711 caller()->CreateAndSetAndSignalOffer();
2712 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2713 // Wait for one video frame to be received by the callee.
2714 MediaExpectations media_expectations;
2715 media_expectations.CalleeExpectsSomeVideo(1);
2716 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2717 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2718 auto receiver = callee()->pc()->GetReceivers()[0];
2719 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2720 auto sources = receiver->GetSources();
2721 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02002722 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002723 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2724 sources[0].source_id());
2725 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07002726}
2727
deadbeef2f425aa2017-04-14 10:41:32 -07002728// Test that if a track is removed and added again with a different stream ID,
2729// the new stream ID is successfully communicated in SDP and media continues to
2730// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002731// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2732// it will not reuse a transceiver that has already been sending. After creating
2733// a new transceiver it tries to create an offer with two senders of the same
2734// track ids and it fails.
2735TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07002736 ASSERT_TRUE(CreatePeerConnectionWrappers());
2737 ConnectFakeSignaling();
2738
deadbeef2f425aa2017-04-14 10:41:32 -07002739 // Add track using stream 1, do offer/answer.
2740 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2741 caller()->CreateLocalAudioTrack();
2742 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07002743 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07002744 caller()->CreateAndSetAndSignalOffer();
2745 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002746 {
2747 MediaExpectations media_expectations;
2748 media_expectations.CalleeExpectsSomeAudio(1);
2749 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2750 }
deadbeef2f425aa2017-04-14 10:41:32 -07002751 // Remove the sender, and create a new one with the new stream.
Harald Alvestrand93dd7632022-01-19 12:28:45 +00002752 caller()->pc()->RemoveTrackOrError(sender);
Steve Antond78323f2018-07-11 11:13:44 -07002753 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07002754 caller()->CreateAndSetAndSignalOffer();
2755 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2756 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002757 {
2758 MediaExpectations media_expectations;
2759 media_expectations.CalleeExpectsSomeAudio();
2760 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2761 }
deadbeef2f425aa2017-04-14 10:41:32 -07002762}
2763
Seth Hampson2f0d7022018-02-20 11:54:42 -08002764TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02002765 ASSERT_TRUE(CreatePeerConnectionWrappers());
2766 ConnectFakeSignaling();
2767
Mirko Bonadei317a1f02019-09-17 17:06:18 +02002768 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002769 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
2770 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02002771 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01002772 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2773 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02002774
Steve Anton15324772018-01-16 10:26:49 -08002775 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02002776 caller()->CreateAndSetAndSignalOffer();
2777 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2778}
2779
Steve Antonede9ca52017-10-16 13:04:27 -07002780// Test that if candidates are only signaled by applying full session
2781// descriptions (instead of using AddIceCandidate), the peers can connect to
2782// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002783TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07002784 ASSERT_TRUE(CreatePeerConnectionWrappers());
2785 // Each side will signal the session descriptions but not candidates.
2786 ConnectFakeSignalingForSdpOnly();
2787
2788 // Add audio video track and exchange the initial offer/answer with media
2789 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08002790 caller()->AddAudioVideoTracks();
2791 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002792 caller()->CreateAndSetAndSignalOffer();
2793
2794 // Wait for all candidates to be gathered on both the caller and callee.
2795 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2796 caller()->ice_gathering_state(), kDefaultTimeout);
2797 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2798 callee()->ice_gathering_state(), kDefaultTimeout);
2799
2800 // The candidates will now be included in the session description, so
2801 // signaling them will start the ICE connection.
2802 caller()->CreateAndSetAndSignalOffer();
2803 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2804
2805 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002806 MediaExpectations media_expectations;
2807 media_expectations.ExpectBidirectionalAudioAndVideo();
2808 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07002809}
2810
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002811#if !defined(THREAD_SANITIZER)
2812// These tests provokes TSAN errors. See bugs.webrtc.org/11305.
2813
henrika5f6bf242017-11-01 11:06:56 +01002814// Test that SetAudioPlayout can be used to disable audio playout from the
2815// start, then later enable it. This may be useful, for example, if the caller
2816// needs to play a local ringtone until some event occurs, after which it
2817// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002818TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01002819 ASSERT_TRUE(CreatePeerConnectionWrappers());
2820 ConnectFakeSignaling();
2821
2822 // Set up audio-only call where audio playout is disabled on caller's side.
2823 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08002824 caller()->AddAudioTrack();
2825 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002826 caller()->CreateAndSetAndSignalOffer();
2827 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2828
2829 // Pump messages for a second.
2830 WAIT(false, 1000);
2831 // Since audio playout is disabled, the caller shouldn't have received
2832 // anything (at the playout level, at least).
2833 EXPECT_EQ(0, caller()->audio_frames_received());
2834 // As a sanity check, make sure the callee (for which playout isn't disabled)
2835 // did still see frames on its audio level.
2836 ASSERT_GT(callee()->audio_frames_received(), 0);
2837
2838 // Enable playout again, and ensure audio starts flowing.
2839 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002840 MediaExpectations media_expectations;
2841 media_expectations.ExpectBidirectionalAudio();
2842 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01002843}
2844
Harald Alvestrand39993842021-02-17 09:05:31 +00002845double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
henrika5f6bf242017-11-01 11:06:56 +01002846 auto report = pc->NewGetStats();
2847 auto track_stats_list =
2848 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2849 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
2850 for (const auto* track_stats : track_stats_list) {
2851 if (track_stats->remote_source.is_defined() &&
2852 *track_stats->remote_source) {
2853 remote_track_stats = track_stats;
2854 break;
2855 }
2856 }
2857
2858 if (!remote_track_stats->total_audio_energy.is_defined()) {
2859 return 0.0;
2860 }
2861 return *remote_track_stats->total_audio_energy;
2862}
2863
2864// Test that if audio playout is disabled via the SetAudioPlayout() method, then
2865// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002866TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01002867 DisableAudioPlayoutStillGeneratesAudioStats) {
2868 ASSERT_TRUE(CreatePeerConnectionWrappers());
2869 ConnectFakeSignaling();
2870
2871 // Set up audio-only call where playout is disabled but audio-processing is
2872 // still active.
Steve Anton15324772018-01-16 10:26:49 -08002873 caller()->AddAudioTrack();
2874 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002875 caller()->pc()->SetAudioPlayout(false);
2876
2877 caller()->CreateAndSetAndSignalOffer();
2878 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2879
2880 // Wait for the callee to receive audio stats.
2881 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
2882}
2883
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002884#endif // !defined(THREAD_SANITIZER)
2885
henrika4f167df2017-11-01 14:45:55 +01002886// Test that SetAudioRecording can be used to disable audio recording from the
2887// start, then later enable it. This may be useful, for example, if the caller
2888// wants to ensure that no audio resources are active before a certain state
2889// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002890TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01002891 ASSERT_TRUE(CreatePeerConnectionWrappers());
2892 ConnectFakeSignaling();
2893
2894 // Set up audio-only call where audio recording is disabled on caller's side.
2895 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08002896 caller()->AddAudioTrack();
2897 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01002898 caller()->CreateAndSetAndSignalOffer();
2899 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2900
2901 // Pump messages for a second.
2902 WAIT(false, 1000);
2903 // Since caller has disabled audio recording, the callee shouldn't have
2904 // received anything.
2905 EXPECT_EQ(0, callee()->audio_frames_received());
2906 // As a sanity check, make sure the caller did still see frames on its
2907 // audio level since audio recording is enabled on the calle side.
2908 ASSERT_GT(caller()->audio_frames_received(), 0);
2909
2910 // Enable audio recording again, and ensure audio starts flowing.
2911 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002912 MediaExpectations media_expectations;
2913 media_expectations.ExpectBidirectionalAudio();
2914 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01002915}
2916
Qingsi Wang7685e862018-06-11 20:15:46 -07002917TEST_P(PeerConnectionIntegrationTest,
2918 IceEventsGeneratedAndLoggedInRtcEventLog) {
2919 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
2920 ConnectFakeSignaling();
2921 PeerConnectionInterface::RTCOfferAnswerOptions options;
2922 options.offer_to_receive_audio = 1;
2923 caller()->SetOfferAnswerOptions(options);
2924 caller()->CreateAndSetAndSignalOffer();
2925 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2926 ASSERT_NE(nullptr, caller()->event_log_factory());
2927 ASSERT_NE(nullptr, callee()->event_log_factory());
2928 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002929 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002930 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002931 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002932 ASSERT_NE(nullptr, caller_event_log);
2933 ASSERT_NE(nullptr, callee_event_log);
2934 int caller_ice_config_count = caller_event_log->GetEventCount(
2935 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2936 int caller_ice_event_count = caller_event_log->GetEventCount(
2937 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2938 int callee_ice_config_count = callee_event_log->GetEventCount(
2939 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2940 int callee_ice_event_count = callee_event_log->GetEventCount(
2941 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2942 EXPECT_LT(0, caller_ice_config_count);
2943 EXPECT_LT(0, caller_ice_event_count);
2944 EXPECT_LT(0, callee_ice_config_count);
2945 EXPECT_LT(0, callee_ice_event_count);
2946}
2947
Qingsi Wangc129c352019-04-18 10:41:58 -07002948TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07002949 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2950 3478};
2951 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2952
2953 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
2954
2955 webrtc::PeerConnectionInterface::IceServer ice_server;
2956 ice_server.urls.push_back("turn:88.88.88.0:3478");
2957 ice_server.username = "test";
2958 ice_server.password = "test";
2959
2960 PeerConnectionInterface::RTCConfiguration caller_config;
2961 caller_config.servers.push_back(ice_server);
2962 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
2963 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07002964 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07002965
2966 PeerConnectionInterface::RTCConfiguration callee_config;
2967 callee_config.servers.push_back(ice_server);
2968 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
2969 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07002970 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07002971
2972 ASSERT_TRUE(
2973 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
2974
2975 // Do normal offer/answer and wait for ICE to complete.
2976 ConnectFakeSignaling();
2977 caller()->AddAudioVideoTracks();
2978 callee()->AddAudioVideoTracks();
2979 caller()->CreateAndSetAndSignalOffer();
2980 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2981 // Since we are doing continual gathering, the ICE transport does not reach
2982 // kIceGatheringComplete (see
2983 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
2984 // kIceConnectionComplete.
2985 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2986 caller()->ice_connection_state(), kDefaultTimeout);
2987 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2988 callee()->ice_connection_state(), kDefaultTimeout);
2989 // Note that we cannot use the metric
Artem Titovcfea2182021-08-10 01:22:31 +02002990 // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
Qingsi Wangc129c352019-04-18 10:41:58 -07002991 // metric is only populated when we reach kIceConnectionComplete in the
2992 // current implementation.
2993 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
2994 caller()->last_candidate_gathered().type());
2995 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
2996 callee()->last_candidate_gathered().type());
2997
2998 // Loosen the caller's candidate filter.
2999 caller_config = caller()->pc()->GetConfiguration();
3000 caller_config.type = webrtc::PeerConnectionInterface::kAll;
3001 caller()->pc()->SetConfiguration(caller_config);
3002 // We should have gathered a new host candidate.
3003 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3004 caller()->last_candidate_gathered().type(), kDefaultTimeout);
3005
3006 // Loosen the callee's candidate filter.
3007 callee_config = callee()->pc()->GetConfiguration();
3008 callee_config.type = webrtc::PeerConnectionInterface::kAll;
3009 callee()->pc()->SetConfiguration(callee_config);
3010 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3011 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02003012
3013 // Create an offer and verify that it does not contain an ICE restart (i.e new
3014 // ice credentials).
3015 std::string caller_ufrag_pre_offer = caller()
3016 ->pc()
3017 ->local_description()
3018 ->description()
3019 ->transport_infos()[0]
3020 .description.ice_ufrag;
3021 caller()->CreateAndSetAndSignalOffer();
3022 std::string caller_ufrag_post_offer = caller()
3023 ->pc()
3024 ->local_description()
3025 ->description()
3026 ->transport_infos()[0]
3027 .description.ice_ufrag;
3028 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07003029}
3030
Eldar Relloda13ea22019-06-01 12:23:43 +03003031TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03003032 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3033 3478};
3034 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3035
3036 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3037
3038 webrtc::PeerConnectionInterface::IceServer ice_server;
3039 ice_server.urls.push_back("turn:88.88.88.0:3478");
3040 ice_server.username = "test";
3041 ice_server.password = "123";
3042
3043 PeerConnectionInterface::RTCConfiguration caller_config;
3044 caller_config.servers.push_back(ice_server);
3045 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3046 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3047
3048 PeerConnectionInterface::RTCConfiguration callee_config;
3049 callee_config.servers.push_back(ice_server);
3050 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3051 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3052
3053 ASSERT_TRUE(
3054 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3055
3056 // Do normal offer/answer and wait for ICE to complete.
3057 ConnectFakeSignaling();
3058 caller()->AddAudioVideoTracks();
3059 callee()->AddAudioVideoTracks();
3060 caller()->CreateAndSetAndSignalOffer();
3061 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3062 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3063 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3064 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02003065 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03003066}
3067
Eldar Rellofa8019c2020-05-14 11:59:33 +03003068TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3069 webrtc::PeerConnectionInterface::IceServer ice_server;
3070 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3071 ice_server.username = "test";
3072 ice_server.password = "test";
3073
3074 PeerConnectionInterface::RTCConfiguration caller_config;
3075 caller_config.servers.push_back(ice_server);
3076 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3077 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3078
3079 PeerConnectionInterface::RTCConfiguration callee_config;
3080 callee_config.servers.push_back(ice_server);
3081 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3082 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3083
3084 ASSERT_TRUE(
3085 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3086
3087 // Do normal offer/answer and wait for ICE to complete.
3088 ConnectFakeSignaling();
3089 caller()->AddAudioVideoTracks();
3090 callee()->AddAudioVideoTracks();
3091 caller()->CreateAndSetAndSignalOffer();
3092 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3093 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3094 EXPECT_EQ(caller()->error_event().address, "");
3095}
3096
Eldar Rello5ab79e62019-10-09 18:29:44 +03003097TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3098 AudioKeepsFlowingAfterImplicitRollback) {
3099 PeerConnectionInterface::RTCConfiguration config;
3100 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3101 config.enable_implicit_rollback = true;
3102 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3103 ConnectFakeSignaling();
3104 caller()->AddAudioTrack();
3105 callee()->AddAudioTrack();
3106 caller()->CreateAndSetAndSignalOffer();
3107 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3108 MediaExpectations media_expectations;
3109 media_expectations.ExpectBidirectionalAudio();
3110 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3111 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
3112 caller()->AddVideoTrack();
3113 callee()->AddVideoTrack();
Tommi87f70902021-04-27 14:43:08 +02003114 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003115 callee()->pc()->SetLocalDescription(observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003116 callee()->CreateOfferAndWait().release());
3117 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3118 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
3119 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3120 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3121}
3122
3123TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3124 ImplicitRollbackVisitsStableState) {
3125 RTCConfiguration config;
3126 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3127 config.enable_implicit_rollback = true;
3128
3129 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3130
Tommi87f70902021-04-27 14:43:08 +02003131 auto sld_observer =
3132 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003133 callee()->pc()->SetLocalDescription(sld_observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003134 callee()->CreateOfferAndWait().release());
3135 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3136 EXPECT_EQ(sld_observer->error(), "");
3137
Tommi87f70902021-04-27 14:43:08 +02003138 auto srd_observer =
3139 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003140 callee()->pc()->SetRemoteDescription(
Niels Möllerafb246b2022-04-20 14:26:50 +02003141 srd_observer.get(), caller()->CreateOfferAndWait().release());
Eldar Rello5ab79e62019-10-09 18:29:44 +03003142 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3143 EXPECT_EQ(srd_observer->error(), "");
3144
3145 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3146 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3147 PeerConnectionInterface::kStable,
3148 PeerConnectionInterface::kHaveRemoteOffer));
3149}
3150
Eldar Rellobd9c33a2020-10-01 17:52:45 +03003151TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3152 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3153 ASSERT_TRUE(CreatePeerConnectionWrappers());
3154 ConnectFakeSignaling();
3155 caller()->AddVideoTrack();
3156 callee()->AddVideoTrack();
3157 auto munger = [](cricket::SessionDescription* desc) {
3158 cricket::VideoContentDescription* video =
3159 GetFirstVideoContentDescription(desc);
3160 auto codecs = video->codecs();
3161 for (auto&& codec : codecs) {
3162 if (codec.name == "H264") {
3163 std::string value;
3164 // The parameter is not supposed to be present in SDP by default.
3165 EXPECT_FALSE(
3166 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3167 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3168 std::string(""));
3169 }
3170 }
3171 video->set_codecs(codecs);
3172 };
3173 // Munge local offer for SLD.
3174 caller()->SetGeneratedSdpMunger(munger);
3175 // Munge remote answer for SRD.
3176 caller()->SetReceivedSdpMunger(munger);
3177 caller()->CreateAndSetAndSignalOffer();
3178 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3179 // Observe that after munging the parameter is present in generated SDP.
3180 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3181 cricket::VideoContentDescription* video =
3182 GetFirstVideoContentDescription(desc);
3183 for (auto&& codec : video->codecs()) {
3184 if (codec.name == "H264") {
3185 std::string value;
3186 EXPECT_TRUE(
3187 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3188 }
3189 }
3190 });
3191 caller()->CreateOfferAndWait();
3192}
3193
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003194TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00003195 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003196 PeerConnectionInterface::RTCConfiguration config;
3197 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3198 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3199 ConnectFakeSignaling();
3200 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3201
3202 caller()->CreateAndSetAndSignalOffer();
3203 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3204 int current_size = caller()->pc()->GetTransceivers().size();
3205 // Add more tracks until we get close to having issues.
3206 // Issues have been seen at:
3207 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003208 // - 16 tracks on android_arm_dbg (flaky)
3209 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003210 // Double the number of tracks
3211 for (int i = 0; i < current_size; i++) {
3212 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3213 }
3214 current_size = caller()->pc()->GetTransceivers().size();
3215 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3216 auto start_time_ms = rtc::TimeMillis();
3217 caller()->CreateAndSetAndSignalOffer();
3218 // We want to stop when the time exceeds one second.
3219 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3220 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3221 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3222 ASSERT_GT(1000, elapsed_time_ms)
3223 << "Audio transceivers: Negotiation took too long after "
3224 << current_size << " tracks added";
3225 }
3226}
3227
3228TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3229 RenegotiateManyVideoTransceivers) {
3230 PeerConnectionInterface::RTCConfiguration config;
3231 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3232 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3233 ConnectFakeSignaling();
3234 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3235
3236 caller()->CreateAndSetAndSignalOffer();
3237 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3238 int current_size = caller()->pc()->GetTransceivers().size();
3239 // Add more tracks until we get close to having issues.
3240 // Issues have been seen at:
3241 // - 96 on a Linux workstation
3242 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3243 // - 32 on android_arm64_rel and linux_dbg bots
Harald Alvestrand785e23b2021-03-15 21:26:27 +00003244 // - 16 on Android 64 (Nexus 5x)
3245 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003246 // Double the number of tracks
3247 for (int i = 0; i < current_size; i++) {
3248 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3249 }
3250 current_size = caller()->pc()->GetTransceivers().size();
3251 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3252 auto start_time_ms = rtc::TimeMillis();
3253 caller()->CreateAndSetAndSignalOffer();
3254 // We want to stop when the time exceeds one second.
3255 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3256 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3257 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3258 ASSERT_GT(1000, elapsed_time_ms)
3259 << "Video transceivers: Negotiation took too long after "
3260 << current_size << " tracks added";
3261 }
3262}
3263
Harald Alvestrand94324f22021-01-13 12:31:53 +00003264TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3265 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3266 PeerConnectionInterface::RTCConfiguration config;
3267 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3268 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3269 ConnectFakeSignaling();
3270 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003271 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003272 caller()->CreateAndSetAndSignalOffer();
3273 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3274 // Wait until we can see the audio flowing.
3275 MediaExpectations media_expectations;
3276 media_expectations.CalleeExpectsSomeAudio();
3277 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3278
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003279 // Get the baseline numbers for audio_packets and audio_delay
3280 // in both directions.
3281 caller()->StartWatchingDelayStats();
3282 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003283
3284 int current_size = caller()->pc()->GetTransceivers().size();
3285 // Add more tracks until we get close to having issues.
3286 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003287 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00003288 // Double the number of tracks
3289 for (int i = 0; i < current_size; i++) {
3290 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3291 }
3292 current_size = caller()->pc()->GetTransceivers().size();
3293 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3294 auto start_time_ms = rtc::TimeMillis();
3295 caller()->CreateAndSetAndSignalOffer();
3296 // We want to stop when the time exceeds one second.
3297 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3298 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3299 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3300 // This is a guard against the test using excessive amounts of time.
3301 ASSERT_GT(5000, elapsed_time_ms)
3302 << "Video transceivers: Negotiation took too long after "
3303 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003304 caller()->UpdateDelayStats("caller reception", current_size);
3305 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00003306 }
3307}
3308
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003309INSTANTIATE_TEST_SUITE_P(
3310 PeerConnectionIntegrationTest,
3311 PeerConnectionIntegrationTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003312 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003313 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3314 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3315 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Steve Antond3679212018-01-17 17:41:02 -08003316
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003317INSTANTIATE_TEST_SUITE_P(
3318 PeerConnectionIntegrationTest,
3319 PeerConnectionIntegrationTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02003320 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003321 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3322 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3323 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Yves Gerey100fe632020-01-17 19:15:53 +01003324
Steve Anton74255ff2018-01-24 18:32:57 -08003325// Tests that verify interoperability between Plan B and Unified Plan
3326// PeerConnections.
3327class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003328 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08003329 public ::testing::WithParamInterface<
3330 std::tuple<SdpSemantics, SdpSemantics>> {
3331 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003332 // Setting the SdpSemantics for the base test to kDefault does not matter
3333 // because we specify not to use the test semantics when creating
Harald Alvestrand39993842021-02-17 09:05:31 +00003334 // PeerConnectionIntegrationWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08003335 PeerConnectionIntegrationInteropTest()
Florent Castelli15a38de2022-04-06 00:38:21 +02003336 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED),
Seth Hampson2f0d7022018-02-20 11:54:42 -08003337 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08003338 callee_semantics_(std::get<1>(GetParam())) {}
3339
3340 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07003341 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3342 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08003343 }
3344
3345 const SdpSemantics caller_semantics_;
3346 const SdpSemantics callee_semantics_;
3347};
3348
3349TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3350 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3351 ConnectFakeSignaling();
3352
3353 caller()->CreateAndSetAndSignalOffer();
3354 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3355}
3356
3357TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3358 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3359 ConnectFakeSignaling();
3360 auto audio_sender = caller()->AddAudioTrack();
3361
3362 caller()->CreateAndSetAndSignalOffer();
3363 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3364
3365 // Verify that one audio receiver has been created on the remote and that it
3366 // has the same track ID as the sending track.
3367 auto receivers = callee()->pc()->GetReceivers();
3368 ASSERT_EQ(1u, receivers.size());
3369 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3370 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3371
Seth Hampson2f0d7022018-02-20 11:54:42 -08003372 MediaExpectations media_expectations;
3373 media_expectations.CalleeExpectsSomeAudio();
3374 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003375}
3376
3377TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3378 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3379 ConnectFakeSignaling();
3380 auto video_sender = caller()->AddVideoTrack();
3381 auto audio_sender = caller()->AddAudioTrack();
3382
3383 caller()->CreateAndSetAndSignalOffer();
3384 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3385
3386 // Verify that one audio and one video receiver have been created on the
3387 // remote and that they have the same track IDs as the sending tracks.
3388 auto audio_receivers =
3389 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3390 ASSERT_EQ(1u, audio_receivers.size());
3391 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3392 auto video_receivers =
3393 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3394 ASSERT_EQ(1u, video_receivers.size());
3395 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3396
Seth Hampson2f0d7022018-02-20 11:54:42 -08003397 MediaExpectations media_expectations;
3398 media_expectations.CalleeExpectsSomeAudioAndVideo();
3399 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003400}
3401
3402TEST_P(PeerConnectionIntegrationInteropTest,
3403 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3404 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3405 ConnectFakeSignaling();
3406 caller()->AddAudioVideoTracks();
3407 callee()->AddAudioVideoTracks();
3408
3409 caller()->CreateAndSetAndSignalOffer();
3410 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3411
Seth Hampson2f0d7022018-02-20 11:54:42 -08003412 MediaExpectations media_expectations;
3413 media_expectations.ExpectBidirectionalAudioAndVideo();
3414 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003415}
3416
3417TEST_P(PeerConnectionIntegrationInteropTest,
3418 ReverseRolesOneAudioLocalToOneVideoRemote) {
3419 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3420 ConnectFakeSignaling();
3421 caller()->AddAudioTrack();
3422 callee()->AddVideoTrack();
3423
3424 caller()->CreateAndSetAndSignalOffer();
3425 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3426
3427 // Verify that only the audio track has been negotiated.
3428 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3429 // Might also check that the callee's NegotiationNeeded flag is set.
3430
3431 // Reverse roles.
3432 callee()->CreateAndSetAndSignalOffer();
3433 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3434
Seth Hampson2f0d7022018-02-20 11:54:42 -08003435 MediaExpectations media_expectations;
3436 media_expectations.CallerExpectsSomeVideo();
3437 media_expectations.CalleeExpectsSomeAudio();
3438 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003439}
3440
Taylor Brandstetter1c7ecef2021-08-11 12:38:35 -07003441TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3442 ASSERT_TRUE(CreatePeerConnectionWrappers());
3443 ConnectFakeSignaling();
3444 caller()->AddAudioVideoTracks();
3445 caller()->CreateAndSetAndSignalOffer();
3446 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3447 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3448 caller()->ExpectCandidates(0);
3449 callee()->ExpectCandidates(0);
3450 caller()->AddAudioTrack();
3451 caller()->CreateAndSetAndSignalOffer();
3452 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3453}
3454
Harald Alvestrand35ba0c52022-05-05 07:37:41 +00003455TEST_P(PeerConnectionIntegrationTest, MediaCallWithoutMediaEngineFails) {
3456 ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
3457 // AddTrack should fail.
3458 EXPECT_FALSE(
3459 caller()->pc()->AddTrack(caller()->CreateLocalAudioTrack(), {}).ok());
3460}
3461
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003462INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07003463 PeerConnectionIntegrationTest,
3464 PeerConnectionIntegrationInteropTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003465 Values(std::make_tuple(SdpSemantics::kPlanB_DEPRECATED,
3466 SdpSemantics::kUnifiedPlan),
3467 std::make_tuple(SdpSemantics::kUnifiedPlan,
3468 SdpSemantics::kPlanB_DEPRECATED)));
Steve Antonba42e992018-04-09 14:10:01 -07003469
3470// Test that if the Unified Plan side offers two video tracks then the Plan B
3471// side will only see the first one and ignore the second.
3472TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07003473 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
Florent Castelli15a38de2022-04-06 00:38:21 +02003474 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB_DEPRECATED));
Steve Anton74255ff2018-01-24 18:32:57 -08003475 ConnectFakeSignaling();
3476 auto first_sender = caller()->AddVideoTrack();
3477 caller()->AddVideoTrack();
3478
3479 caller()->CreateAndSetAndSignalOffer();
3480 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3481
3482 // Verify that there is only one receiver and it corresponds to the first
3483 // added track.
3484 auto receivers = callee()->pc()->GetReceivers();
3485 ASSERT_EQ(1u, receivers.size());
3486 EXPECT_TRUE(receivers[0]->track()->enabled());
3487 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3488
Seth Hampson2f0d7022018-02-20 11:54:42 -08003489 MediaExpectations media_expectations;
3490 media_expectations.CalleeExpectsSomeVideo();
3491 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003492}
3493
Steve Anton2bed3972019-01-04 17:04:30 -08003494// Test that if the initial offer tagged BUNDLE section is rejected due to its
3495// associated RtpTransceiver being stopped and another transceiver is added,
3496// then renegotiation causes the callee to receive the new video track without
3497// error.
3498// This is a regression test for bugs.webrtc.org/9954
3499TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3500 ReOfferWithStoppedBundleTaggedTransceiver) {
3501 RTCConfiguration config;
3502 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3503 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3504 ConnectFakeSignaling();
3505 auto audio_transceiver_or_error =
3506 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3507 ASSERT_TRUE(audio_transceiver_or_error.ok());
3508 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3509
3510 caller()->CreateAndSetAndSignalOffer();
3511 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3512 {
3513 MediaExpectations media_expectations;
3514 media_expectations.CalleeExpectsSomeAudio();
3515 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3516 }
3517
Harald Alvestrand6060df52020-08-11 09:54:02 +02003518 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08003519 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3520
3521 caller()->CreateAndSetAndSignalOffer();
3522 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3523 {
3524 MediaExpectations media_expectations;
3525 media_expectations.CalleeExpectsSomeVideo();
3526 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3527 }
3528}
3529
Harald Alvestrandbedb6052020-08-20 14:50:10 +02003530TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3531 StopTransceiverRemovesDtlsTransports) {
3532 RTCConfiguration config;
3533 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3534 ConnectFakeSignaling();
3535 auto audio_transceiver_or_error =
3536 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3537 ASSERT_TRUE(audio_transceiver_or_error.ok());
3538 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3539
3540 caller()->CreateAndSetAndSignalOffer();
3541 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3542
3543 audio_transceiver->StopStandard();
3544 caller()->CreateAndSetAndSignalOffer();
3545 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3546 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3547 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3548 caller()->pc()->ice_gathering_state());
3549 EXPECT_THAT(caller()->ice_gathering_state_history(),
3550 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3551 PeerConnectionInterface::kIceGatheringComplete,
3552 PeerConnectionInterface::kIceGatheringNew));
3553}
3554
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003555TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00003556 StopTransceiverStopsAndRemovesTransceivers) {
3557 RTCConfiguration config;
3558 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3559 ConnectFakeSignaling();
3560 auto audio_transceiver_or_error =
3561 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3562 ASSERT_TRUE(audio_transceiver_or_error.ok());
3563 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3564
3565 caller()->CreateAndSetAndSignalOffer();
3566 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3567 caller_transceiver->StopStandard();
3568
3569 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3570 caller()->CreateAndSetAndSignalOffer();
3571 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3572 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3573 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3574 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3575 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3576 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3577 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3578 EXPECT_TRUE(caller_transceiver->stopped());
3579 EXPECT_TRUE(callee_transceiver->stopped());
3580}
3581
3582TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003583 StopTransceiverEndsIncomingAudioTrack) {
3584 RTCConfiguration config;
3585 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3586 ConnectFakeSignaling();
3587 auto audio_transceiver_or_error =
3588 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3589 ASSERT_TRUE(audio_transceiver_or_error.ok());
3590 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3591
3592 caller()->CreateAndSetAndSignalOffer();
3593 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3594 auto caller_track = audio_transceiver->receiver()->track();
3595 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3596 audio_transceiver->StopStandard();
3597 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3598 caller_track->state());
3599 caller()->CreateAndSetAndSignalOffer();
3600 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3601 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3602 callee_track->state());
3603}
3604
3605TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3606 StopTransceiverEndsIncomingVideoTrack) {
3607 RTCConfiguration config;
3608 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3609 ConnectFakeSignaling();
3610 auto audio_transceiver_or_error =
3611 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3612 ASSERT_TRUE(audio_transceiver_or_error.ok());
3613 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3614
3615 caller()->CreateAndSetAndSignalOffer();
3616 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3617 auto caller_track = audio_transceiver->receiver()->track();
3618 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3619 audio_transceiver->StopStandard();
3620 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3621 caller_track->state());
3622 caller()->CreateAndSetAndSignalOffer();
3623 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3624 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3625 callee_track->state());
3626}
3627
Jonas Oreland65455162022-06-08 11:25:46 +02003628TEST_P(PeerConnectionIntegrationTest, EndToEndRtpSenderVideoEncoderSelector) {
3629 ASSERT_TRUE(
3630 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
3631 ConnectFakeSignaling();
3632 // Add one-directional video, from caller to callee.
3633 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
3634 caller()->CreateLocalVideoTrack();
3635 auto sender = caller()->AddTrack(caller_track);
3636 PeerConnectionInterface::RTCOfferAnswerOptions options;
3637 options.offer_to_receive_video = 0;
3638 caller()->SetOfferAnswerOptions(options);
3639 caller()->CreateAndSetAndSignalOffer();
3640 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3641 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
3642
3643 std::unique_ptr<MockEncoderSelector> encoder_selector =
3644 std::make_unique<MockEncoderSelector>();
3645 EXPECT_CALL(*encoder_selector, OnCurrentEncoder);
3646
3647 sender->SetEncoderSelector(std::move(encoder_selector));
3648
3649 // Expect video to be received in one direction.
3650 MediaExpectations media_expectations;
3651 media_expectations.CallerExpectsNoVideo();
3652 media_expectations.CalleeExpectsSomeVideo();
3653
3654 EXPECT_TRUE(ExpectNewFrames(media_expectations));
3655}
3656
Harald Alvestrand89c40e22021-02-17 08:58:35 +00003657} // namespace
Harald Alvestrand39993842021-02-17 09:05:31 +00003658
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01003659} // namespace webrtc