blob: 8afd807ff782762e5ee08758d648c80860fcac7d [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"
52#include "api/transport/rtp/rtp_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080053#include "api/uma_metrics.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000054#include "api/units/time_delta.h"
55#include "api/video/video_rotation.h"
56#include "logging/rtc_event_log/fake_rtc_event_log.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070057#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000058#include "media/base/codec.h"
59#include "media/base/media_constants.h"
60#include "media/base/stream_params.h"
Steve Anton10542f22019-01-11 09:11:00 -080061#include "p2p/base/mock_async_resolver.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000062#include "p2p/base/port.h"
63#include "p2p/base/port_allocator.h"
Steve Anton10542f22019-01-11 09:11:00 -080064#include "p2p/base/port_interface.h"
65#include "p2p/base/test_stun_server.h"
66#include "p2p/base/test_turn_customizer.h"
67#include "p2p/base/test_turn_server.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000068#include "p2p/base/transport_description.h"
69#include "p2p/base/transport_info.h"
Steve Anton10542f22019-01-11 09:11:00 -080070#include "pc/media_session.h"
71#include "pc/peer_connection.h"
72#include "pc/peer_connection_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080073#include "pc/session_description.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000074#include "pc/test/fake_periodic_video_source.h"
75#include "pc/test/integration_test_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080076#include "pc/test/mock_peer_connection_observers.h"
Jonas Olssonb75d9e92019-02-22 10:33:29 +010077#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070078#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080079#include "rtc_base/fake_network.h"
80#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020081#include "rtc_base/gunit.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000082#include "rtc_base/helpers.h"
83#include "rtc_base/location.h"
84#include "rtc_base/logging.h"
85#include "rtc_base/ref_counted_object.h"
86#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
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001790#if !defined(THREAD_SANITIZER)
1791// This test provokes TSAN errors. See bugs.webrtc.org/3608
1792
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001793constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1794 cricket::PORTALLOCATOR_DISABLE_RELAY |
1795 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001796
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001797// Use a mock resolver to resolve the hostname back to the original IP on both
1798// sides and check that the ICE connection connects.
Markus Handell56910532021-04-10 11:23:14 +00001799// TODO(bugs.webrtc.org/12590): Flaky on Windows and on Linux MSAN.
Harald Alvestrand4f7486a2022-06-02 11:35:49 +00001800#if defined(WEBRTC_WIN)
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001801#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1802 DISABLED_IceStatesReachCompletionWithRemoteHostname
1803#else
1804#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1805 IceStatesReachCompletionWithRemoteHostname
1806#endif
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001807TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001808 MAYBE_IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001809 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001810 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001811 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001812 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001813 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1814 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001815
1816 // This also verifies that the injected AsyncResolverFactory is used by
1817 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001818 EXPECT_CALL(*caller_resolver_factory, Create())
1819 .WillOnce(Return(&caller_async_resolver));
1820 webrtc::PeerConnectionDependencies caller_deps(nullptr);
1821 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1822
1823 EXPECT_CALL(*callee_resolver_factory, Create())
1824 .WillOnce(Return(&callee_async_resolver));
1825 webrtc::PeerConnectionDependencies callee_deps(nullptr);
1826 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1827
1828 PeerConnectionInterface::RTCConfiguration config;
1829 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1830 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1831
1832 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1833 config, std::move(caller_deps), config, std::move(callee_deps)));
1834
1835 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1836 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1837
1838 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07001839 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001840 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07001841 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001842 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001843
1844 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001845
1846 ConnectFakeSignaling();
1847 caller()->AddAudioVideoTracks();
1848 callee()->AddAudioVideoTracks();
1849 caller()->CreateAndSetAndSignalOffer();
1850 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1851 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1852 caller()->ice_connection_state(), kDefaultTimeout);
1853 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1854 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08001855
Ying Wangef3998f2019-12-09 13:06:53 +01001856 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1857 "WebRTC.PeerConnection.CandidatePairType_UDP",
1858 webrtc::kIceCandidatePairHostNameHostName));
Harald Alvestrand4f7486a2022-06-02 11:35:49 +00001859 DestroyPeerConnections();
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001860}
1861
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001862#endif // !defined(THREAD_SANITIZER)
1863
Steve Antonede9ca52017-10-16 13:04:27 -07001864// Test that firewalling the ICE connection causes the clients to identify the
1865// disconnected state and then removing the firewall causes them to reconnect.
1866class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08001867 : public PeerConnectionIntegrationBaseTest,
1868 public ::testing::WithParamInterface<
1869 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07001870 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001871 PeerConnectionIntegrationIceStatesTest()
1872 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1873 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07001874 }
1875
1876 void StartStunServer(const SocketAddress& server_address) {
1877 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01001878 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07001879 }
1880
1881 bool TestIPv6() {
1882 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1883 }
1884
1885 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001886 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1887 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07001888 }
1889
1890 std::vector<SocketAddress> CallerAddresses() {
1891 std::vector<SocketAddress> addresses;
1892 addresses.push_back(SocketAddress("1.1.1.1", 0));
1893 if (TestIPv6()) {
1894 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1895 }
1896 return addresses;
1897 }
1898
1899 std::vector<SocketAddress> CalleeAddresses() {
1900 std::vector<SocketAddress> addresses;
1901 addresses.push_back(SocketAddress("2.2.2.2", 0));
1902 if (TestIPv6()) {
1903 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1904 }
1905 return addresses;
1906 }
1907
1908 void SetUpNetworkInterfaces() {
1909 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07001910 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1911 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07001912
1913 // Add network addresses for test.
1914 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001915 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001916 }
1917 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001918 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001919 }
1920 }
1921
1922 private:
1923 uint32_t port_allocator_flags_;
1924 std::unique_ptr<cricket::TestStunServer> stun_server_;
1925};
1926
Yves Gerey100fe632020-01-17 19:15:53 +01001927// Ensure FakeClockForTest is constructed first (see class for rationale).
1928class PeerConnectionIntegrationIceStatesTestWithFakeClock
1929 : public FakeClockForTest,
1930 public PeerConnectionIntegrationIceStatesTest {};
1931
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001932#if !defined(THREAD_SANITIZER)
1933// This test provokes TSAN errors. bugs.webrtc.org/11282
1934
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001935// Tests that if the connection doesn't get set up properly we eventually reach
1936// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01001937TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
1938 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01001939 // Block connections to/from the caller and wait for ICE to become
1940 // disconnected.
1941 for (const auto& caller_address : CallerAddresses()) {
1942 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
1943 }
1944
1945 ASSERT_TRUE(CreatePeerConnectionWrappers());
1946 ConnectFakeSignaling();
1947 SetPortAllocatorFlags();
1948 SetUpNetworkInterfaces();
1949 caller()->AddAudioVideoTracks();
1950 caller()->CreateAndSetAndSignalOffer();
1951
1952 // According to RFC7675, if there is no response within 30 seconds then the
1953 // peer should consider the other side to have rejected the connection. This
1954 // is signaled by the state transitioning to "failed".
1955 constexpr int kConsentTimeout = 30000;
1956 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
1957 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01001958 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07001959}
1960
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001961#endif // !defined(THREAD_SANITIZER)
1962
Steve Antonede9ca52017-10-16 13:04:27 -07001963// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
1964// and that the statistics in the metric observers are updated correctly.
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001965// TODO(bugs.webrtc.org/12591): Flaky on Windows.
1966#if defined(WEBRTC_WIN)
1967#define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
1968#else
1969#define MAYBE_VerifyBestConnection VerifyBestConnection
1970#endif
1971TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
Steve Antonede9ca52017-10-16 13:04:27 -07001972 ASSERT_TRUE(CreatePeerConnectionWrappers());
1973 ConnectFakeSignaling();
1974 SetPortAllocatorFlags();
1975 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08001976 caller()->AddAudioVideoTracks();
1977 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07001978 caller()->CreateAndSetAndSignalOffer();
1979
1980 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08001981 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1982 caller()->ice_connection_state(), kDefaultTimeout);
1983 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1984 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07001985
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001986 // TODO(bugs.webrtc.org/9456): Fix it.
1987 const int num_best_ipv4 = webrtc::metrics::NumEvents(
1988 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
1989 const int num_best_ipv6 = webrtc::metrics::NumEvents(
1990 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001991 if (TestIPv6()) {
1992 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
1993 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01001994 EXPECT_METRIC_EQ(0, num_best_ipv4);
1995 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001996 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01001997 EXPECT_METRIC_EQ(1, num_best_ipv4);
1998 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07001999 }
2000
Ying Wangef3998f2019-12-09 13:06:53 +01002001 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
2002 "WebRTC.PeerConnection.CandidatePairType_UDP",
2003 webrtc::kIceCandidatePairHostHost));
2004 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
2005 "WebRTC.PeerConnection.CandidatePairType_UDP",
2006 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07002007}
2008
2009constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
2010 cricket::PORTALLOCATOR_DISABLE_STUN |
2011 cricket::PORTALLOCATOR_DISABLE_RELAY;
2012constexpr uint32_t kFlagsIPv6NoStun =
2013 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
2014 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
2015constexpr uint32_t kFlagsIPv4Stun =
2016 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
2017
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002018INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002019 PeerConnectionIntegrationTest,
2020 PeerConnectionIntegrationIceStatesTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02002021 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Seth Hampson2f0d7022018-02-20 11:54:42 -08002022 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2023 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2024 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07002025
Yves Gerey100fe632020-01-17 19:15:53 +01002026INSTANTIATE_TEST_SUITE_P(
2027 PeerConnectionIntegrationTest,
2028 PeerConnectionIntegrationIceStatesTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02002029 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Yves Gerey100fe632020-01-17 19:15:53 +01002030 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2031 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2032 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2033
deadbeef1dcb1642017-03-29 21:08:16 -07002034// This test sets up a call between two parties with audio and video.
2035// During the call, the caller restarts ICE and the test verifies that
2036// new ICE candidates are generated and audio and video still can flow, and the
2037// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002038TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07002039 ASSERT_TRUE(CreatePeerConnectionWrappers());
2040 ConnectFakeSignaling();
2041 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08002042 caller()->AddAudioVideoTracks();
2043 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002044 caller()->CreateAndSetAndSignalOffer();
2045 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2046 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2047 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002048 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2049 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07002050
2051 // To verify that the ICE restart actually occurs, get
2052 // ufrag/password/candidates before and after restart.
2053 // Create an SDP string of the first audio candidate for both clients.
2054 const webrtc::IceCandidateCollection* audio_candidates_caller =
2055 caller()->pc()->local_description()->candidates(0);
2056 const webrtc::IceCandidateCollection* audio_candidates_callee =
2057 callee()->pc()->local_description()->candidates(0);
2058 ASSERT_GT(audio_candidates_caller->count(), 0u);
2059 ASSERT_GT(audio_candidates_callee->count(), 0u);
2060 std::string caller_candidate_pre_restart;
2061 ASSERT_TRUE(
2062 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2063 std::string callee_candidate_pre_restart;
2064 ASSERT_TRUE(
2065 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2066 const cricket::SessionDescription* desc =
2067 caller()->pc()->local_description()->description();
2068 std::string caller_ufrag_pre_restart =
2069 desc->transport_infos()[0].description.ice_ufrag;
2070 desc = callee()->pc()->local_description()->description();
2071 std::string callee_ufrag_pre_restart =
2072 desc->transport_infos()[0].description.ice_ufrag;
2073
Alex Drake00c7ecf2019-08-06 10:54:47 -07002074 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002075 // Have the caller initiate an ICE restart.
2076 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2077 caller()->CreateAndSetAndSignalOffer();
2078 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2079 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2080 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002081 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07002082 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2083
2084 // Grab the ufrags/candidates again.
2085 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2086 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2087 ASSERT_GT(audio_candidates_caller->count(), 0u);
2088 ASSERT_GT(audio_candidates_callee->count(), 0u);
2089 std::string caller_candidate_post_restart;
2090 ASSERT_TRUE(
2091 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2092 std::string callee_candidate_post_restart;
2093 ASSERT_TRUE(
2094 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2095 desc = caller()->pc()->local_description()->description();
2096 std::string caller_ufrag_post_restart =
2097 desc->transport_infos()[0].description.ice_ufrag;
2098 desc = callee()->pc()->local_description()->description();
2099 std::string callee_ufrag_post_restart =
2100 desc->transport_infos()[0].description.ice_ufrag;
2101 // Sanity check that an ICE restart was actually negotiated in SDP.
2102 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2103 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2104 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2105 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07002106 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002107
2108 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002109 MediaExpectations media_expectations;
2110 media_expectations.ExpectBidirectionalAudioAndVideo();
2111 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002112}
2113
2114// Verify that audio/video can be received end-to-end when ICE renomination is
2115// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002116TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07002117 PeerConnectionInterface::RTCConfiguration config;
2118 config.enable_ice_renomination = true;
2119 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2120 ConnectFakeSignaling();
2121 // Do normal offer/answer and wait for some frames to be received in each
2122 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002123 caller()->AddAudioVideoTracks();
2124 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002125 caller()->CreateAndSetAndSignalOffer();
2126 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2127 // Sanity check that ICE renomination was actually negotiated.
2128 const cricket::SessionDescription* desc =
2129 caller()->pc()->local_description()->description();
2130 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002131 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002132 }
2133 desc = callee()->pc()->local_description()->description();
2134 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002135 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002136 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08002137 MediaExpectations media_expectations;
2138 media_expectations.ExpectBidirectionalAudioAndVideo();
2139 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002140}
2141
Steve Anton6f25b092017-10-23 09:39:20 -07002142// With a max bundle policy and RTCP muxing, adding a new media description to
2143// the connection should not affect ICE at all because the new media will use
2144// the existing connection.
Rasmus Brandt685be142021-03-15 14:03:38 +01002145// TODO(bugs.webrtc.org/12538): Fails on tsan.
2146#if defined(THREAD_SANITIZER)
2147#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2148 DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2149#else
2150#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2151 AddMediaToConnectedBundleDoesNotRestartIce
2152#endif
Seth Hampson2f0d7022018-02-20 11:54:42 -08002153TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt685be142021-03-15 14:03:38 +01002154 MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07002155 PeerConnectionInterface::RTCConfiguration config;
2156 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2157 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2158 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2159 config, PeerConnectionInterface::RTCConfiguration()));
2160 ConnectFakeSignaling();
2161
Steve Anton15324772018-01-16 10:26:49 -08002162 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002163 caller()->CreateAndSetAndSignalOffer();
2164 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07002165 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2166 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07002167
2168 caller()->clear_ice_connection_state_history();
2169
Steve Anton15324772018-01-16 10:26:49 -08002170 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002171 caller()->CreateAndSetAndSignalOffer();
2172 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2173
2174 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2175}
2176
deadbeef1dcb1642017-03-29 21:08:16 -07002177// This test sets up a call between two parties with audio and video. It then
2178// renegotiates setting the video m-line to "port 0", then later renegotiates
2179// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002180TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002181 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2182 ASSERT_TRUE(CreatePeerConnectionWrappers());
2183 ConnectFakeSignaling();
2184
2185 // Do initial negotiation, only sending media from the caller. Will result in
2186 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08002187 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002188 caller()->CreateAndSetAndSignalOffer();
2189 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2190
2191 // Negotiate again, disabling the video "m=" section (the callee will set the
2192 // port to 0 due to offer_to_receive_video = 0).
Florent Castelli15a38de2022-04-06 00:38:21 +02002193 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002194 PeerConnectionInterface::RTCOfferAnswerOptions options;
2195 options.offer_to_receive_video = 0;
2196 callee()->SetOfferAnswerOptions(options);
2197 } else {
2198 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002199 callee()
2200 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2201 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002202 });
2203 }
deadbeef1dcb1642017-03-29 21:08:16 -07002204 caller()->CreateAndSetAndSignalOffer();
2205 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2206 // Sanity check that video "m=" section was actually rejected.
2207 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2208 callee()->pc()->local_description()->description());
2209 ASSERT_NE(nullptr, answer_video_content);
2210 ASSERT_TRUE(answer_video_content->rejected);
2211
2212 // Enable video and do negotiation again, making sure video is received
2213 // end-to-end, also adding media stream to callee.
Florent Castelli15a38de2022-04-06 00:38:21 +02002214 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002215 PeerConnectionInterface::RTCOfferAnswerOptions options;
2216 options.offer_to_receive_video = 1;
2217 callee()->SetOfferAnswerOptions(options);
2218 } else {
2219 // The caller's transceiver is stopped, so we need to add another track.
2220 auto caller_transceiver =
2221 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002222 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002223 caller()->AddVideoTrack();
2224 }
2225 callee()->AddVideoTrack();
2226 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07002227 caller()->CreateAndSetAndSignalOffer();
2228 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002229
deadbeef1dcb1642017-03-29 21:08:16 -07002230 // Verify the caller receives frames from the newly added stream, and the
2231 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002232 MediaExpectations media_expectations;
2233 media_expectations.CalleeExpectsSomeAudio();
2234 media_expectations.ExpectBidirectionalVideo();
2235 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002236}
2237
deadbeef1dcb1642017-03-29 21:08:16 -07002238// This tests that if we negotiate after calling CreateSender but before we
2239// have a track, then set a track later, frames from the newly-set track are
2240// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002241TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07002242 MediaFlowsAfterEarlyWarmupWithCreateSender) {
2243 ASSERT_TRUE(CreatePeerConnectionWrappers());
2244 ConnectFakeSignaling();
2245 auto caller_audio_sender =
2246 caller()->pc()->CreateSender("audio", "caller_stream");
2247 auto caller_video_sender =
2248 caller()->pc()->CreateSender("video", "caller_stream");
2249 auto callee_audio_sender =
2250 callee()->pc()->CreateSender("audio", "callee_stream");
2251 auto callee_video_sender =
2252 callee()->pc()->CreateSender("video", "callee_stream");
2253 caller()->CreateAndSetAndSignalOffer();
2254 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2255 // Wait for ICE to complete, without any tracks being set.
2256 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2257 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2258 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2259 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2260 // Now set the tracks, and expect frames to immediately start flowing.
Niels Möllerafb246b2022-04-20 14:26:50 +02002261 EXPECT_TRUE(
2262 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2263 EXPECT_TRUE(
2264 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2265 EXPECT_TRUE(
2266 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2267 EXPECT_TRUE(
2268 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002269 MediaExpectations media_expectations;
2270 media_expectations.ExpectBidirectionalAudioAndVideo();
2271 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2272}
2273
2274// This tests that if we negotiate after calling AddTransceiver but before we
2275// have a track, then set a track later, frames from the newly-set tracks are
2276// received end-to-end.
2277TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2278 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2279 ASSERT_TRUE(CreatePeerConnectionWrappers());
2280 ConnectFakeSignaling();
2281 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2282 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2283 auto caller_audio_sender = audio_result.MoveValue()->sender();
2284 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2285 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2286 auto caller_video_sender = video_result.MoveValue()->sender();
2287 callee()->SetRemoteOfferHandler([this] {
2288 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02002289 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002290 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002291 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002292 RtpTransceiverDirection::kSendRecv);
2293 });
2294 caller()->CreateAndSetAndSignalOffer();
2295 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2296 // Wait for ICE to complete, without any tracks being set.
2297 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2298 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2299 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2300 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2301 // Now set the tracks, and expect frames to immediately start flowing.
2302 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2303 auto callee_video_sender = callee()->pc()->GetSenders()[1];
Niels Möllerafb246b2022-04-20 14:26:50 +02002304 ASSERT_TRUE(
2305 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2306 ASSERT_TRUE(
2307 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2308 ASSERT_TRUE(
2309 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2310 ASSERT_TRUE(
2311 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002312 MediaExpectations media_expectations;
2313 media_expectations.ExpectBidirectionalAudioAndVideo();
2314 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002315}
2316
2317// This test verifies that a remote video track can be added via AddStream,
2318// and sent end-to-end. For this particular test, it's simply echoed back
2319// from the caller to the callee, rather than being forwarded to a third
2320// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002321TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07002322 ASSERT_TRUE(CreatePeerConnectionWrappers());
2323 ConnectFakeSignaling();
2324 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08002325 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002326 caller()->CreateAndSetAndSignalOffer();
2327 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002328 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07002329
2330 // Echo the stream back, and do a new offer/anwer (initiated by callee this
2331 // time).
2332 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2333 callee()->CreateAndSetAndSignalOffer();
2334 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2335
Seth Hampson2f0d7022018-02-20 11:54:42 -08002336 MediaExpectations media_expectations;
2337 media_expectations.ExpectBidirectionalVideo();
2338 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002339}
2340
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002341#if !defined(THREAD_SANITIZER)
2342// This test provokes TSAN errors. bugs.webrtc.org/11282
2343
deadbeef1dcb1642017-03-29 21:08:16 -07002344// Test that we achieve the expected end-to-end connection time, using a
2345// fake clock and simulated latency on the media and signaling paths.
2346// We use a TURN<->TURN connection because this is usually the quickest to
2347// set up initially, especially when we're confident the connection will work
2348// and can start sending media before we get a STUN response.
2349//
2350// With various optimizations enabled, here are the network delays we expect to
2351// be on the critical path:
2352// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2353// signaling answer (with DTLS fingerprint).
2354// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2355// using TURN<->TURN pair, and DTLS exchange is 4 packets,
2356// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01002357TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2358 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07002359 static constexpr int media_hop_delay_ms = 50;
2360 static constexpr int signaling_trip_delay_ms = 500;
2361 // For explanation of these values, see comment above.
2362 static constexpr int required_media_hops = 9;
2363 static constexpr int required_signaling_trips = 2;
2364 // For internal delays (such as posting an event asychronously).
2365 static constexpr int allowed_internal_delay_ms = 20;
2366 static constexpr int total_connection_time_ms =
2367 media_hop_delay_ms * required_media_hops +
2368 signaling_trip_delay_ms * required_signaling_trips +
2369 allowed_internal_delay_ms;
2370
2371 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2372 3478};
2373 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2374 0};
2375 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2376 3478};
2377 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2378 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002379 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2380 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002381
Seth Hampsonaed71642018-06-11 07:41:32 -07002382 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2383 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07002384 // Bypass permission check on received packets so media can be sent before
2385 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07002386 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
2387 turn_server_1->set_enable_permission_checks(false);
2388 });
2389 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
2390 turn_server_2->set_enable_permission_checks(false);
2391 });
deadbeef1dcb1642017-03-29 21:08:16 -07002392
2393 PeerConnectionInterface::RTCConfiguration client_1_config;
2394 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2395 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2396 ice_server_1.username = "test";
2397 ice_server_1.password = "test";
2398 client_1_config.servers.push_back(ice_server_1);
2399 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2400 client_1_config.presume_writable_when_fully_relayed = true;
2401
2402 PeerConnectionInterface::RTCConfiguration client_2_config;
2403 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2404 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2405 ice_server_2.username = "test";
2406 ice_server_2.password = "test";
2407 client_2_config.servers.push_back(ice_server_2);
2408 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2409 client_2_config.presume_writable_when_fully_relayed = true;
2410
2411 ASSERT_TRUE(
2412 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2413 // Set up the simulated delays.
2414 SetSignalingDelayMs(signaling_trip_delay_ms);
2415 ConnectFakeSignaling();
2416 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2417 virtual_socket_server()->UpdateDelayDistribution();
2418
2419 // Set "offer to receive audio/video" without adding any tracks, so we just
2420 // set up ICE/DTLS with no media.
2421 PeerConnectionInterface::RTCOfferAnswerOptions options;
2422 options.offer_to_receive_audio = 1;
2423 options.offer_to_receive_video = 1;
2424 caller()->SetOfferAnswerOptions(options);
2425 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07002426 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01002427 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002428 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2429 // If this is not done a DCHECK can be hit in ports.cc, because a large
2430 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07002431 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07002432}
2433
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002434#endif // !defined(THREAD_SANITIZER)
2435
Jonas Orelandbdcee282017-10-10 14:01:40 +02002436// Verify that a TurnCustomizer passed in through RTCConfiguration
2437// is actually used by the underlying TURN candidate pair.
2438// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002439TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02002440 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2441 3478};
2442 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2443 0};
2444 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2445 3478};
2446 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2447 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002448 CreateTurnServer(turn_server_1_internal_address,
2449 turn_server_1_external_address);
2450 CreateTurnServer(turn_server_2_internal_address,
2451 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002452
2453 PeerConnectionInterface::RTCConfiguration client_1_config;
2454 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2455 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2456 ice_server_1.username = "test";
2457 ice_server_1.password = "test";
2458 client_1_config.servers.push_back(ice_server_1);
2459 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002460 auto* customizer1 = CreateTurnCustomizer();
2461 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002462
2463 PeerConnectionInterface::RTCConfiguration client_2_config;
2464 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2465 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2466 ice_server_2.username = "test";
2467 ice_server_2.password = "test";
2468 client_2_config.servers.push_back(ice_server_2);
2469 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002470 auto* customizer2 = CreateTurnCustomizer();
2471 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002472
2473 ASSERT_TRUE(
2474 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2475 ConnectFakeSignaling();
2476
2477 // Set "offer to receive audio/video" without adding any tracks, so we just
2478 // set up ICE/DTLS with no media.
2479 PeerConnectionInterface::RTCOfferAnswerOptions options;
2480 options.offer_to_receive_audio = 1;
2481 options.offer_to_receive_video = 1;
2482 caller()->SetOfferAnswerOptions(options);
2483 caller()->CreateAndSetAndSignalOffer();
2484 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2485
Seth Hampsonaed71642018-06-11 07:41:32 -07002486 ExpectTurnCustomizerCountersIncremented(customizer1);
2487 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002488}
2489
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002490// Verifies that you can use TCP instead of UDP to connect to a TURN server and
2491// send media between the caller and the callee.
2492TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2493 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2494 3478};
2495 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2496
2497 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07002498 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2499 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002500
2501 webrtc::PeerConnectionInterface::IceServer ice_server;
2502 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2503 ice_server.username = "test";
2504 ice_server.password = "test";
2505
2506 PeerConnectionInterface::RTCConfiguration client_1_config;
2507 client_1_config.servers.push_back(ice_server);
2508 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2509
2510 PeerConnectionInterface::RTCConfiguration client_2_config;
2511 client_2_config.servers.push_back(ice_server);
2512 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2513
2514 ASSERT_TRUE(
2515 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2516
2517 // Do normal offer/answer and wait for ICE to complete.
2518 ConnectFakeSignaling();
2519 caller()->AddAudioVideoTracks();
2520 callee()->AddAudioVideoTracks();
2521 caller()->CreateAndSetAndSignalOffer();
2522 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2523 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2524 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2525
2526 MediaExpectations media_expectations;
2527 media_expectations.ExpectBidirectionalAudioAndVideo();
2528 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2529}
2530
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002531// Verify that a SSLCertificateVerifier passed in through
2532// PeerConnectionDependencies is actually used by the underlying SSL
2533// implementation to determine whether a certificate presented by the TURN
2534// server is accepted by the client. Note that openssladapter_unittest.cc
2535// contains more detailed, lower-level tests.
2536TEST_P(PeerConnectionIntegrationTest,
2537 SSLCertificateVerifierUsedForTurnConnections) {
2538 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2539 3478};
2540 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2541
2542 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2543 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002544 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2545 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002546
2547 webrtc::PeerConnectionInterface::IceServer ice_server;
2548 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2549 ice_server.username = "test";
2550 ice_server.password = "test";
2551
2552 PeerConnectionInterface::RTCConfiguration client_1_config;
2553 client_1_config.servers.push_back(ice_server);
2554 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2555
2556 PeerConnectionInterface::RTCConfiguration client_2_config;
2557 client_2_config.servers.push_back(ice_server);
2558 // Setting the type to kRelay forces the connection to go through a TURN
2559 // server.
2560 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2561
2562 // Get a copy to the pointer so we can verify calls later.
2563 rtc::TestCertificateVerifier* client_1_cert_verifier =
2564 new rtc::TestCertificateVerifier();
2565 client_1_cert_verifier->verify_certificate_ = true;
2566 rtc::TestCertificateVerifier* client_2_cert_verifier =
2567 new rtc::TestCertificateVerifier();
2568 client_2_cert_verifier->verify_certificate_ = true;
2569
2570 // Create the dependencies with the test certificate verifier.
2571 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2572 client_1_deps.tls_cert_verifier =
2573 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2574 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2575 client_2_deps.tls_cert_verifier =
2576 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2577
2578 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2579 client_1_config, std::move(client_1_deps), client_2_config,
2580 std::move(client_2_deps)));
2581 ConnectFakeSignaling();
2582
2583 // Set "offer to receive audio/video" without adding any tracks, so we just
2584 // set up ICE/DTLS with no media.
2585 PeerConnectionInterface::RTCOfferAnswerOptions options;
2586 options.offer_to_receive_audio = 1;
2587 options.offer_to_receive_video = 1;
2588 caller()->SetOfferAnswerOptions(options);
2589 caller()->CreateAndSetAndSignalOffer();
2590 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2591
2592 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2593 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002594}
2595
Qingsi Wang25ec8882019-11-15 12:33:05 -08002596// Test that the injected ICE transport factory is used to create ICE transports
2597// for WebRTC connections.
2598TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2599 PeerConnectionInterface::RTCConfiguration default_config;
2600 PeerConnectionDependencies dependencies(nullptr);
2601 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2602 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2603 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02002604 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2605 std::move(dependencies), nullptr,
2606 /*reset_encoder_factory=*/false,
2607 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08002608 ASSERT_TRUE(wrapper);
2609 wrapper->CreateDataChannel();
Tommi87f70902021-04-27 14:43:08 +02002610 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02002611 wrapper->pc()->SetLocalDescription(observer.get(),
Qingsi Wang25ec8882019-11-15 12:33:05 -08002612 wrapper->CreateOfferAndWait().release());
2613}
2614
deadbeefc964d0b2017-04-03 10:03:35 -07002615// Test that audio and video flow end-to-end when codec names don't use the
2616// expected casing, given that they're supposed to be case insensitive. To test
2617// this, all but one codec is removed from each media description, and its
2618// casing is changed.
2619//
2620// In the past, this has regressed and caused crashes/black video, due to the
2621// fact that code at some layers was doing case-insensitive comparisons and
2622// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002623TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07002624 ASSERT_TRUE(CreatePeerConnectionWrappers());
2625 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002626 caller()->AddAudioVideoTracks();
2627 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07002628
2629 // Remove all but one audio/video codec (opus and VP8), and change the
2630 // casing of the caller's generated offer.
2631 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2632 cricket::AudioContentDescription* audio =
2633 GetFirstAudioContentDescription(description);
2634 ASSERT_NE(nullptr, audio);
2635 auto audio_codecs = audio->codecs();
2636 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2637 [](const cricket::AudioCodec& codec) {
2638 return codec.name != "opus";
2639 }),
2640 audio_codecs.end());
2641 ASSERT_EQ(1u, audio_codecs.size());
2642 audio_codecs[0].name = "OpUs";
2643 audio->set_codecs(audio_codecs);
2644
2645 cricket::VideoContentDescription* video =
2646 GetFirstVideoContentDescription(description);
2647 ASSERT_NE(nullptr, video);
2648 auto video_codecs = video->codecs();
2649 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2650 [](const cricket::VideoCodec& codec) {
2651 return codec.name != "VP8";
2652 }),
2653 video_codecs.end());
2654 ASSERT_EQ(1u, video_codecs.size());
2655 video_codecs[0].name = "vP8";
2656 video->set_codecs(video_codecs);
2657 });
2658
2659 caller()->CreateAndSetAndSignalOffer();
2660 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2661
2662 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002663 MediaExpectations media_expectations;
2664 media_expectations.ExpectBidirectionalAudioAndVideo();
2665 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07002666}
2667
Jonas Oreland49ac5952018-09-26 16:04:32 +02002668TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07002669 ASSERT_TRUE(CreatePeerConnectionWrappers());
2670 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002671 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07002672 caller()->CreateAndSetAndSignalOffer();
2673 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07002674 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002675 MediaExpectations media_expectations;
2676 media_expectations.CalleeExpectsSomeAudio(1);
2677 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02002678 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07002679 auto receiver = callee()->pc()->GetReceivers()[0];
2680 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002681 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07002682 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2683 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02002684 sources[0].source_id());
2685 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2686}
2687
2688TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2689 ASSERT_TRUE(CreatePeerConnectionWrappers());
2690 ConnectFakeSignaling();
2691 caller()->AddVideoTrack();
2692 caller()->CreateAndSetAndSignalOffer();
2693 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2694 // Wait for one video frame to be received by the callee.
2695 MediaExpectations media_expectations;
2696 media_expectations.CalleeExpectsSomeVideo(1);
2697 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2698 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2699 auto receiver = callee()->pc()->GetReceivers()[0];
2700 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2701 auto sources = receiver->GetSources();
2702 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02002703 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002704 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2705 sources[0].source_id());
2706 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07002707}
2708
deadbeef2f425aa2017-04-14 10:41:32 -07002709// Test that if a track is removed and added again with a different stream ID,
2710// the new stream ID is successfully communicated in SDP and media continues to
2711// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002712// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2713// it will not reuse a transceiver that has already been sending. After creating
2714// a new transceiver it tries to create an offer with two senders of the same
2715// track ids and it fails.
2716TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07002717 ASSERT_TRUE(CreatePeerConnectionWrappers());
2718 ConnectFakeSignaling();
2719
deadbeef2f425aa2017-04-14 10:41:32 -07002720 // Add track using stream 1, do offer/answer.
2721 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2722 caller()->CreateLocalAudioTrack();
2723 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07002724 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07002725 caller()->CreateAndSetAndSignalOffer();
2726 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002727 {
2728 MediaExpectations media_expectations;
2729 media_expectations.CalleeExpectsSomeAudio(1);
2730 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2731 }
deadbeef2f425aa2017-04-14 10:41:32 -07002732 // Remove the sender, and create a new one with the new stream.
Harald Alvestrand93dd7632022-01-19 12:28:45 +00002733 caller()->pc()->RemoveTrackOrError(sender);
Steve Antond78323f2018-07-11 11:13:44 -07002734 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07002735 caller()->CreateAndSetAndSignalOffer();
2736 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2737 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002738 {
2739 MediaExpectations media_expectations;
2740 media_expectations.CalleeExpectsSomeAudio();
2741 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2742 }
deadbeef2f425aa2017-04-14 10:41:32 -07002743}
2744
Seth Hampson2f0d7022018-02-20 11:54:42 -08002745TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02002746 ASSERT_TRUE(CreatePeerConnectionWrappers());
2747 ConnectFakeSignaling();
2748
Mirko Bonadei317a1f02019-09-17 17:06:18 +02002749 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002750 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
2751 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02002752 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01002753 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2754 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02002755
Steve Anton15324772018-01-16 10:26:49 -08002756 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02002757 caller()->CreateAndSetAndSignalOffer();
2758 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2759}
2760
Steve Antonede9ca52017-10-16 13:04:27 -07002761// Test that if candidates are only signaled by applying full session
2762// descriptions (instead of using AddIceCandidate), the peers can connect to
2763// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002764TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07002765 ASSERT_TRUE(CreatePeerConnectionWrappers());
2766 // Each side will signal the session descriptions but not candidates.
2767 ConnectFakeSignalingForSdpOnly();
2768
2769 // Add audio video track and exchange the initial offer/answer with media
2770 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08002771 caller()->AddAudioVideoTracks();
2772 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002773 caller()->CreateAndSetAndSignalOffer();
2774
2775 // Wait for all candidates to be gathered on both the caller and callee.
2776 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2777 caller()->ice_gathering_state(), kDefaultTimeout);
2778 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
2779 callee()->ice_gathering_state(), kDefaultTimeout);
2780
2781 // The candidates will now be included in the session description, so
2782 // signaling them will start the ICE connection.
2783 caller()->CreateAndSetAndSignalOffer();
2784 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2785
2786 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002787 MediaExpectations media_expectations;
2788 media_expectations.ExpectBidirectionalAudioAndVideo();
2789 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07002790}
2791
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002792#if !defined(THREAD_SANITIZER)
2793// These tests provokes TSAN errors. See bugs.webrtc.org/11305.
2794
henrika5f6bf242017-11-01 11:06:56 +01002795// Test that SetAudioPlayout can be used to disable audio playout from the
2796// start, then later enable it. This may be useful, for example, if the caller
2797// needs to play a local ringtone until some event occurs, after which it
2798// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002799TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01002800 ASSERT_TRUE(CreatePeerConnectionWrappers());
2801 ConnectFakeSignaling();
2802
2803 // Set up audio-only call where audio playout is disabled on caller's side.
2804 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08002805 caller()->AddAudioTrack();
2806 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002807 caller()->CreateAndSetAndSignalOffer();
2808 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2809
2810 // Pump messages for a second.
2811 WAIT(false, 1000);
2812 // Since audio playout is disabled, the caller shouldn't have received
2813 // anything (at the playout level, at least).
2814 EXPECT_EQ(0, caller()->audio_frames_received());
2815 // As a sanity check, make sure the callee (for which playout isn't disabled)
2816 // did still see frames on its audio level.
2817 ASSERT_GT(callee()->audio_frames_received(), 0);
2818
2819 // Enable playout again, and ensure audio starts flowing.
2820 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002821 MediaExpectations media_expectations;
2822 media_expectations.ExpectBidirectionalAudio();
2823 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01002824}
2825
Harald Alvestrand39993842021-02-17 09:05:31 +00002826double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
henrika5f6bf242017-11-01 11:06:56 +01002827 auto report = pc->NewGetStats();
2828 auto track_stats_list =
2829 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
2830 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
2831 for (const auto* track_stats : track_stats_list) {
2832 if (track_stats->remote_source.is_defined() &&
2833 *track_stats->remote_source) {
2834 remote_track_stats = track_stats;
2835 break;
2836 }
2837 }
2838
2839 if (!remote_track_stats->total_audio_energy.is_defined()) {
2840 return 0.0;
2841 }
2842 return *remote_track_stats->total_audio_energy;
2843}
2844
2845// Test that if audio playout is disabled via the SetAudioPlayout() method, then
2846// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002847TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01002848 DisableAudioPlayoutStillGeneratesAudioStats) {
2849 ASSERT_TRUE(CreatePeerConnectionWrappers());
2850 ConnectFakeSignaling();
2851
2852 // Set up audio-only call where playout is disabled but audio-processing is
2853 // still active.
Steve Anton15324772018-01-16 10:26:49 -08002854 caller()->AddAudioTrack();
2855 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01002856 caller()->pc()->SetAudioPlayout(false);
2857
2858 caller()->CreateAndSetAndSignalOffer();
2859 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2860
2861 // Wait for the callee to receive audio stats.
2862 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
2863}
2864
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002865#endif // !defined(THREAD_SANITIZER)
2866
henrika4f167df2017-11-01 14:45:55 +01002867// Test that SetAudioRecording can be used to disable audio recording from the
2868// start, then later enable it. This may be useful, for example, if the caller
2869// wants to ensure that no audio resources are active before a certain state
2870// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002871TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01002872 ASSERT_TRUE(CreatePeerConnectionWrappers());
2873 ConnectFakeSignaling();
2874
2875 // Set up audio-only call where audio recording is disabled on caller's side.
2876 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08002877 caller()->AddAudioTrack();
2878 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01002879 caller()->CreateAndSetAndSignalOffer();
2880 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2881
2882 // Pump messages for a second.
2883 WAIT(false, 1000);
2884 // Since caller has disabled audio recording, the callee shouldn't have
2885 // received anything.
2886 EXPECT_EQ(0, callee()->audio_frames_received());
2887 // As a sanity check, make sure the caller did still see frames on its
2888 // audio level since audio recording is enabled on the calle side.
2889 ASSERT_GT(caller()->audio_frames_received(), 0);
2890
2891 // Enable audio recording again, and ensure audio starts flowing.
2892 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002893 MediaExpectations media_expectations;
2894 media_expectations.ExpectBidirectionalAudio();
2895 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01002896}
2897
Qingsi Wang7685e862018-06-11 20:15:46 -07002898TEST_P(PeerConnectionIntegrationTest,
2899 IceEventsGeneratedAndLoggedInRtcEventLog) {
2900 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
2901 ConnectFakeSignaling();
2902 PeerConnectionInterface::RTCOfferAnswerOptions options;
2903 options.offer_to_receive_audio = 1;
2904 caller()->SetOfferAnswerOptions(options);
2905 caller()->CreateAndSetAndSignalOffer();
2906 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2907 ASSERT_NE(nullptr, caller()->event_log_factory());
2908 ASSERT_NE(nullptr, callee()->event_log_factory());
2909 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002910 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002911 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01002912 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07002913 ASSERT_NE(nullptr, caller_event_log);
2914 ASSERT_NE(nullptr, callee_event_log);
2915 int caller_ice_config_count = caller_event_log->GetEventCount(
2916 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2917 int caller_ice_event_count = caller_event_log->GetEventCount(
2918 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2919 int callee_ice_config_count = callee_event_log->GetEventCount(
2920 webrtc::RtcEvent::Type::IceCandidatePairConfig);
2921 int callee_ice_event_count = callee_event_log->GetEventCount(
2922 webrtc::RtcEvent::Type::IceCandidatePairEvent);
2923 EXPECT_LT(0, caller_ice_config_count);
2924 EXPECT_LT(0, caller_ice_event_count);
2925 EXPECT_LT(0, callee_ice_config_count);
2926 EXPECT_LT(0, callee_ice_event_count);
2927}
2928
Qingsi Wangc129c352019-04-18 10:41:58 -07002929TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07002930 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2931 3478};
2932 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2933
2934 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
2935
2936 webrtc::PeerConnectionInterface::IceServer ice_server;
2937 ice_server.urls.push_back("turn:88.88.88.0:3478");
2938 ice_server.username = "test";
2939 ice_server.password = "test";
2940
2941 PeerConnectionInterface::RTCConfiguration caller_config;
2942 caller_config.servers.push_back(ice_server);
2943 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
2944 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07002945 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07002946
2947 PeerConnectionInterface::RTCConfiguration callee_config;
2948 callee_config.servers.push_back(ice_server);
2949 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
2950 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07002951 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07002952
2953 ASSERT_TRUE(
2954 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
2955
2956 // Do normal offer/answer and wait for ICE to complete.
2957 ConnectFakeSignaling();
2958 caller()->AddAudioVideoTracks();
2959 callee()->AddAudioVideoTracks();
2960 caller()->CreateAndSetAndSignalOffer();
2961 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2962 // Since we are doing continual gathering, the ICE transport does not reach
2963 // kIceGatheringComplete (see
2964 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
2965 // kIceConnectionComplete.
2966 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2967 caller()->ice_connection_state(), kDefaultTimeout);
2968 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2969 callee()->ice_connection_state(), kDefaultTimeout);
2970 // Note that we cannot use the metric
Artem Titovcfea2182021-08-10 01:22:31 +02002971 // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
Qingsi Wangc129c352019-04-18 10:41:58 -07002972 // metric is only populated when we reach kIceConnectionComplete in the
2973 // current implementation.
2974 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
2975 caller()->last_candidate_gathered().type());
2976 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
2977 callee()->last_candidate_gathered().type());
2978
2979 // Loosen the caller's candidate filter.
2980 caller_config = caller()->pc()->GetConfiguration();
2981 caller_config.type = webrtc::PeerConnectionInterface::kAll;
2982 caller()->pc()->SetConfiguration(caller_config);
2983 // We should have gathered a new host candidate.
2984 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
2985 caller()->last_candidate_gathered().type(), kDefaultTimeout);
2986
2987 // Loosen the callee's candidate filter.
2988 callee_config = callee()->pc()->GetConfiguration();
2989 callee_config.type = webrtc::PeerConnectionInterface::kAll;
2990 callee()->pc()->SetConfiguration(callee_config);
2991 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
2992 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02002993
2994 // Create an offer and verify that it does not contain an ICE restart (i.e new
2995 // ice credentials).
2996 std::string caller_ufrag_pre_offer = caller()
2997 ->pc()
2998 ->local_description()
2999 ->description()
3000 ->transport_infos()[0]
3001 .description.ice_ufrag;
3002 caller()->CreateAndSetAndSignalOffer();
3003 std::string caller_ufrag_post_offer = caller()
3004 ->pc()
3005 ->local_description()
3006 ->description()
3007 ->transport_infos()[0]
3008 .description.ice_ufrag;
3009 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07003010}
3011
Eldar Relloda13ea22019-06-01 12:23:43 +03003012TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03003013 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3014 3478};
3015 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3016
3017 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3018
3019 webrtc::PeerConnectionInterface::IceServer ice_server;
3020 ice_server.urls.push_back("turn:88.88.88.0:3478");
3021 ice_server.username = "test";
3022 ice_server.password = "123";
3023
3024 PeerConnectionInterface::RTCConfiguration caller_config;
3025 caller_config.servers.push_back(ice_server);
3026 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3027 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3028
3029 PeerConnectionInterface::RTCConfiguration callee_config;
3030 callee_config.servers.push_back(ice_server);
3031 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3032 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3033
3034 ASSERT_TRUE(
3035 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3036
3037 // Do normal offer/answer and wait for ICE to complete.
3038 ConnectFakeSignaling();
3039 caller()->AddAudioVideoTracks();
3040 callee()->AddAudioVideoTracks();
3041 caller()->CreateAndSetAndSignalOffer();
3042 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3043 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3044 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3045 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02003046 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03003047}
3048
Eldar Rellofa8019c2020-05-14 11:59:33 +03003049TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3050 webrtc::PeerConnectionInterface::IceServer ice_server;
3051 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3052 ice_server.username = "test";
3053 ice_server.password = "test";
3054
3055 PeerConnectionInterface::RTCConfiguration caller_config;
3056 caller_config.servers.push_back(ice_server);
3057 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3058 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3059
3060 PeerConnectionInterface::RTCConfiguration callee_config;
3061 callee_config.servers.push_back(ice_server);
3062 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3063 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3064
3065 ASSERT_TRUE(
3066 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3067
3068 // Do normal offer/answer and wait for ICE to complete.
3069 ConnectFakeSignaling();
3070 caller()->AddAudioVideoTracks();
3071 callee()->AddAudioVideoTracks();
3072 caller()->CreateAndSetAndSignalOffer();
3073 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3074 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3075 EXPECT_EQ(caller()->error_event().address, "");
3076}
3077
Eldar Rello5ab79e62019-10-09 18:29:44 +03003078TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3079 AudioKeepsFlowingAfterImplicitRollback) {
3080 PeerConnectionInterface::RTCConfiguration config;
3081 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3082 config.enable_implicit_rollback = true;
3083 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3084 ConnectFakeSignaling();
3085 caller()->AddAudioTrack();
3086 callee()->AddAudioTrack();
3087 caller()->CreateAndSetAndSignalOffer();
3088 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3089 MediaExpectations media_expectations;
3090 media_expectations.ExpectBidirectionalAudio();
3091 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3092 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
3093 caller()->AddVideoTrack();
3094 callee()->AddVideoTrack();
Tommi87f70902021-04-27 14:43:08 +02003095 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003096 callee()->pc()->SetLocalDescription(observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003097 callee()->CreateOfferAndWait().release());
3098 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3099 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
3100 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3101 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3102}
3103
3104TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3105 ImplicitRollbackVisitsStableState) {
3106 RTCConfiguration config;
3107 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3108 config.enable_implicit_rollback = true;
3109
3110 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3111
Tommi87f70902021-04-27 14:43:08 +02003112 auto sld_observer =
3113 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003114 callee()->pc()->SetLocalDescription(sld_observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003115 callee()->CreateOfferAndWait().release());
3116 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3117 EXPECT_EQ(sld_observer->error(), "");
3118
Tommi87f70902021-04-27 14:43:08 +02003119 auto srd_observer =
3120 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003121 callee()->pc()->SetRemoteDescription(
Niels Möllerafb246b2022-04-20 14:26:50 +02003122 srd_observer.get(), caller()->CreateOfferAndWait().release());
Eldar Rello5ab79e62019-10-09 18:29:44 +03003123 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3124 EXPECT_EQ(srd_observer->error(), "");
3125
3126 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3127 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3128 PeerConnectionInterface::kStable,
3129 PeerConnectionInterface::kHaveRemoteOffer));
3130}
3131
Eldar Rellobd9c33a2020-10-01 17:52:45 +03003132TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3133 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3134 ASSERT_TRUE(CreatePeerConnectionWrappers());
3135 ConnectFakeSignaling();
3136 caller()->AddVideoTrack();
3137 callee()->AddVideoTrack();
3138 auto munger = [](cricket::SessionDescription* desc) {
3139 cricket::VideoContentDescription* video =
3140 GetFirstVideoContentDescription(desc);
3141 auto codecs = video->codecs();
3142 for (auto&& codec : codecs) {
3143 if (codec.name == "H264") {
3144 std::string value;
3145 // The parameter is not supposed to be present in SDP by default.
3146 EXPECT_FALSE(
3147 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3148 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3149 std::string(""));
3150 }
3151 }
3152 video->set_codecs(codecs);
3153 };
3154 // Munge local offer for SLD.
3155 caller()->SetGeneratedSdpMunger(munger);
3156 // Munge remote answer for SRD.
3157 caller()->SetReceivedSdpMunger(munger);
3158 caller()->CreateAndSetAndSignalOffer();
3159 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3160 // Observe that after munging the parameter is present in generated SDP.
3161 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3162 cricket::VideoContentDescription* video =
3163 GetFirstVideoContentDescription(desc);
3164 for (auto&& codec : video->codecs()) {
3165 if (codec.name == "H264") {
3166 std::string value;
3167 EXPECT_TRUE(
3168 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3169 }
3170 }
3171 });
3172 caller()->CreateOfferAndWait();
3173}
3174
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003175TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00003176 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003177 PeerConnectionInterface::RTCConfiguration config;
3178 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3179 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3180 ConnectFakeSignaling();
3181 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3182
3183 caller()->CreateAndSetAndSignalOffer();
3184 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3185 int current_size = caller()->pc()->GetTransceivers().size();
3186 // Add more tracks until we get close to having issues.
3187 // Issues have been seen at:
3188 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003189 // - 16 tracks on android_arm_dbg (flaky)
3190 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003191 // Double the number of tracks
3192 for (int i = 0; i < current_size; i++) {
3193 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3194 }
3195 current_size = caller()->pc()->GetTransceivers().size();
3196 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3197 auto start_time_ms = rtc::TimeMillis();
3198 caller()->CreateAndSetAndSignalOffer();
3199 // We want to stop when the time exceeds one second.
3200 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3201 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3202 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3203 ASSERT_GT(1000, elapsed_time_ms)
3204 << "Audio transceivers: Negotiation took too long after "
3205 << current_size << " tracks added";
3206 }
3207}
3208
3209TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3210 RenegotiateManyVideoTransceivers) {
3211 PeerConnectionInterface::RTCConfiguration config;
3212 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3213 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3214 ConnectFakeSignaling();
3215 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3216
3217 caller()->CreateAndSetAndSignalOffer();
3218 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3219 int current_size = caller()->pc()->GetTransceivers().size();
3220 // Add more tracks until we get close to having issues.
3221 // Issues have been seen at:
3222 // - 96 on a Linux workstation
3223 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3224 // - 32 on android_arm64_rel and linux_dbg bots
Harald Alvestrand785e23b2021-03-15 21:26:27 +00003225 // - 16 on Android 64 (Nexus 5x)
3226 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003227 // Double the number of tracks
3228 for (int i = 0; i < current_size; i++) {
3229 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3230 }
3231 current_size = caller()->pc()->GetTransceivers().size();
3232 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3233 auto start_time_ms = rtc::TimeMillis();
3234 caller()->CreateAndSetAndSignalOffer();
3235 // We want to stop when the time exceeds one second.
3236 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3237 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3238 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3239 ASSERT_GT(1000, elapsed_time_ms)
3240 << "Video transceivers: Negotiation took too long after "
3241 << current_size << " tracks added";
3242 }
3243}
3244
Harald Alvestrand94324f22021-01-13 12:31:53 +00003245TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3246 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3247 PeerConnectionInterface::RTCConfiguration config;
3248 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3249 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3250 ConnectFakeSignaling();
3251 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003252 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003253 caller()->CreateAndSetAndSignalOffer();
3254 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3255 // Wait until we can see the audio flowing.
3256 MediaExpectations media_expectations;
3257 media_expectations.CalleeExpectsSomeAudio();
3258 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3259
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003260 // Get the baseline numbers for audio_packets and audio_delay
3261 // in both directions.
3262 caller()->StartWatchingDelayStats();
3263 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003264
3265 int current_size = caller()->pc()->GetTransceivers().size();
3266 // Add more tracks until we get close to having issues.
3267 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003268 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00003269 // Double the number of tracks
3270 for (int i = 0; i < current_size; i++) {
3271 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3272 }
3273 current_size = caller()->pc()->GetTransceivers().size();
3274 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3275 auto start_time_ms = rtc::TimeMillis();
3276 caller()->CreateAndSetAndSignalOffer();
3277 // We want to stop when the time exceeds one second.
3278 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3279 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3280 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3281 // This is a guard against the test using excessive amounts of time.
3282 ASSERT_GT(5000, elapsed_time_ms)
3283 << "Video transceivers: Negotiation took too long after "
3284 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003285 caller()->UpdateDelayStats("caller reception", current_size);
3286 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00003287 }
3288}
3289
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003290INSTANTIATE_TEST_SUITE_P(
3291 PeerConnectionIntegrationTest,
3292 PeerConnectionIntegrationTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003293 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003294 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3295 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3296 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Steve Antond3679212018-01-17 17:41:02 -08003297
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003298INSTANTIATE_TEST_SUITE_P(
3299 PeerConnectionIntegrationTest,
3300 PeerConnectionIntegrationTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02003301 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003302 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3303 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3304 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Yves Gerey100fe632020-01-17 19:15:53 +01003305
Steve Anton74255ff2018-01-24 18:32:57 -08003306// Tests that verify interoperability between Plan B and Unified Plan
3307// PeerConnections.
3308class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003309 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08003310 public ::testing::WithParamInterface<
3311 std::tuple<SdpSemantics, SdpSemantics>> {
3312 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003313 // Setting the SdpSemantics for the base test to kDefault does not matter
3314 // because we specify not to use the test semantics when creating
Harald Alvestrand39993842021-02-17 09:05:31 +00003315 // PeerConnectionIntegrationWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08003316 PeerConnectionIntegrationInteropTest()
Florent Castelli15a38de2022-04-06 00:38:21 +02003317 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED),
Seth Hampson2f0d7022018-02-20 11:54:42 -08003318 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08003319 callee_semantics_(std::get<1>(GetParam())) {}
3320
3321 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07003322 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3323 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08003324 }
3325
3326 const SdpSemantics caller_semantics_;
3327 const SdpSemantics callee_semantics_;
3328};
3329
3330TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3331 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3332 ConnectFakeSignaling();
3333
3334 caller()->CreateAndSetAndSignalOffer();
3335 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3336}
3337
3338TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3339 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3340 ConnectFakeSignaling();
3341 auto audio_sender = caller()->AddAudioTrack();
3342
3343 caller()->CreateAndSetAndSignalOffer();
3344 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3345
3346 // Verify that one audio receiver has been created on the remote and that it
3347 // has the same track ID as the sending track.
3348 auto receivers = callee()->pc()->GetReceivers();
3349 ASSERT_EQ(1u, receivers.size());
3350 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3351 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3352
Seth Hampson2f0d7022018-02-20 11:54:42 -08003353 MediaExpectations media_expectations;
3354 media_expectations.CalleeExpectsSomeAudio();
3355 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003356}
3357
3358TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3359 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3360 ConnectFakeSignaling();
3361 auto video_sender = caller()->AddVideoTrack();
3362 auto audio_sender = caller()->AddAudioTrack();
3363
3364 caller()->CreateAndSetAndSignalOffer();
3365 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3366
3367 // Verify that one audio and one video receiver have been created on the
3368 // remote and that they have the same track IDs as the sending tracks.
3369 auto audio_receivers =
3370 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3371 ASSERT_EQ(1u, audio_receivers.size());
3372 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3373 auto video_receivers =
3374 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3375 ASSERT_EQ(1u, video_receivers.size());
3376 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3377
Seth Hampson2f0d7022018-02-20 11:54:42 -08003378 MediaExpectations media_expectations;
3379 media_expectations.CalleeExpectsSomeAudioAndVideo();
3380 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003381}
3382
3383TEST_P(PeerConnectionIntegrationInteropTest,
3384 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3385 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3386 ConnectFakeSignaling();
3387 caller()->AddAudioVideoTracks();
3388 callee()->AddAudioVideoTracks();
3389
3390 caller()->CreateAndSetAndSignalOffer();
3391 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3392
Seth Hampson2f0d7022018-02-20 11:54:42 -08003393 MediaExpectations media_expectations;
3394 media_expectations.ExpectBidirectionalAudioAndVideo();
3395 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003396}
3397
3398TEST_P(PeerConnectionIntegrationInteropTest,
3399 ReverseRolesOneAudioLocalToOneVideoRemote) {
3400 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3401 ConnectFakeSignaling();
3402 caller()->AddAudioTrack();
3403 callee()->AddVideoTrack();
3404
3405 caller()->CreateAndSetAndSignalOffer();
3406 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3407
3408 // Verify that only the audio track has been negotiated.
3409 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3410 // Might also check that the callee's NegotiationNeeded flag is set.
3411
3412 // Reverse roles.
3413 callee()->CreateAndSetAndSignalOffer();
3414 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3415
Seth Hampson2f0d7022018-02-20 11:54:42 -08003416 MediaExpectations media_expectations;
3417 media_expectations.CallerExpectsSomeVideo();
3418 media_expectations.CalleeExpectsSomeAudio();
3419 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003420}
3421
Taylor Brandstetter1c7ecef2021-08-11 12:38:35 -07003422TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3423 ASSERT_TRUE(CreatePeerConnectionWrappers());
3424 ConnectFakeSignaling();
3425 caller()->AddAudioVideoTracks();
3426 caller()->CreateAndSetAndSignalOffer();
3427 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3428 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3429 caller()->ExpectCandidates(0);
3430 callee()->ExpectCandidates(0);
3431 caller()->AddAudioTrack();
3432 caller()->CreateAndSetAndSignalOffer();
3433 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3434}
3435
Harald Alvestrand35ba0c52022-05-05 07:37:41 +00003436TEST_P(PeerConnectionIntegrationTest, MediaCallWithoutMediaEngineFails) {
3437 ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
3438 // AddTrack should fail.
3439 EXPECT_FALSE(
3440 caller()->pc()->AddTrack(caller()->CreateLocalAudioTrack(), {}).ok());
3441}
3442
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003443INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07003444 PeerConnectionIntegrationTest,
3445 PeerConnectionIntegrationInteropTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003446 Values(std::make_tuple(SdpSemantics::kPlanB_DEPRECATED,
3447 SdpSemantics::kUnifiedPlan),
3448 std::make_tuple(SdpSemantics::kUnifiedPlan,
3449 SdpSemantics::kPlanB_DEPRECATED)));
Steve Antonba42e992018-04-09 14:10:01 -07003450
3451// Test that if the Unified Plan side offers two video tracks then the Plan B
3452// side will only see the first one and ignore the second.
3453TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07003454 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
Florent Castelli15a38de2022-04-06 00:38:21 +02003455 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB_DEPRECATED));
Steve Anton74255ff2018-01-24 18:32:57 -08003456 ConnectFakeSignaling();
3457 auto first_sender = caller()->AddVideoTrack();
3458 caller()->AddVideoTrack();
3459
3460 caller()->CreateAndSetAndSignalOffer();
3461 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3462
3463 // Verify that there is only one receiver and it corresponds to the first
3464 // added track.
3465 auto receivers = callee()->pc()->GetReceivers();
3466 ASSERT_EQ(1u, receivers.size());
3467 EXPECT_TRUE(receivers[0]->track()->enabled());
3468 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3469
Seth Hampson2f0d7022018-02-20 11:54:42 -08003470 MediaExpectations media_expectations;
3471 media_expectations.CalleeExpectsSomeVideo();
3472 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003473}
3474
Steve Anton2bed3972019-01-04 17:04:30 -08003475// Test that if the initial offer tagged BUNDLE section is rejected due to its
3476// associated RtpTransceiver being stopped and another transceiver is added,
3477// then renegotiation causes the callee to receive the new video track without
3478// error.
3479// This is a regression test for bugs.webrtc.org/9954
3480TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3481 ReOfferWithStoppedBundleTaggedTransceiver) {
3482 RTCConfiguration config;
3483 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3484 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3485 ConnectFakeSignaling();
3486 auto audio_transceiver_or_error =
3487 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3488 ASSERT_TRUE(audio_transceiver_or_error.ok());
3489 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3490
3491 caller()->CreateAndSetAndSignalOffer();
3492 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3493 {
3494 MediaExpectations media_expectations;
3495 media_expectations.CalleeExpectsSomeAudio();
3496 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3497 }
3498
Harald Alvestrand6060df52020-08-11 09:54:02 +02003499 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08003500 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3501
3502 caller()->CreateAndSetAndSignalOffer();
3503 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3504 {
3505 MediaExpectations media_expectations;
3506 media_expectations.CalleeExpectsSomeVideo();
3507 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3508 }
3509}
3510
Harald Alvestrandbedb6052020-08-20 14:50:10 +02003511TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3512 StopTransceiverRemovesDtlsTransports) {
3513 RTCConfiguration config;
3514 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3515 ConnectFakeSignaling();
3516 auto audio_transceiver_or_error =
3517 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3518 ASSERT_TRUE(audio_transceiver_or_error.ok());
3519 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3520
3521 caller()->CreateAndSetAndSignalOffer();
3522 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3523
3524 audio_transceiver->StopStandard();
3525 caller()->CreateAndSetAndSignalOffer();
3526 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3527 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3528 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3529 caller()->pc()->ice_gathering_state());
3530 EXPECT_THAT(caller()->ice_gathering_state_history(),
3531 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3532 PeerConnectionInterface::kIceGatheringComplete,
3533 PeerConnectionInterface::kIceGatheringNew));
3534}
3535
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003536TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00003537 StopTransceiverStopsAndRemovesTransceivers) {
3538 RTCConfiguration config;
3539 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3540 ConnectFakeSignaling();
3541 auto audio_transceiver_or_error =
3542 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3543 ASSERT_TRUE(audio_transceiver_or_error.ok());
3544 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3545
3546 caller()->CreateAndSetAndSignalOffer();
3547 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3548 caller_transceiver->StopStandard();
3549
3550 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3551 caller()->CreateAndSetAndSignalOffer();
3552 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3553 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3554 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3555 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3556 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3557 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3558 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3559 EXPECT_TRUE(caller_transceiver->stopped());
3560 EXPECT_TRUE(callee_transceiver->stopped());
3561}
3562
3563TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003564 StopTransceiverEndsIncomingAudioTrack) {
3565 RTCConfiguration config;
3566 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3567 ConnectFakeSignaling();
3568 auto audio_transceiver_or_error =
3569 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3570 ASSERT_TRUE(audio_transceiver_or_error.ok());
3571 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3572
3573 caller()->CreateAndSetAndSignalOffer();
3574 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3575 auto caller_track = audio_transceiver->receiver()->track();
3576 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3577 audio_transceiver->StopStandard();
3578 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3579 caller_track->state());
3580 caller()->CreateAndSetAndSignalOffer();
3581 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3582 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3583 callee_track->state());
3584}
3585
3586TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3587 StopTransceiverEndsIncomingVideoTrack) {
3588 RTCConfiguration config;
3589 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3590 ConnectFakeSignaling();
3591 auto audio_transceiver_or_error =
3592 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3593 ASSERT_TRUE(audio_transceiver_or_error.ok());
3594 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3595
3596 caller()->CreateAndSetAndSignalOffer();
3597 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3598 auto caller_track = audio_transceiver->receiver()->track();
3599 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3600 audio_transceiver->StopStandard();
3601 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3602 caller_track->state());
3603 caller()->CreateAndSetAndSignalOffer();
3604 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3605 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3606 callee_track->state());
3607}
3608
Harald Alvestrand89c40e22021-02-17 08:58:35 +00003609} // namespace
Harald Alvestrand39993842021-02-17 09:05:31 +00003610
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01003611} // namespace webrtc