blob: 6017f54dd47b295251eb2f36f72ea3fdd4b8b0a1 [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 Alvestrand39993842021-02-17 09:05:31 +000011#include <stdint.h>
deadbeef1dcb1642017-03-29 21:08:16 -070012
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -070013#include <algorithm>
deadbeef1dcb1642017-03-29 21:08:16 -070014#include <memory>
Harald Alvestrand39993842021-02-17 09:05:31 +000015#include <string>
16#include <tuple>
Harald Alvestrandc24a2182022-02-23 13:44:59 +000017#include <type_traits>
deadbeef1dcb1642017-03-29 21:08:16 -070018#include <utility>
19#include <vector>
20
Steve Anton64b626b2019-01-28 17:25:26 -080021#include "absl/algorithm/container.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000022#include "absl/types/optional.h"
23#include "api/async_resolver_factory.h"
24#include "api/candidate.h"
25#include "api/crypto/crypto_options.h"
26#include "api/dtmf_sender_interface.h"
27#include "api/ice_transport_interface.h"
28#include "api/jsep.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "api/media_stream_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000030#include "api/media_types.h"
Steve Anton10542f22019-01-11 09:11:00 -080031#include "api/peer_connection_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000032#include "api/rtc_error.h"
33#include "api/rtc_event_log/rtc_event.h"
34#include "api/rtc_event_log/rtc_event_log.h"
35#include "api/rtc_event_log_output.h"
36#include "api/rtp_parameters.h"
Steve Anton10542f22019-01-11 09:11:00 -080037#include "api/rtp_receiver_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000038#include "api/rtp_sender_interface.h"
39#include "api/rtp_transceiver_direction.h"
40#include "api/rtp_transceiver_interface.h"
41#include "api/scoped_refptr.h"
42#include "api/stats/rtc_stats.h"
43#include "api/stats/rtc_stats_report.h"
44#include "api/stats/rtcstats_objects.h"
45#include "api/transport/rtp/rtp_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080046#include "api/uma_metrics.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000047#include "api/units/time_delta.h"
48#include "api/video/video_rotation.h"
49#include "logging/rtc_event_log/fake_rtc_event_log.h"
Qingsi Wang7685e862018-06-11 20:15:46 -070050#include "logging/rtc_event_log/fake_rtc_event_log_factory.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000051#include "media/base/codec.h"
52#include "media/base/media_constants.h"
53#include "media/base/stream_params.h"
Steve Anton10542f22019-01-11 09:11:00 -080054#include "p2p/base/mock_async_resolver.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000055#include "p2p/base/port.h"
56#include "p2p/base/port_allocator.h"
Steve Anton10542f22019-01-11 09:11:00 -080057#include "p2p/base/port_interface.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000058#include "p2p/base/stun_server.h"
Steve Anton10542f22019-01-11 09:11:00 -080059#include "p2p/base/test_stun_server.h"
60#include "p2p/base/test_turn_customizer.h"
61#include "p2p/base/test_turn_server.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000062#include "p2p/base/transport_description.h"
63#include "p2p/base/transport_info.h"
Steve Anton10542f22019-01-11 09:11:00 -080064#include "pc/media_session.h"
65#include "pc/peer_connection.h"
66#include "pc/peer_connection_factory.h"
Steve Anton10542f22019-01-11 09:11:00 -080067#include "pc/session_description.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000068#include "pc/test/fake_periodic_video_source.h"
69#include "pc/test/integration_test_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080070#include "pc/test/mock_peer_connection_observers.h"
Jonas Olssonb75d9e92019-02-22 10:33:29 +010071#include "rtc_base/fake_clock.h"
Qingsi Wangecd30542019-05-22 14:34:56 -070072#include "rtc_base/fake_mdns_responder.h"
Steve Anton10542f22019-01-11 09:11:00 -080073#include "rtc_base/fake_network.h"
74#include "rtc_base/firewall_socket_server.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020075#include "rtc_base/gunit.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000076#include "rtc_base/helpers.h"
77#include "rtc_base/location.h"
78#include "rtc_base/logging.h"
79#include "rtc_base/ref_counted_object.h"
80#include "rtc_base/socket_address.h"
81#include "rtc_base/ssl_certificate.h"
82#include "rtc_base/ssl_fingerprint.h"
83#include "rtc_base/ssl_identity.h"
84#include "rtc_base/ssl_stream_adapter.h"
Steve Anton10542f22019-01-11 09:11:00 -080085#include "rtc_base/test_certificate_verifier.h"
Harald Alvestrand39993842021-02-17 09:05:31 +000086#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080087#include "rtc_base/time_utils.h"
88#include "rtc_base/virtual_socket_server.h"
Mirko Bonadei17f48782018-09-28 08:51:10 +020089#include "system_wrappers/include/metrics.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000090#include "test/gmock.h"
91#include "test/gtest.h"
deadbeef1dcb1642017-03-29 21:08:16 -070092
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010093namespace webrtc {
Harald Alvestrand39993842021-02-17 09:05:31 +000094
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +010095namespace {
96
Seth Hampson2f0d7022018-02-20 11:54:42 -080097class PeerConnectionIntegrationTest
98 : public PeerConnectionIntegrationBaseTest,
Evan Shrubsole7619b7c2022-03-01 10:42:44 +010099 public ::testing::WithParamInterface<
100 std::tuple<SdpSemantics, std::string>> {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800101 protected:
102 PeerConnectionIntegrationTest()
Evan Shrubsole7619b7c2022-03-01 10:42:44 +0100103 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam()),
104 std::get<1>(GetParam())) {}
Seth Hampson2f0d7022018-02-20 11:54:42 -0800105};
106
Yves Gerey100fe632020-01-17 19:15:53 +0100107// Fake clock must be set before threads are started to prevent race on
108// Set/GetClockForTesting().
109// To achieve that, multiple inheritance is used as a mixin pattern
110// where order of construction is finely controlled.
111// This also ensures peerconnection is closed before switching back to non-fake
112// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
113class FakeClockForTest : public rtc::ScopedFakeClock {
114 protected:
115 FakeClockForTest() {
116 // Some things use a time of "0" as a special value, so we need to start out
117 // the fake clock at a nonzero time.
118 // TODO(deadbeef): Fix this.
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100119 AdvanceTime(webrtc::TimeDelta::Seconds(1));
Yves Gerey100fe632020-01-17 19:15:53 +0100120 }
121
122 // Explicit handle.
123 ScopedFakeClock& FakeClock() { return *this; }
124};
125
126// Ensure FakeClockForTest is constructed first (see class for rationale).
127class PeerConnectionIntegrationTestWithFakeClock
128 : public FakeClockForTest,
129 public PeerConnectionIntegrationTest {};
130
Seth Hampson2f0d7022018-02-20 11:54:42 -0800131class PeerConnectionIntegrationTestPlanB
132 : public PeerConnectionIntegrationBaseTest {
133 protected:
134 PeerConnectionIntegrationTestPlanB()
Florent Castelli15a38de2022-04-06 00:38:21 +0200135 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
Seth Hampson2f0d7022018-02-20 11:54:42 -0800136};
137
138class PeerConnectionIntegrationTestUnifiedPlan
139 : public PeerConnectionIntegrationBaseTest {
140 protected:
141 PeerConnectionIntegrationTestUnifiedPlan()
142 : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
143};
144
deadbeef1dcb1642017-03-29 21:08:16 -0700145// Test the OnFirstPacketReceived callback from audio/video RtpReceivers. This
146// includes testing that the callback is invoked if an observer is connected
147// after the first packet has already been received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800148TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700149 RtpReceiverObserverOnFirstPacketReceived) {
150 ASSERT_TRUE(CreatePeerConnectionWrappers());
151 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800152 caller()->AddAudioVideoTracks();
153 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700154 // Start offer/answer exchange and wait for it to complete.
155 caller()->CreateAndSetAndSignalOffer();
156 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
157 // Should be one receiver each for audio/video.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200158 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
159 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700160 // Wait for all "first packet received" callbacks to be fired.
161 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800162 absl::c_all_of(caller()->rtp_receiver_observers(),
163 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
164 return o->first_packet_received();
165 }),
deadbeef1dcb1642017-03-29 21:08:16 -0700166 kMaxWaitForFramesMs);
167 EXPECT_TRUE_WAIT(
Steve Anton64b626b2019-01-28 17:25:26 -0800168 absl::c_all_of(callee()->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 // If new observers are set after the first packet was already received, the
174 // callback should still be invoked.
175 caller()->ResetRtpReceiverObservers();
176 callee()->ResetRtpReceiverObservers();
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200177 EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
178 EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
deadbeef1dcb1642017-03-29 21:08:16 -0700179 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800180 absl::c_all_of(caller()->rtp_receiver_observers(),
181 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
182 return o->first_packet_received();
183 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700184 EXPECT_TRUE(
Steve Anton64b626b2019-01-28 17:25:26 -0800185 absl::c_all_of(callee()->rtp_receiver_observers(),
186 [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
187 return o->first_packet_received();
188 }));
deadbeef1dcb1642017-03-29 21:08:16 -0700189}
190
191class DummyDtmfObserver : public DtmfSenderObserverInterface {
192 public:
193 DummyDtmfObserver() : completed_(false) {}
194
195 // Implements DtmfSenderObserverInterface.
196 void OnToneChange(const std::string& tone) override {
197 tones_.push_back(tone);
198 if (tone.empty()) {
199 completed_ = true;
200 }
201 }
202
203 const std::vector<std::string>& tones() const { return tones_; }
204 bool completed() const { return completed_; }
205
206 private:
207 bool completed_;
208 std::vector<std::string> tones_;
209};
210
Artem Titov880fa812021-07-30 22:30:23 +0200211// Assumes `sender` already has an audio track added and the offer/answer
deadbeef1dcb1642017-03-29 21:08:16 -0700212// exchange is done.
Harald Alvestrand39993842021-02-17 09:05:31 +0000213void TestDtmfFromSenderToReceiver(PeerConnectionIntegrationWrapper* sender,
214 PeerConnectionIntegrationWrapper* receiver) {
Steve Anton15324772018-01-16 10:26:49 -0800215 // We should be able to get a DTMF sender from the local sender.
216 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender =
217 sender->pc()->GetSenders().at(0)->GetDtmfSender();
218 ASSERT_TRUE(dtmf_sender);
deadbeef1dcb1642017-03-29 21:08:16 -0700219 DummyDtmfObserver observer;
deadbeef1dcb1642017-03-29 21:08:16 -0700220 dtmf_sender->RegisterObserver(&observer);
221
222 // Test the DtmfSender object just created.
223 EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
224 EXPECT_TRUE(dtmf_sender->InsertDtmf("1a", 100, 50));
225
226 EXPECT_TRUE_WAIT(observer.completed(), kDefaultTimeout);
227 std::vector<std::string> tones = {"1", "a", ""};
228 EXPECT_EQ(tones, observer.tones());
229 dtmf_sender->UnregisterObserver();
230 // TODO(deadbeef): Verify the tones were actually received end-to-end.
231}
232
233// Verifies the DtmfSenderObserver callbacks for a DtmfSender (one in each
234// direction).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800235TEST_P(PeerConnectionIntegrationTest, DtmfSenderObserver) {
deadbeef1dcb1642017-03-29 21:08:16 -0700236 ASSERT_TRUE(CreatePeerConnectionWrappers());
237 ConnectFakeSignaling();
238 // Only need audio for DTMF.
Steve Anton15324772018-01-16 10:26:49 -0800239 caller()->AddAudioTrack();
240 callee()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -0700241 caller()->CreateAndSetAndSignalOffer();
242 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeef71452802017-05-07 17:21:01 -0700243 // DTLS must finish before the DTMF sender can be used reliably.
244 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -0700245 TestDtmfFromSenderToReceiver(caller(), callee());
246 TestDtmfFromSenderToReceiver(callee(), caller());
247}
248
249// Basic end-to-end test, verifying media can be encoded/transmitted/decoded
250// between two connections, using DTLS-SRTP.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800251TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) {
deadbeef1dcb1642017-03-29 21:08:16 -0700252 ASSERT_TRUE(CreatePeerConnectionWrappers());
253 ConnectFakeSignaling();
Harald Alvestrand194939b2018-01-24 16:04:13 +0100254
deadbeef1dcb1642017-03-29 21:08:16 -0700255 // Do normal offer/answer and wait for some frames to be received in each
256 // direction.
Steve Anton15324772018-01-16 10:26:49 -0800257 caller()->AddAudioVideoTracks();
258 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700259 caller()->CreateAndSetAndSignalOffer();
260 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800261 MediaExpectations media_expectations;
262 media_expectations.ExpectBidirectionalAudioAndVideo();
263 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Ying Wangef3998f2019-12-09 13:06:53 +0100264 EXPECT_METRIC_LE(
265 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
266 webrtc::kEnumCounterKeyProtocolDtls));
267 EXPECT_METRIC_EQ(
268 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
269 webrtc::kEnumCounterKeyProtocolSdes));
deadbeef1dcb1642017-03-29 21:08:16 -0700270}
271
Harald Alvestrandca327932022-04-04 15:37:31 +0000272#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06 +0000273// Uses SDES instead of DTLS for key agreement.
274TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
275 PeerConnectionInterface::RTCConfiguration sdes_config;
276 sdes_config.enable_dtls_srtp.emplace(false);
277 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config));
278 ConnectFakeSignaling();
279
280 // Do normal offer/answer and wait for some frames to be received in each
281 // direction.
282 caller()->AddAudioVideoTracks();
283 callee()->AddAudioVideoTracks();
284 caller()->CreateAndSetAndSignalOffer();
285 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
286 MediaExpectations media_expectations;
287 media_expectations.ExpectBidirectionalAudioAndVideo();
288 ASSERT_TRUE(ExpectNewFrames(media_expectations));
289 EXPECT_METRIC_LE(
290 2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
291 webrtc::kEnumCounterKeyProtocolSdes));
292 EXPECT_METRIC_EQ(
293 0, webrtc::metrics::NumEvents("WebRTC.PeerConnection.KeyProtocol",
294 webrtc::kEnumCounterKeyProtocolDtls));
295}
Harald Alvestrandca327932022-04-04 15:37:31 +0000296#endif
Harald Alvestrand50b95522021-11-18 10:01:06 +0000297
Artem Titov880fa812021-07-30 22:30:23 +0200298// Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions`
Steve Anton9a44b2d2019-07-12 12:58:30 -0700299// option to offer encrypted versions of all header extensions alongside the
300// unencrypted versions.
301TEST_P(PeerConnectionIntegrationTest,
302 EndToEndCallWithEncryptedRtpHeaderExtensions) {
303 CryptoOptions crypto_options;
304 crypto_options.srtp.enable_encrypted_rtp_header_extensions = true;
305 PeerConnectionInterface::RTCConfiguration config;
306 config.crypto_options = crypto_options;
307 // Note: This allows offering >14 RTP header extensions.
308 config.offer_extmap_allow_mixed = true;
309 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
310 ConnectFakeSignaling();
311
312 // Do normal offer/answer and wait for some frames to be received in each
313 // direction.
314 caller()->AddAudioVideoTracks();
315 callee()->AddAudioVideoTracks();
316 caller()->CreateAndSetAndSignalOffer();
317 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
318 MediaExpectations media_expectations;
319 media_expectations.ExpectBidirectionalAudioAndVideo();
320 ASSERT_TRUE(ExpectNewFrames(media_expectations));
321}
322
deadbeef1dcb1642017-03-29 21:08:16 -0700323// This test sets up a call between two parties with a source resolution of
324// 1280x720 and verifies that a 16:9 aspect ratio is received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800325TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -0700326 Send1280By720ResolutionAndReceive16To9AspectRatio) {
327 ASSERT_TRUE(CreatePeerConnectionWrappers());
328 ConnectFakeSignaling();
329
Niels Möller5c7efe72018-05-11 10:34:46 +0200330 // Add video tracks with 16:9 aspect ratio, size 1280 x 720.
331 webrtc::FakePeriodicVideoSource::Config config;
332 config.width = 1280;
333 config.height = 720;
Johannes Kron965e7942018-09-13 15:36:20 +0200334 config.timestamp_offset_ms = rtc::TimeMillis();
Niels Möller5c7efe72018-05-11 10:34:46 +0200335 caller()->AddTrack(caller()->CreateLocalVideoTrackWithConfig(config));
336 callee()->AddTrack(callee()->CreateLocalVideoTrackWithConfig(config));
deadbeef1dcb1642017-03-29 21:08:16 -0700337
338 // Do normal offer/answer and wait for at least one frame to be received in
339 // each direction.
340 caller()->CreateAndSetAndSignalOffer();
341 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
342 callee()->min_video_frames_received_per_track() > 0,
343 kMaxWaitForFramesMs);
344
345 // Check rendered aspect ratio.
346 EXPECT_EQ(16.0 / 9, caller()->local_rendered_aspect_ratio());
347 EXPECT_EQ(16.0 / 9, caller()->rendered_aspect_ratio());
348 EXPECT_EQ(16.0 / 9, callee()->local_rendered_aspect_ratio());
349 EXPECT_EQ(16.0 / 9, callee()->rendered_aspect_ratio());
350}
351
352// This test sets up an one-way call, with media only from caller to
353// callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800354TEST_P(PeerConnectionIntegrationTest, OneWayMediaCall) {
deadbeef1dcb1642017-03-29 21:08:16 -0700355 ASSERT_TRUE(CreatePeerConnectionWrappers());
356 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800357 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700358 caller()->CreateAndSetAndSignalOffer();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800359 MediaExpectations media_expectations;
360 media_expectations.CalleeExpectsSomeAudioAndVideo();
361 media_expectations.CallerExpectsNoAudio();
362 media_expectations.CallerExpectsNoVideo();
363 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700364}
365
Johannes Kron3e983682020-03-29 22:17:00 +0200366// Tests that send only works without the caller having a decoder factory and
367// the callee having an encoder factory.
368TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSendOnlyVideo) {
369 ASSERT_TRUE(
370 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
371 ConnectFakeSignaling();
372 // Add one-directional video, from caller to callee.
373 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
374 caller()->CreateLocalVideoTrack();
375 caller()->AddTrack(caller_track);
376 PeerConnectionInterface::RTCOfferAnswerOptions options;
377 options.offer_to_receive_video = 0;
378 caller()->SetOfferAnswerOptions(options);
379 caller()->CreateAndSetAndSignalOffer();
380 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
381 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
382
383 // Expect video to be received in one direction.
384 MediaExpectations media_expectations;
385 media_expectations.CallerExpectsNoVideo();
386 media_expectations.CalleeExpectsSomeVideo();
387
388 EXPECT_TRUE(ExpectNewFrames(media_expectations));
389}
390
391// Tests that receive only works without the caller having an encoder factory
392// and the callee having a decoder factory.
393TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithReceiveOnlyVideo) {
394 ASSERT_TRUE(
395 CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/false));
396 ConnectFakeSignaling();
397 // Add one-directional video, from callee to caller.
398 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
399 callee()->CreateLocalVideoTrack();
400 callee()->AddTrack(callee_track);
401 PeerConnectionInterface::RTCOfferAnswerOptions options;
402 options.offer_to_receive_video = 1;
403 caller()->SetOfferAnswerOptions(options);
404 caller()->CreateAndSetAndSignalOffer();
405 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
406 ASSERT_EQ(caller()->pc()->GetReceivers().size(), 1u);
407
408 // Expect video to be received in one direction.
409 MediaExpectations media_expectations;
410 media_expectations.CallerExpectsSomeVideo();
411 media_expectations.CalleeExpectsNoVideo();
412
413 EXPECT_TRUE(ExpectNewFrames(media_expectations));
414}
415
416TEST_P(PeerConnectionIntegrationTest,
417 EndToEndCallAddReceiveVideoToSendOnlyCall) {
418 ASSERT_TRUE(CreatePeerConnectionWrappers());
419 ConnectFakeSignaling();
420 // Add one-directional video, from caller to callee.
421 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
422 caller()->CreateLocalVideoTrack();
423 caller()->AddTrack(caller_track);
424 caller()->CreateAndSetAndSignalOffer();
425 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
426
427 // Add receive video.
428 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
429 callee()->CreateLocalVideoTrack();
430 callee()->AddTrack(callee_track);
431 caller()->CreateAndSetAndSignalOffer();
432 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
433
434 // Ensure that video frames are received end-to-end.
435 MediaExpectations media_expectations;
436 media_expectations.ExpectBidirectionalVideo();
437 ASSERT_TRUE(ExpectNewFrames(media_expectations));
438}
439
440TEST_P(PeerConnectionIntegrationTest,
441 EndToEndCallAddSendVideoToReceiveOnlyCall) {
442 ASSERT_TRUE(CreatePeerConnectionWrappers());
443 ConnectFakeSignaling();
444 // Add one-directional video, from callee to caller.
445 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
446 callee()->CreateLocalVideoTrack();
447 callee()->AddTrack(callee_track);
448 caller()->CreateAndSetAndSignalOffer();
449 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
450
451 // Add send video.
452 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
453 caller()->CreateLocalVideoTrack();
454 caller()->AddTrack(caller_track);
455 caller()->CreateAndSetAndSignalOffer();
456 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
457
458 // Expect video to be received in one direction.
459 MediaExpectations media_expectations;
460 media_expectations.ExpectBidirectionalVideo();
461 ASSERT_TRUE(ExpectNewFrames(media_expectations));
462}
463
464TEST_P(PeerConnectionIntegrationTest,
465 EndToEndCallRemoveReceiveVideoFromSendReceiveCall) {
466 ASSERT_TRUE(CreatePeerConnectionWrappers());
467 ConnectFakeSignaling();
468 // Add send video, from caller to callee.
469 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
470 caller()->CreateLocalVideoTrack();
471 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
472 caller()->AddTrack(caller_track);
473 // Add receive video, from callee to caller.
474 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
475 callee()->CreateLocalVideoTrack();
476
477 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
478 callee()->AddTrack(callee_track);
479 caller()->CreateAndSetAndSignalOffer();
480 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
481
482 // Remove receive video (i.e., callee sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000483 callee()->pc()->RemoveTrackOrError(callee_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200484
485 caller()->CreateAndSetAndSignalOffer();
486 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
487
488 // Expect one-directional video.
489 MediaExpectations media_expectations;
490 media_expectations.CallerExpectsNoVideo();
491 media_expectations.CalleeExpectsSomeVideo();
492
493 ASSERT_TRUE(ExpectNewFrames(media_expectations));
494}
495
496TEST_P(PeerConnectionIntegrationTest,
497 EndToEndCallRemoveSendVideoFromSendReceiveCall) {
498 ASSERT_TRUE(CreatePeerConnectionWrappers());
499 ConnectFakeSignaling();
500 // Add send video, from caller to callee.
501 rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
502 caller()->CreateLocalVideoTrack();
503 rtc::scoped_refptr<webrtc::RtpSenderInterface> caller_sender =
504 caller()->AddTrack(caller_track);
505 // Add receive video, from callee to caller.
506 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
507 callee()->CreateLocalVideoTrack();
508
509 rtc::scoped_refptr<webrtc::RtpSenderInterface> callee_sender =
510 callee()->AddTrack(callee_track);
511 caller()->CreateAndSetAndSignalOffer();
512 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
513
514 // Remove send video (i.e., caller sender track).
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000515 caller()->pc()->RemoveTrackOrError(caller_sender);
Johannes Kron3e983682020-03-29 22:17:00 +0200516
517 caller()->CreateAndSetAndSignalOffer();
518 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
519
520 // Expect one-directional video.
521 MediaExpectations media_expectations;
522 media_expectations.CalleeExpectsNoVideo();
523 media_expectations.CallerExpectsSomeVideo();
524
525 ASSERT_TRUE(ExpectNewFrames(media_expectations));
526}
527
deadbeef1dcb1642017-03-29 21:08:16 -0700528// This test sets up a audio call initially, with the callee rejecting video
529// initially. Then later the callee decides to upgrade to audio/video, and
530// initiates a new offer/answer exchange.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800531TEST_P(PeerConnectionIntegrationTest, AudioToVideoUpgrade) {
deadbeef1dcb1642017-03-29 21:08:16 -0700532 ASSERT_TRUE(CreatePeerConnectionWrappers());
533 ConnectFakeSignaling();
534 // Initially, offer an audio/video stream from the caller, but refuse to
535 // send/receive video on the callee side.
Steve Anton15324772018-01-16 10:26:49 -0800536 caller()->AddAudioVideoTracks();
537 callee()->AddAudioTrack();
Florent Castelli15a38de2022-04-06 00:38:21 +0200538 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800539 PeerConnectionInterface::RTCOfferAnswerOptions options;
540 options.offer_to_receive_video = 0;
541 callee()->SetOfferAnswerOptions(options);
542 } else {
543 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200544 callee()
545 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
546 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800547 });
548 }
deadbeef1dcb1642017-03-29 21:08:16 -0700549 // Do offer/answer and make sure audio is still received end-to-end.
550 caller()->CreateAndSetAndSignalOffer();
551 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800552 {
553 MediaExpectations media_expectations;
554 media_expectations.ExpectBidirectionalAudio();
555 media_expectations.ExpectNoVideo();
556 ASSERT_TRUE(ExpectNewFrames(media_expectations));
557 }
deadbeef1dcb1642017-03-29 21:08:16 -0700558 // Sanity check that the callee's description has a rejected video section.
559 ASSERT_NE(nullptr, callee()->pc()->local_description());
560 const ContentInfo* callee_video_content =
561 GetFirstVideoContent(callee()->pc()->local_description()->description());
562 ASSERT_NE(nullptr, callee_video_content);
563 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800564
deadbeef1dcb1642017-03-29 21:08:16 -0700565 // Now negotiate with video and ensure negotiation succeeds, with video
566 // frames and additional audio frames being received.
Steve Anton15324772018-01-16 10:26:49 -0800567 callee()->AddVideoTrack();
Florent Castelli15a38de2022-04-06 00:38:21 +0200568 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800569 PeerConnectionInterface::RTCOfferAnswerOptions options;
570 options.offer_to_receive_video = 1;
571 callee()->SetOfferAnswerOptions(options);
572 } else {
573 callee()->SetRemoteOfferHandler(nullptr);
574 caller()->SetRemoteOfferHandler([this] {
575 // The caller creates a new transceiver to receive video on when receiving
576 // the offer, but by default it is send only.
577 auto transceivers = caller()->pc()->GetTransceivers();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200578 ASSERT_EQ(2U, transceivers.size());
Seth Hampson2f0d7022018-02-20 11:54:42 -0800579 ASSERT_EQ(cricket::MEDIA_TYPE_VIDEO,
Harald Alvestrand6060df52020-08-11 09:54:02 +0200580 transceivers[1]->receiver()->media_type());
Niels Möllerafb246b2022-04-20 14:26:50 +0200581 transceivers[1]->sender()->SetTrack(
582 caller()->CreateLocalVideoTrack().get());
Harald Alvestrand6060df52020-08-11 09:54:02 +0200583 transceivers[1]->SetDirectionWithError(
584 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800585 });
586 }
deadbeef1dcb1642017-03-29 21:08:16 -0700587 callee()->CreateAndSetAndSignalOffer();
588 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800589 {
590 // Expect additional audio frames to be received after the upgrade.
591 MediaExpectations media_expectations;
592 media_expectations.ExpectBidirectionalAudioAndVideo();
593 ASSERT_TRUE(ExpectNewFrames(media_expectations));
594 }
deadbeef1dcb1642017-03-29 21:08:16 -0700595}
596
deadbeef4389b4d2017-09-07 09:07:36 -0700597// Simpler than the above test; just add an audio track to an established
598// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800599TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -0700600 ASSERT_TRUE(CreatePeerConnectionWrappers());
601 ConnectFakeSignaling();
602 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -0800603 caller()->AddVideoTrack();
604 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700605 caller()->CreateAndSetAndSignalOffer();
606 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
607 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -0800608 caller()->AddAudioTrack();
609 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700610 caller()->CreateAndSetAndSignalOffer();
611 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
612 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800613 MediaExpectations media_expectations;
614 media_expectations.ExpectBidirectionalAudioAndVideo();
615 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -0700616}
617
deadbeef1dcb1642017-03-29 21:08:16 -0700618// This test sets up a call that's transferred to a new caller with a different
619// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800620TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -0700621 ASSERT_TRUE(CreatePeerConnectionWrappers());
622 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800623 caller()->AddAudioVideoTracks();
624 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700625 caller()->CreateAndSetAndSignalOffer();
626 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
627
628 // Keep the original peer around which will still send packets to the
629 // receiving client. These SRTP packets will be dropped.
Harald Alvestrand39993842021-02-17 09:05:31 +0000630 std::unique_ptr<PeerConnectionIntegrationWrapper> original_peer(
deadbeef1dcb1642017-03-29 21:08:16 -0700631 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -0800632 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -0700633 // TODO(deadbeef): Why do we call Close here? That goes against the comment
634 // directly above.
635 original_peer->pc()->Close();
636
637 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800638 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700639 caller()->CreateAndSetAndSignalOffer();
640 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
641 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800642 MediaExpectations media_expectations;
643 media_expectations.ExpectBidirectionalAudioAndVideo();
644 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700645}
646
647// This test sets up a call that's transferred to a new callee with a different
648// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800649TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -0700650 ASSERT_TRUE(CreatePeerConnectionWrappers());
651 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800652 caller()->AddAudioVideoTracks();
653 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700654 caller()->CreateAndSetAndSignalOffer();
655 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
656
657 // Keep the original peer around which will still send packets to the
658 // receiving client. These SRTP packets will be dropped.
Harald Alvestrand39993842021-02-17 09:05:31 +0000659 std::unique_ptr<PeerConnectionIntegrationWrapper> original_peer(
deadbeef1dcb1642017-03-29 21:08:16 -0700660 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -0800661 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -0700662 // TODO(deadbeef): Why do we call Close here? That goes against the comment
663 // directly above.
664 original_peer->pc()->Close();
665
666 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800667 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700668 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
669 caller()->CreateAndSetAndSignalOffer();
670 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
671 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800672 MediaExpectations media_expectations;
673 media_expectations.ExpectBidirectionalAudioAndVideo();
674 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700675}
676
677// This test sets up a non-bundled call and negotiates bundling at the same
678// time as starting an ICE restart. When bundling is in effect in the restart,
679// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800680TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -0700681 ASSERT_TRUE(CreatePeerConnectionWrappers());
682 ConnectFakeSignaling();
683
Steve Anton15324772018-01-16 10:26:49 -0800684 caller()->AddAudioVideoTracks();
685 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700686 // Remove the bundle group from the SDP received by the callee.
687 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
688 desc->RemoveGroupByName("BUNDLE");
689 });
690 caller()->CreateAndSetAndSignalOffer();
691 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800692 {
693 MediaExpectations media_expectations;
694 media_expectations.ExpectBidirectionalAudioAndVideo();
695 ASSERT_TRUE(ExpectNewFrames(media_expectations));
696 }
deadbeef1dcb1642017-03-29 21:08:16 -0700697 // Now stop removing the BUNDLE group, and trigger an ICE restart.
698 callee()->SetReceivedSdpMunger(nullptr);
699 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
700 caller()->CreateAndSetAndSignalOffer();
701 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
702
703 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800704 {
705 MediaExpectations media_expectations;
706 media_expectations.ExpectBidirectionalAudioAndVideo();
707 ASSERT_TRUE(ExpectNewFrames(media_expectations));
708 }
deadbeef1dcb1642017-03-29 21:08:16 -0700709}
710
711// Test CVO (Coordination of Video Orientation). If a video source is rotated
712// and both peers support the CVO RTP header extension, the actual video frames
713// don't need to be encoded in different resolutions, since the rotation is
714// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800715TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700716 ASSERT_TRUE(CreatePeerConnectionWrappers());
717 ConnectFakeSignaling();
718 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800719 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700720 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800721 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700722 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
723
724 // Wait for video frames to be received by both sides.
725 caller()->CreateAndSetAndSignalOffer();
726 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
727 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
728 callee()->min_video_frames_received_per_track() > 0,
729 kMaxWaitForFramesMs);
730
731 // Ensure that the aspect ratio is unmodified.
732 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
733 // not just assumed.
734 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
735 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
736 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
737 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
738 // Ensure that the CVO bits were surfaced to the renderer.
739 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
740 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
741}
742
743// Test that when the CVO extension isn't supported, video is rotated the
744// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800745TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700746 ASSERT_TRUE(CreatePeerConnectionWrappers());
747 ConnectFakeSignaling();
748 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800749 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700750 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800751 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700752 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
753
754 // Remove the CVO extension from the offered SDP.
755 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
756 cricket::VideoContentDescription* video =
757 GetFirstVideoContentDescription(desc);
758 video->ClearRtpHeaderExtensions();
759 });
760 // Wait for video frames to be received by both sides.
761 caller()->CreateAndSetAndSignalOffer();
762 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
763 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
764 callee()->min_video_frames_received_per_track() > 0,
765 kMaxWaitForFramesMs);
766
767 // Expect that the aspect ratio is inversed to account for the 90/270 degree
768 // rotation.
769 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
770 // not just assumed.
771 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
772 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
773 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
774 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
775 // Expect that each endpoint is unaware of the rotation of the other endpoint.
776 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
777 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
778}
779
deadbeef1dcb1642017-03-29 21:08:16 -0700780// Test that if the answerer rejects the audio m= section, no audio is sent or
781// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800782TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700783 ASSERT_TRUE(CreatePeerConnectionWrappers());
784 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800785 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200786 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800787 // Only add video track for callee, and set offer_to_receive_audio to 0, so
788 // it will reject the audio m= section completely.
789 PeerConnectionInterface::RTCOfferAnswerOptions options;
790 options.offer_to_receive_audio = 0;
791 callee()->SetOfferAnswerOptions(options);
792 } else {
793 // Stopping the audio RtpTransceiver will cause the media section to be
794 // rejected in the answer.
795 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200796 callee()
797 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
798 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800799 });
800 }
Steve Anton15324772018-01-16 10:26:49 -0800801 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700802 // Do offer/answer and wait for successful end-to-end video frames.
803 caller()->CreateAndSetAndSignalOffer();
804 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800805 MediaExpectations media_expectations;
806 media_expectations.ExpectBidirectionalVideo();
807 media_expectations.ExpectNoAudio();
808 ASSERT_TRUE(ExpectNewFrames(media_expectations));
809
deadbeef1dcb1642017-03-29 21:08:16 -0700810 // Sanity check that the callee's description has a rejected audio section.
811 ASSERT_NE(nullptr, callee()->pc()->local_description());
812 const ContentInfo* callee_audio_content =
813 GetFirstAudioContent(callee()->pc()->local_description()->description());
814 ASSERT_NE(nullptr, callee_audio_content);
815 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800816 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200817 // The caller's transceiver should have stopped after receiving the answer,
818 // and thus no longer listed in transceivers.
819 EXPECT_EQ(nullptr,
820 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800821 }
deadbeef1dcb1642017-03-29 21:08:16 -0700822}
823
824// Test that if the answerer rejects the video m= section, no video is sent or
825// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800826TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700827 ASSERT_TRUE(CreatePeerConnectionWrappers());
828 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800829 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200830 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800831 // Only add audio track for callee, and set offer_to_receive_video to 0, so
832 // it will reject the video m= section completely.
833 PeerConnectionInterface::RTCOfferAnswerOptions options;
834 options.offer_to_receive_video = 0;
835 callee()->SetOfferAnswerOptions(options);
836 } else {
837 // Stopping the video RtpTransceiver will cause the media section to be
838 // rejected in the answer.
839 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200840 callee()
841 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
842 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800843 });
844 }
Steve Anton15324772018-01-16 10:26:49 -0800845 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700846 // Do offer/answer and wait for successful end-to-end audio frames.
847 caller()->CreateAndSetAndSignalOffer();
848 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800849 MediaExpectations media_expectations;
850 media_expectations.ExpectBidirectionalAudio();
851 media_expectations.ExpectNoVideo();
852 ASSERT_TRUE(ExpectNewFrames(media_expectations));
853
deadbeef1dcb1642017-03-29 21:08:16 -0700854 // Sanity check that the callee's description has a rejected video section.
855 ASSERT_NE(nullptr, callee()->pc()->local_description());
856 const ContentInfo* callee_video_content =
857 GetFirstVideoContent(callee()->pc()->local_description()->description());
858 ASSERT_NE(nullptr, callee_video_content);
859 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800860 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200861 // The caller's transceiver should have stopped after receiving the answer,
862 // and thus is no longer present.
863 EXPECT_EQ(nullptr,
864 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800865 }
deadbeef1dcb1642017-03-29 21:08:16 -0700866}
867
868// Test that if the answerer rejects both audio and video m= sections, nothing
869// bad happens.
870// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
871// test anything but the fact that negotiation succeeds, which doesn't mean
872// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800873TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -0700874 ASSERT_TRUE(CreatePeerConnectionWrappers());
875 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800876 caller()->AddAudioVideoTracks();
Florent Castelli15a38de2022-04-06 00:38:21 +0200877 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800878 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
879 // will reject both audio and video m= sections.
880 PeerConnectionInterface::RTCOfferAnswerOptions options;
881 options.offer_to_receive_audio = 0;
882 options.offer_to_receive_video = 0;
883 callee()->SetOfferAnswerOptions(options);
884 } else {
885 callee()->SetRemoteOfferHandler([this] {
886 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +0100887 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200888 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800889 }
890 });
891 }
deadbeef1dcb1642017-03-29 21:08:16 -0700892 // Do offer/answer and wait for stable signaling state.
893 caller()->CreateAndSetAndSignalOffer();
894 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800895
deadbeef1dcb1642017-03-29 21:08:16 -0700896 // Sanity check that the callee's description has rejected m= sections.
897 ASSERT_NE(nullptr, callee()->pc()->local_description());
898 const ContentInfo* callee_audio_content =
899 GetFirstAudioContent(callee()->pc()->local_description()->description());
900 ASSERT_NE(nullptr, callee_audio_content);
901 EXPECT_TRUE(callee_audio_content->rejected);
902 const ContentInfo* callee_video_content =
903 GetFirstVideoContent(callee()->pc()->local_description()->description());
904 ASSERT_NE(nullptr, callee_video_content);
905 EXPECT_TRUE(callee_video_content->rejected);
906}
907
908// This test sets up an audio and video call between two parties. After the
909// call runs for a while, the caller sends an updated offer with video being
910// rejected. Once the re-negotiation is done, the video flow should stop and
911// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800912TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700913 ASSERT_TRUE(CreatePeerConnectionWrappers());
914 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800915 caller()->AddAudioVideoTracks();
916 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700917 caller()->CreateAndSetAndSignalOffer();
918 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800919 {
920 MediaExpectations media_expectations;
921 media_expectations.ExpectBidirectionalAudioAndVideo();
922 ASSERT_TRUE(ExpectNewFrames(media_expectations));
923 }
deadbeef1dcb1642017-03-29 21:08:16 -0700924 // Renegotiate, rejecting the video m= section.
Florent Castelli15a38de2022-04-06 00:38:21 +0200925 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -0800926 caller()->SetGeneratedSdpMunger(
927 [](cricket::SessionDescription* description) {
928 for (cricket::ContentInfo& content : description->contents()) {
929 if (cricket::IsVideoContent(&content)) {
930 content.rejected = true;
931 }
932 }
933 });
934 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200935 caller()
936 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
937 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800938 }
deadbeef1dcb1642017-03-29 21:08:16 -0700939 caller()->CreateAndSetAndSignalOffer();
940 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
941
942 // Sanity check that the caller's description has a rejected video section.
943 ASSERT_NE(nullptr, caller()->pc()->local_description());
944 const ContentInfo* caller_video_content =
945 GetFirstVideoContent(caller()->pc()->local_description()->description());
946 ASSERT_NE(nullptr, caller_video_content);
947 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -0700948 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800949 {
950 MediaExpectations media_expectations;
951 media_expectations.ExpectBidirectionalAudio();
952 media_expectations.ExpectNoVideo();
953 ASSERT_TRUE(ExpectNewFrames(media_expectations));
954 }
deadbeef1dcb1642017-03-29 21:08:16 -0700955}
956
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700957// Do one offer/answer with audio, another that disables it (rejecting the m=
958// section), and another that re-enables it. Regression test for:
959// bugs.webrtc.org/6023
960TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
961 ASSERT_TRUE(CreatePeerConnectionWrappers());
962 ConnectFakeSignaling();
963
964 // Add audio track, do normal offer/answer.
965 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
966 caller()->CreateLocalAudioTrack();
967 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
968 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
969 caller()->CreateAndSetAndSignalOffer();
970 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
971
972 // Remove audio track, and set offer_to_receive_audio to false to cause the
973 // m= section to be completely disabled, not just "recvonly".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000974 caller()->pc()->RemoveTrackOrError(sender);
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700975 PeerConnectionInterface::RTCOfferAnswerOptions options;
976 options.offer_to_receive_audio = 0;
977 caller()->SetOfferAnswerOptions(options);
978 caller()->CreateAndSetAndSignalOffer();
979 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
980
981 // Add the audio track again, expecting negotiation to succeed and frames to
982 // flow.
983 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
984 options.offer_to_receive_audio = 1;
985 caller()->SetOfferAnswerOptions(options);
986 caller()->CreateAndSetAndSignalOffer();
987 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
988
989 MediaExpectations media_expectations;
990 media_expectations.CalleeExpectsSomeAudio();
991 EXPECT_TRUE(ExpectNewFrames(media_expectations));
992}
993
deadbeef1dcb1642017-03-29 21:08:16 -0700994// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
995// is needed to support legacy endpoints.
996// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
997// add a test for an end-to-end test without MID signaling either (basically,
998// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800999TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -07001000 ASSERT_TRUE(CreatePeerConnectionWrappers());
1001 ConnectFakeSignaling();
1002 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08001003 caller()->AddAudioVideoTracks();
1004 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07001005 // Remove SSRCs and MSIDs from the received offer SDP.
1006 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07001007 caller()->CreateAndSetAndSignalOffer();
1008 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001009 MediaExpectations media_expectations;
1010 media_expectations.ExpectBidirectionalAudioAndVideo();
1011 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001012}
1013
Seth Hampson5897a6e2018-04-03 11:16:33 -07001014// Basic end-to-end test, without SSRC signaling. This means that the track
1015// was created properly and frames are delivered when the MSIDs are communicated
1016// with a=msid lines and no a=ssrc lines.
1017TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1018 EndToEndCallWithoutSsrcSignaling) {
1019 const char kStreamId[] = "streamId";
1020 ASSERT_TRUE(CreatePeerConnectionWrappers());
1021 ConnectFakeSignaling();
1022 // Add just audio tracks.
1023 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
1024 callee()->AddAudioTrack();
1025
1026 // Remove SSRCs from the received offer SDP.
1027 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
1028 caller()->CreateAndSetAndSignalOffer();
1029 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1030 MediaExpectations media_expectations;
1031 media_expectations.ExpectBidirectionalAudio();
1032 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1033}
1034
Johannes Kron3e983682020-03-29 22:17:00 +02001035TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1036 EndToEndCallAddReceiveVideoToSendOnlyCall) {
1037 ASSERT_TRUE(CreatePeerConnectionWrappers());
1038 ConnectFakeSignaling();
1039 // Add one-directional video, from caller to callee.
1040 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
1041 caller()->CreateLocalVideoTrack();
1042
1043 RtpTransceiverInit video_transceiver_init;
1044 video_transceiver_init.stream_ids = {"video1"};
1045 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
1046 auto video_sender =
1047 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
1048 caller()->CreateAndSetAndSignalOffer();
1049 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1050
1051 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +02001052 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02001053
1054 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
1055 callee()->CreateLocalVideoTrack();
1056
1057 callee()->AddTrack(callee_track);
1058 caller()->CreateAndSetAndSignalOffer();
1059 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1060 // Ensure that video frames are received end-to-end.
1061 MediaExpectations media_expectations;
1062 media_expectations.ExpectBidirectionalVideo();
1063 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1064}
1065
Steve Antondf527fd2018-04-27 15:52:03 -07001066// Tests that video flows between multiple video tracks when SSRCs are not
1067// signaled. This exercises the MID RTP header extension which is needed to
1068// demux the incoming video tracks.
1069TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1070 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
1071 ASSERT_TRUE(CreatePeerConnectionWrappers());
1072 ConnectFakeSignaling();
1073 caller()->AddVideoTrack();
1074 caller()->AddVideoTrack();
1075 callee()->AddVideoTrack();
1076 callee()->AddVideoTrack();
1077
1078 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1079 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1080 caller()->CreateAndSetAndSignalOffer();
1081 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1082 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1083 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1084
1085 // Expect video to be received in both directions on both tracks.
1086 MediaExpectations media_expectations;
1087 media_expectations.ExpectBidirectionalVideo();
1088 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1089}
1090
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07001091// Used for the test below.
1092void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
1093 RemoveSsrcsAndKeepMsids(desc);
1094 desc->RemoveGroupByName("BUNDLE");
1095 for (ContentInfo& content : desc->contents()) {
1096 cricket::MediaContentDescription* media = content.media_description();
1097 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1098 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1099 [](const RtpExtension& extension) {
1100 return extension.uri ==
1101 RtpExtension::kMidUri;
1102 }),
1103 extensions.end());
1104 media->set_rtp_header_extensions(extensions);
1105 }
1106}
1107
1108// Tests that video flows between multiple video tracks when BUNDLE is not used,
1109// SSRCs are not signaled and the MID RTP header extension is not used. This
1110// relies on demuxing by payload type, which normally doesn't work if you have
1111// multiple media sections using the same payload type, but which should work as
1112// long as the media sections aren't bundled.
1113// Regression test for: http://crbug.com/webrtc/12023
1114TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1115 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
1116 ASSERT_TRUE(CreatePeerConnectionWrappers());
1117 ConnectFakeSignaling();
1118 caller()->AddVideoTrack();
1119 caller()->AddVideoTrack();
1120 callee()->AddVideoTrack();
1121 callee()->AddVideoTrack();
1122 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1123 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
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 not bundled.
1129 ASSERT_NE(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
1138// Used for the test below.
1139void ModifyPayloadTypesAndRemoveMidExtension(
1140 cricket::SessionDescription* desc) {
1141 int pt = 96;
1142 for (ContentInfo& content : desc->contents()) {
1143 cricket::MediaContentDescription* media = content.media_description();
1144 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1145 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1146 [](const RtpExtension& extension) {
1147 return extension.uri ==
1148 RtpExtension::kMidUri;
1149 }),
1150 extensions.end());
1151 media->set_rtp_header_extensions(extensions);
1152 cricket::VideoContentDescription* video = media->as_video();
1153 ASSERT_TRUE(video != nullptr);
1154 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
1155 video->set_codecs(codecs);
1156 }
1157}
1158
1159// Tests that two video tracks can be demultiplexed by payload type alone, by
1160// using different payload types for the same codec in different m= sections.
1161// This practice is discouraged but historically has been supported.
1162// Regression test for: http://crbug.com/webrtc/12029
1163TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1164 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
1165 ASSERT_TRUE(CreatePeerConnectionWrappers());
1166 ConnectFakeSignaling();
1167 caller()->AddVideoTrack();
1168 caller()->AddVideoTrack();
1169 callee()->AddVideoTrack();
1170 callee()->AddVideoTrack();
1171 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1172 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1173 // We can't remove SSRCs from the generated SDP because then no send streams
1174 // would be created.
1175 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1176 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1177 caller()->CreateAndSetAndSignalOffer();
1178 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1179 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1180 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1181 // Make sure we are bundled.
1182 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
1183 caller()->pc()->GetSenders()[1]->dtls_transport());
1184
1185 // Expect video to be received in both directions on both tracks.
1186 MediaExpectations media_expectations;
1187 media_expectations.ExpectBidirectionalVideo();
1188 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1189}
1190
Henrik Boström5b147782018-12-04 11:25:05 +01001191TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
1192 ASSERT_TRUE(CreatePeerConnectionWrappers());
1193 ConnectFakeSignaling();
1194 caller()->AddAudioTrack();
1195 caller()->AddVideoTrack();
1196 caller()->CreateAndSetAndSignalOffer();
1197 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1198 auto callee_receivers = callee()->pc()->GetReceivers();
1199 ASSERT_EQ(2u, callee_receivers.size());
1200 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
1201 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
1202}
1203
1204TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
1205 ASSERT_TRUE(CreatePeerConnectionWrappers());
1206 ConnectFakeSignaling();
1207 caller()->AddAudioTrack();
1208 caller()->AddVideoTrack();
1209 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1210 caller()->CreateAndSetAndSignalOffer();
1211 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1212 auto callee_receivers = callee()->pc()->GetReceivers();
1213 ASSERT_EQ(2u, callee_receivers.size());
1214 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
1215 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
1216 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
1217 callee_receivers[1]->stream_ids()[0]);
1218 EXPECT_EQ(callee_receivers[0]->streams()[0],
1219 callee_receivers[1]->streams()[0]);
1220}
1221
deadbeef1dcb1642017-03-29 21:08:16 -07001222// Test that if two video tracks are sent (from caller to callee, in this test),
1223// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001224TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07001225 ASSERT_TRUE(CreatePeerConnectionWrappers());
1226 ConnectFakeSignaling();
1227 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08001228 caller()->AddAudioVideoTracks();
1229 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001230 caller()->CreateAndSetAndSignalOffer();
1231 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08001232 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001233
1234 MediaExpectations media_expectations;
1235 media_expectations.CalleeExpectsSomeAudioAndVideo();
1236 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001237}
1238
1239static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
1240 bool first = true;
1241 for (cricket::ContentInfo& content : desc->contents()) {
1242 if (first) {
1243 first = false;
1244 continue;
1245 }
1246 content.bundle_only = true;
1247 }
1248 first = true;
1249 for (cricket::TransportInfo& transport : desc->transport_infos()) {
1250 if (first) {
1251 first = false;
1252 continue;
1253 }
1254 transport.description.ice_ufrag.clear();
1255 transport.description.ice_pwd.clear();
1256 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
1257 transport.description.identity_fingerprint.reset(nullptr);
1258 }
1259}
1260
1261// Test that if applying a true "max bundle" offer, which uses ports of 0,
1262// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
1263// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
1264// successfully and media flows.
1265// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
1266// TODO(deadbeef): Won't need this test once we start generating actual
1267// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001268TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001269 EndToEndCallWithSpecCompliantMaxBundleOffer) {
1270 ASSERT_TRUE(CreatePeerConnectionWrappers());
1271 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001272 caller()->AddAudioVideoTracks();
1273 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001274 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
1275 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
1276 // but the first m= section.
1277 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
1278 caller()->CreateAndSetAndSignalOffer();
1279 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001280 MediaExpectations media_expectations;
1281 media_expectations.ExpectBidirectionalAudioAndVideo();
1282 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001283}
1284
1285// Test that we can receive the audio output level from a remote audio track.
1286// TODO(deadbeef): Use a fake audio source and verify that the output level is
1287// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001288TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001289 ASSERT_TRUE(CreatePeerConnectionWrappers());
1290 ConnectFakeSignaling();
1291 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001292 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001293 caller()->CreateAndSetAndSignalOffer();
1294 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1295
1296 // Get the audio output level stats. Note that the level is not available
1297 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07001298 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001299 kMaxWaitForFramesMs);
1300}
1301
1302// Test that an audio input level is reported.
1303// TODO(deadbeef): Use a fake audio source and verify that the input level is
1304// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001305TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001306 ASSERT_TRUE(CreatePeerConnectionWrappers());
1307 ConnectFakeSignaling();
1308 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001309 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001310 caller()->CreateAndSetAndSignalOffer();
1311 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1312
1313 // Get the audio input level stats. The level should be available very
1314 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07001315 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001316 kMaxWaitForStatsMs);
1317}
1318
1319// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001320TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001321 ASSERT_TRUE(CreatePeerConnectionWrappers());
1322 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001323 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001324 // Do offer/answer, wait for the callee to receive some frames.
1325 caller()->CreateAndSetAndSignalOffer();
1326 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001327
1328 MediaExpectations media_expectations;
1329 media_expectations.CalleeExpectsSomeAudioAndVideo();
1330 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001331
1332 // Get a handle to the remote tracks created, so they can be used as GetStats
1333 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01001334 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08001335 // We received frames, so we definitely should have nonzero "received bytes"
1336 // stats at this point.
Niels Möllerafb246b2022-04-20 14:26:50 +02001337 EXPECT_GT(
1338 callee()->OldGetStatsForTrack(receiver->track().get())->BytesReceived(),
1339 0);
Steve Anton15324772018-01-16 10:26:49 -08001340 }
deadbeef1dcb1642017-03-29 21:08:16 -07001341}
1342
1343// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001344TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001345 ASSERT_TRUE(CreatePeerConnectionWrappers());
1346 ConnectFakeSignaling();
1347 auto audio_track = caller()->CreateLocalAudioTrack();
1348 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08001349 caller()->AddTrack(audio_track);
1350 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07001351 // Do offer/answer, wait for the callee to receive some frames.
1352 caller()->CreateAndSetAndSignalOffer();
1353 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001354 MediaExpectations media_expectations;
1355 media_expectations.CalleeExpectsSomeAudioAndVideo();
1356 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001357
1358 // The callee received frames, so we definitely should have nonzero "sent
1359 // bytes" stats at this point.
Niels Möllerafb246b2022-04-20 14:26:50 +02001360 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track.get())->BytesSent(), 0);
1361 EXPECT_GT(caller()->OldGetStatsForTrack(video_track.get())->BytesSent(), 0);
deadbeefd8ad7882017-04-18 16:01:17 -07001362}
1363
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001364// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001365TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001366 ASSERT_TRUE(CreatePeerConnectionWrappers());
1367 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001368 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001369
Steve Anton15324772018-01-16 10:26:49 -08001370 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001371
1372 // Do offer/answer, wait for the callee to receive some frames.
1373 caller()->CreateAndSetAndSignalOffer();
1374 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1375
1376 // Get the remote audio track created on the receiver, so they can be used as
1377 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08001378 auto receivers = callee()->pc()->GetReceivers();
1379 ASSERT_EQ(1u, receivers.size());
1380 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001381
1382 // Get the audio output level stats. Note that the level is not available
1383 // until an RTCP packet has been received.
Niels Möllerafb246b2022-04-20 14:26:50 +02001384 EXPECT_TRUE_WAIT(callee()->OldGetStatsForTrack(remote_audio_track.get())
1385 ->CaptureStartNtpTime() > 0,
1386 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001387}
1388
Steve Antona41959e2018-11-28 11:15:33 -08001389// Test that the track ID is associated with all local and remote SSRC stats
1390// using the old GetStats() and more than 1 audio and more than 1 video track.
1391// This is a regression test for crbug.com/906988
1392TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1393 OldGetStatsAssociatesTrackIdForManyMediaSections) {
1394 ASSERT_TRUE(CreatePeerConnectionWrappers());
1395 ConnectFakeSignaling();
1396 auto audio_sender_1 = caller()->AddAudioTrack();
1397 auto video_sender_1 = caller()->AddVideoTrack();
1398 auto audio_sender_2 = caller()->AddAudioTrack();
1399 auto video_sender_2 = caller()->AddVideoTrack();
1400 caller()->CreateAndSetAndSignalOffer();
1401 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1402
1403 MediaExpectations media_expectations;
1404 media_expectations.CalleeExpectsSomeAudioAndVideo();
1405 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1406
1407 std::vector<std::string> track_ids = {
1408 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1409 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1410
1411 auto caller_stats = caller()->OldGetStats();
1412 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1413 auto callee_stats = callee()->OldGetStats();
1414 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1415}
1416
Steve Antonffa6ce42018-11-30 09:26:08 -08001417// Test that the new GetStats() returns stats for all outgoing/incoming streams
1418// with the correct track IDs if there are more than one audio and more than one
1419// video senders/receivers.
1420TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
1421 ASSERT_TRUE(CreatePeerConnectionWrappers());
1422 ConnectFakeSignaling();
1423 auto audio_sender_1 = caller()->AddAudioTrack();
1424 auto video_sender_1 = caller()->AddVideoTrack();
1425 auto audio_sender_2 = caller()->AddAudioTrack();
1426 auto video_sender_2 = caller()->AddVideoTrack();
1427 caller()->CreateAndSetAndSignalOffer();
1428 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1429
1430 MediaExpectations media_expectations;
1431 media_expectations.CalleeExpectsSomeAudioAndVideo();
1432 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1433
1434 std::vector<std::string> track_ids = {
1435 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1436 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1437
1438 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
1439 caller()->NewGetStats();
1440 ASSERT_TRUE(caller_report);
1441 auto outbound_stream_stats =
1442 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02001443 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08001444 std::vector<std::string> outbound_track_ids;
1445 for (const auto& stat : outbound_stream_stats) {
1446 ASSERT_TRUE(stat->bytes_sent.is_defined());
1447 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001448 if (*stat->kind == "video") {
1449 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
1450 EXPECT_GT(*stat->key_frames_encoded, 0u);
1451 ASSERT_TRUE(stat->frames_encoded.is_defined());
1452 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
1453 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001454 ASSERT_TRUE(stat->track_id.is_defined());
1455 const auto* track_stat =
1456 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1457 ASSERT_TRUE(track_stat);
1458 outbound_track_ids.push_back(*track_stat->track_identifier);
1459 }
1460 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
1461
1462 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
1463 callee()->NewGetStats();
1464 ASSERT_TRUE(callee_report);
1465 auto inbound_stream_stats =
1466 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1467 ASSERT_EQ(4u, inbound_stream_stats.size());
1468 std::vector<std::string> inbound_track_ids;
1469 for (const auto& stat : inbound_stream_stats) {
1470 ASSERT_TRUE(stat->bytes_received.is_defined());
1471 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001472 if (*stat->kind == "video") {
1473 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
1474 EXPECT_GT(*stat->key_frames_decoded, 0u);
1475 ASSERT_TRUE(stat->frames_decoded.is_defined());
1476 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
1477 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001478 ASSERT_TRUE(stat->track_id.is_defined());
1479 const auto* track_stat =
1480 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1481 ASSERT_TRUE(track_stat);
1482 inbound_track_ids.push_back(*track_stat->track_identifier);
1483 }
1484 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
1485}
1486
1487// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07001488// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
1489// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001490TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07001491 GetStatsForUnsignaledStreamWithNewStatsApi) {
1492 ASSERT_TRUE(CreatePeerConnectionWrappers());
1493 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001494 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07001495 // Remove SSRCs and MSIDs from the received offer SDP.
1496 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1497 caller()->CreateAndSetAndSignalOffer();
1498 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001499 MediaExpectations media_expectations;
1500 media_expectations.CalleeExpectsSomeAudio(1);
1501 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07001502
1503 // We received a frame, so we should have nonzero "bytes received" stats for
1504 // the unsignaled stream, if stats are working for it.
1505 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1506 callee()->NewGetStats();
1507 ASSERT_NE(nullptr, report);
1508 auto inbound_stream_stats =
1509 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1510 ASSERT_EQ(1U, inbound_stream_stats.size());
1511 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
1512 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07001513 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
1514}
1515
Taylor Brandstettera4653442018-06-19 09:44:26 -07001516// Same as above but for the legacy stats implementation.
1517TEST_P(PeerConnectionIntegrationTest,
1518 GetStatsForUnsignaledStreamWithOldStatsApi) {
1519 ASSERT_TRUE(CreatePeerConnectionWrappers());
1520 ConnectFakeSignaling();
1521 caller()->AddAudioTrack();
1522 // Remove SSRCs and MSIDs from the received offer SDP.
1523 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1524 caller()->CreateAndSetAndSignalOffer();
1525 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1526
1527 // Note that, since the old stats implementation associates SSRCs with tracks
1528 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
1529 // associated track ID. So we can't use the track "selector" argument.
1530 //
1531 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
1532 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001533 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07001534 kDefaultTimeout);
1535}
1536
zhihuangf8164932017-05-19 13:09:47 -07001537// Test that we can successfully get the media related stats (audio level
1538// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001539TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07001540 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
1541 ASSERT_TRUE(CreatePeerConnectionWrappers());
1542 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001543 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07001544 // Remove SSRCs and MSIDs from the received offer SDP.
1545 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1546 caller()->CreateAndSetAndSignalOffer();
1547 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001548 MediaExpectations media_expectations;
1549 media_expectations.CalleeExpectsSomeAudio(1);
1550 media_expectations.CalleeExpectsSomeVideo(1);
1551 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07001552
1553 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1554 callee()->NewGetStats();
1555 ASSERT_NE(nullptr, report);
1556
1557 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1558 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
1559 ASSERT_GE(audio_index, 0);
1560 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07001561}
1562
deadbeef4e2deab2017-09-20 13:56:21 -07001563// Helper for test below.
1564void ModifySsrcs(cricket::SessionDescription* desc) {
1565 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07001566 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08001567 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07001568 for (uint32_t& ssrc : stream.ssrcs) {
1569 ssrc = rtc::CreateRandomId();
1570 }
1571 }
1572 }
1573}
1574
1575// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
1576// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
1577// This should result in two "RTCInboundRTPStreamStats", but only one
1578// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
1579// being reset to 0 once the SSRC change occurs.
1580//
1581// Regression test for this bug:
1582// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
1583//
1584// The bug causes the track stats to only represent one of the two streams:
1585// whichever one has the higher SSRC. So with this bug, there was a 50% chance
1586// that the track stat counters would reset to 0 when the new stream is
1587// received, and a 50% chance that they'll stop updating (while
1588// "concealed_samples" continues increasing, due to silence being generated for
1589// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001590TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08001591 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07001592 ASSERT_TRUE(CreatePeerConnectionWrappers());
1593 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001594 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07001595 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
1596 // that doesn't signal SSRCs (from the callee's perspective).
1597 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1598 caller()->CreateAndSetAndSignalOffer();
1599 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1600 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001601 {
1602 MediaExpectations media_expectations;
1603 media_expectations.CalleeExpectsSomeAudio(50);
1604 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1605 }
deadbeef4e2deab2017-09-20 13:56:21 -07001606 // Some audio frames were received, so we should have nonzero "samples
1607 // received" for the track.
1608 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1609 callee()->NewGetStats();
1610 ASSERT_NE(nullptr, report);
1611 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1612 ASSERT_EQ(1U, track_stats.size());
1613 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1614 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
1615 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
1616
1617 // Create a new offer and munge it to cause the caller to use a new SSRC.
1618 caller()->SetGeneratedSdpMunger(ModifySsrcs);
1619 caller()->CreateAndSetAndSignalOffer();
1620 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1621 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
1622 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001623 {
1624 MediaExpectations media_expectations;
1625 media_expectations.CalleeExpectsSomeAudio(25);
1626 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1627 }
deadbeef4e2deab2017-09-20 13:56:21 -07001628
1629 report = callee()->NewGetStats();
1630 ASSERT_NE(nullptr, report);
1631 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1632 ASSERT_EQ(1U, track_stats.size());
1633 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1634 // The "total samples received" stat should only be greater than it was
1635 // before.
1636 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
1637 // Right now, the new SSRC will cause the counters to reset to 0.
1638 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
1639
1640 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08001641 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07001642 // good sign that we're seeing stats from the old stream that's no longer
1643 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08001644 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07001645 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
1646 EXPECT_LT(*track_stats[0]->concealed_samples,
1647 *track_stats[0]->total_samples_received *
1648 kAcceptableConcealedSamplesPercentage);
1649
1650 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
1651 // sanity check that the SSRC really changed.
1652 // TODO(deadbeef): This isn't working right now, because we're not returning
1653 // *any* stats for the inactive stream. Uncomment when the bug is completely
1654 // fixed.
1655 // auto inbound_stream_stats =
1656 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1657 // ASSERT_EQ(2U, inbound_stream_stats.size());
1658}
1659
deadbeef1dcb1642017-03-29 21:08:16 -07001660// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001661TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001662 PeerConnectionFactory::Options dtls_10_options;
1663 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1664 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1665 dtls_10_options));
1666 ConnectFakeSignaling();
1667 // Do normal offer/answer and wait for some frames to be received in each
1668 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001669 caller()->AddAudioVideoTracks();
1670 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001671 caller()->CreateAndSetAndSignalOffer();
1672 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001673 MediaExpectations media_expectations;
1674 media_expectations.ExpectBidirectionalAudioAndVideo();
1675 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001676}
1677
1678// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001679TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001680 PeerConnectionFactory::Options dtls_10_options;
1681 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1682 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1683 dtls_10_options));
1684 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001685 caller()->AddAudioVideoTracks();
1686 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001687 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001688 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001689 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001690 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001691 kDefaultTimeout);
1692 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001693 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001694 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001695 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1696 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1697 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001698}
1699
1700// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001701TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001702 PeerConnectionFactory::Options dtls_12_options;
1703 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1704 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
1705 dtls_12_options));
1706 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001707 caller()->AddAudioVideoTracks();
1708 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001709 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001710 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001711 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001712 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001713 kDefaultTimeout);
1714 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001715 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001716 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001717 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1718 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1719 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001720}
1721
1722// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
1723// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001724TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001725 PeerConnectionFactory::Options caller_options;
1726 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1727 PeerConnectionFactory::Options callee_options;
1728 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1729 ASSERT_TRUE(
1730 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1731 ConnectFakeSignaling();
1732 // Do normal offer/answer and wait for some frames to be received in each
1733 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001734 caller()->AddAudioVideoTracks();
1735 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001736 caller()->CreateAndSetAndSignalOffer();
1737 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001738 MediaExpectations media_expectations;
1739 media_expectations.ExpectBidirectionalAudioAndVideo();
1740 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001741}
1742
1743// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
1744// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001745TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07001746 PeerConnectionFactory::Options caller_options;
1747 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1748 PeerConnectionFactory::Options callee_options;
1749 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1750 ASSERT_TRUE(
1751 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1752 ConnectFakeSignaling();
1753 // Do normal offer/answer and wait for some frames to be received in each
1754 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001755 caller()->AddAudioVideoTracks();
1756 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001757 caller()->CreateAndSetAndSignalOffer();
1758 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001759 MediaExpectations media_expectations;
1760 media_expectations.ExpectBidirectionalAudioAndVideo();
1761 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001762}
1763
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001764// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
1765// works as expected; the cipher should only be used if enabled by both sides.
1766TEST_P(PeerConnectionIntegrationTest,
1767 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
1768 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001769 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001770 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001771 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1772 false;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001773 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001774 TestNegotiatedCipherSuite(caller_options, callee_options,
1775 expected_cipher_suite);
1776}
1777
1778TEST_P(PeerConnectionIntegrationTest,
1779 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
1780 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001781 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1782 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001783 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001784 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001785 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001786 TestNegotiatedCipherSuite(caller_options, callee_options,
1787 expected_cipher_suite);
1788}
1789
1790TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
1791 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001792 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001793 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001794 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001795 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_32;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001796 TestNegotiatedCipherSuite(caller_options, callee_options,
1797 expected_cipher_suite);
1798}
1799
deadbeef1dcb1642017-03-29 21:08:16 -07001800// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001801TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001802 bool local_gcm_enabled = false;
1803 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001804 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07001805 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
1806 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001807 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001808}
1809
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001810// Test that a GCM cipher is used if both ends support it and non-GCM is
1811// disabled.
1812TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001813 bool local_gcm_enabled = true;
1814 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001815 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07001816 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
1817 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001818 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001819}
1820
deadbeef7914b8c2017-04-21 03:23:33 -07001821// Verify that media can be transmitted end-to-end when GCM crypto suites are
1822// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
1823// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
1824// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001825TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07001826 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001827 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001828 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07001829 ASSERT_TRUE(
1830 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
1831 ConnectFakeSignaling();
1832 // Do normal offer/answer and wait for some frames to be received in each
1833 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001834 caller()->AddAudioVideoTracks();
1835 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07001836 caller()->CreateAndSetAndSignalOffer();
1837 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001838 MediaExpectations media_expectations;
1839 media_expectations.ExpectBidirectionalAudioAndVideo();
1840 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07001841}
1842
deadbeef1dcb1642017-03-29 21:08:16 -07001843// Test that the ICE connection and gathering states eventually reach
1844// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08001845TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07001846 ASSERT_TRUE(CreatePeerConnectionWrappers());
1847 ConnectFakeSignaling();
1848 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001849 caller()->AddAudioVideoTracks();
1850 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001851 caller()->CreateAndSetAndSignalOffer();
1852 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1853 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1854 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
1855 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1856 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
1857 // After the best candidate pair is selected and all candidates are signaled,
1858 // the ICE connection state should reach "complete".
1859 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
1860 // answerer/"callee" by default) only reaches "connected". When this is
1861 // fixed, this test should be updated.
1862 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1863 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00001864 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1865 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001866}
1867
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001868#if !defined(THREAD_SANITIZER)
1869// This test provokes TSAN errors. See bugs.webrtc.org/3608
1870
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001871constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1872 cricket::PORTALLOCATOR_DISABLE_RELAY |
1873 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001874
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001875// Use a mock resolver to resolve the hostname back to the original IP on both
1876// sides and check that the ICE connection connects.
Markus Handell56910532021-04-10 11:23:14 +00001877// TODO(bugs.webrtc.org/12590): Flaky on Windows and on Linux MSAN.
1878#if defined(WEBRTC_WIN) || defined(WEBRTC_LINUX)
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001879#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1880 DISABLED_IceStatesReachCompletionWithRemoteHostname
1881#else
1882#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1883 IceStatesReachCompletionWithRemoteHostname
1884#endif
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001885TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001886 MAYBE_IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001887 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001888 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001889 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001890 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001891 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1892 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001893
1894 // This also verifies that the injected AsyncResolverFactory is used by
1895 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001896 EXPECT_CALL(*caller_resolver_factory, Create())
1897 .WillOnce(Return(&caller_async_resolver));
1898 webrtc::PeerConnectionDependencies caller_deps(nullptr);
1899 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1900
1901 EXPECT_CALL(*callee_resolver_factory, Create())
1902 .WillOnce(Return(&callee_async_resolver));
1903 webrtc::PeerConnectionDependencies callee_deps(nullptr);
1904 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1905
1906 PeerConnectionInterface::RTCConfiguration config;
1907 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1908 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1909
1910 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1911 config, std::move(caller_deps), config, std::move(callee_deps)));
1912
1913 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1914 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1915
1916 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07001917 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001918 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07001919 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001920 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001921
1922 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001923
1924 ConnectFakeSignaling();
1925 caller()->AddAudioVideoTracks();
1926 callee()->AddAudioVideoTracks();
1927 caller()->CreateAndSetAndSignalOffer();
1928 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1929 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1930 caller()->ice_connection_state(), kDefaultTimeout);
1931 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1932 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08001933
Ying Wangef3998f2019-12-09 13:06:53 +01001934 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1935 "WebRTC.PeerConnection.CandidatePairType_UDP",
1936 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001937}
1938
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001939#endif // !defined(THREAD_SANITIZER)
1940
Steve Antonede9ca52017-10-16 13:04:27 -07001941// Test that firewalling the ICE connection causes the clients to identify the
1942// disconnected state and then removing the firewall causes them to reconnect.
1943class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08001944 : public PeerConnectionIntegrationBaseTest,
1945 public ::testing::WithParamInterface<
1946 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07001947 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001948 PeerConnectionIntegrationIceStatesTest()
1949 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1950 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07001951 }
1952
1953 void StartStunServer(const SocketAddress& server_address) {
1954 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01001955 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07001956 }
1957
1958 bool TestIPv6() {
1959 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1960 }
1961
1962 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001963 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1964 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07001965 }
1966
1967 std::vector<SocketAddress> CallerAddresses() {
1968 std::vector<SocketAddress> addresses;
1969 addresses.push_back(SocketAddress("1.1.1.1", 0));
1970 if (TestIPv6()) {
1971 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1972 }
1973 return addresses;
1974 }
1975
1976 std::vector<SocketAddress> CalleeAddresses() {
1977 std::vector<SocketAddress> addresses;
1978 addresses.push_back(SocketAddress("2.2.2.2", 0));
1979 if (TestIPv6()) {
1980 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1981 }
1982 return addresses;
1983 }
1984
1985 void SetUpNetworkInterfaces() {
1986 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07001987 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1988 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07001989
1990 // Add network addresses for test.
1991 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001992 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001993 }
1994 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001995 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001996 }
1997 }
1998
1999 private:
2000 uint32_t port_allocator_flags_;
2001 std::unique_ptr<cricket::TestStunServer> stun_server_;
2002};
2003
Yves Gerey100fe632020-01-17 19:15:53 +01002004// Ensure FakeClockForTest is constructed first (see class for rationale).
2005class PeerConnectionIntegrationIceStatesTestWithFakeClock
2006 : public FakeClockForTest,
2007 public PeerConnectionIntegrationIceStatesTest {};
2008
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002009#if !defined(THREAD_SANITIZER)
2010// This test provokes TSAN errors. bugs.webrtc.org/11282
2011
Steve Antonede9ca52017-10-16 13:04:27 -07002012// Tests that the PeerConnection goes through all the ICE gathering/connection
2013// states over the duration of the call. This includes Disconnected and Failed
2014// states, induced by putting a firewall between the peers and waiting for them
2015// to time out.
Yves Gerey100fe632020-01-17 19:15:53 +01002016TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) {
Steve Antonede9ca52017-10-16 13:04:27 -07002017 const SocketAddress kStunServerAddress =
2018 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
2019 StartStunServer(kStunServerAddress);
2020
2021 PeerConnectionInterface::RTCConfiguration config;
2022 PeerConnectionInterface::IceServer ice_stun_server;
2023 ice_stun_server.urls.push_back(
2024 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
2025 kStunServerAddress.PortAsString());
2026 config.servers.push_back(ice_stun_server);
2027
2028 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2029 ConnectFakeSignaling();
2030 SetPortAllocatorFlags();
2031 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08002032 caller()->AddAudioVideoTracks();
2033 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002034
2035 // Initial state before anything happens.
2036 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
2037 caller()->ice_gathering_state());
2038 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
2039 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01002040 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
2041 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07002042
2043 // Start the call by creating the offer, setting it as the local description,
2044 // then sending it to the peer who will respond with an answer. This happens
2045 // asynchronously so that we can watch the states as it runs in the
2046 // background.
2047 caller()->CreateAndSetAndSignalOffer();
2048
Steve Antona9b67ce2020-01-16 14:00:44 -08002049 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2050 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002051 FakeClock());
Steve Antona9b67ce2020-01-16 14:00:44 -08002052 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2053 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002054 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002055
2056 // Verify that the observer was notified of the intermediate transitions.
2057 EXPECT_THAT(caller()->ice_connection_state_history(),
2058 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
2059 PeerConnectionInterface::kIceConnectionConnected,
2060 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olssonacd8ae72019-02-25 15:26:24 +01002061 EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
2062 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
2063 PeerConnectionInterface::kIceConnectionConnected,
2064 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02002065 EXPECT_THAT(
2066 caller()->peer_connection_state_history(),
2067 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02002068 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07002069 EXPECT_THAT(caller()->ice_gathering_state_history(),
2070 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
2071 PeerConnectionInterface::kIceGatheringComplete));
2072
2073 // Block connections to/from the caller and wait for ICE to become
2074 // disconnected.
2075 for (const auto& caller_address : CallerAddresses()) {
2076 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2077 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01002078 RTC_LOG(LS_INFO) << "Firewall rules applied";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002079 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2080 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002081 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002082 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2083 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002084 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002085
2086 // Let ICE re-establish by removing the firewall rules.
2087 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01002088 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002089 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2090 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002091 FakeClock());
Jonas Olssonacd8ae72019-02-25 15:26:24 +01002092 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002093 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002094 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002095
2096 // According to RFC7675, if there is no response within 30 seconds then the
2097 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08002098 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07002099 constexpr int kConsentTimeout = 30000;
2100 for (const auto& caller_address : CallerAddresses()) {
2101 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2102 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01002103 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002104 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2105 caller()->ice_connection_state(), kConsentTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002106 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002107 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2108 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002109 kConsentTimeout, FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002110}
2111
2112// Tests that if the connection doesn't get set up properly we eventually reach
2113// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01002114TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
2115 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002116 // Block connections to/from the caller and wait for ICE to become
2117 // disconnected.
2118 for (const auto& caller_address : CallerAddresses()) {
2119 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2120 }
2121
2122 ASSERT_TRUE(CreatePeerConnectionWrappers());
2123 ConnectFakeSignaling();
2124 SetPortAllocatorFlags();
2125 SetUpNetworkInterfaces();
2126 caller()->AddAudioVideoTracks();
2127 caller()->CreateAndSetAndSignalOffer();
2128
2129 // According to RFC7675, if there is no response within 30 seconds then the
2130 // peer should consider the other side to have rejected the connection. This
2131 // is signaled by the state transitioning to "failed".
2132 constexpr int kConsentTimeout = 30000;
2133 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2134 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002135 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002136}
2137
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002138#endif // !defined(THREAD_SANITIZER)
2139
Steve Antonede9ca52017-10-16 13:04:27 -07002140// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
2141// and that the statistics in the metric observers are updated correctly.
Rasmus Brandt32af25b2021-03-17 13:40:21 +01002142// TODO(bugs.webrtc.org/12591): Flaky on Windows.
2143#if defined(WEBRTC_WIN)
2144#define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
2145#else
2146#define MAYBE_VerifyBestConnection VerifyBestConnection
2147#endif
2148TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
Steve Antonede9ca52017-10-16 13:04:27 -07002149 ASSERT_TRUE(CreatePeerConnectionWrappers());
2150 ConnectFakeSignaling();
2151 SetPortAllocatorFlags();
2152 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08002153 caller()->AddAudioVideoTracks();
2154 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002155 caller()->CreateAndSetAndSignalOffer();
2156
2157 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08002158 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2159 caller()->ice_connection_state(), kDefaultTimeout);
2160 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2161 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07002162
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002163 // TODO(bugs.webrtc.org/9456): Fix it.
2164 const int num_best_ipv4 = webrtc::metrics::NumEvents(
2165 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
2166 const int num_best_ipv6 = webrtc::metrics::NumEvents(
2167 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002168 if (TestIPv6()) {
2169 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
2170 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01002171 EXPECT_METRIC_EQ(0, num_best_ipv4);
2172 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002173 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01002174 EXPECT_METRIC_EQ(1, num_best_ipv4);
2175 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002176 }
2177
Ying Wangef3998f2019-12-09 13:06:53 +01002178 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
2179 "WebRTC.PeerConnection.CandidatePairType_UDP",
2180 webrtc::kIceCandidatePairHostHost));
2181 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
2182 "WebRTC.PeerConnection.CandidatePairType_UDP",
2183 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07002184}
2185
2186constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
2187 cricket::PORTALLOCATOR_DISABLE_STUN |
2188 cricket::PORTALLOCATOR_DISABLE_RELAY;
2189constexpr uint32_t kFlagsIPv6NoStun =
2190 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
2191 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
2192constexpr uint32_t kFlagsIPv4Stun =
2193 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
2194
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002195INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002196 PeerConnectionIntegrationTest,
2197 PeerConnectionIntegrationIceStatesTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02002198 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Seth Hampson2f0d7022018-02-20 11:54:42 -08002199 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2200 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2201 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07002202
Yves Gerey100fe632020-01-17 19:15:53 +01002203INSTANTIATE_TEST_SUITE_P(
2204 PeerConnectionIntegrationTest,
2205 PeerConnectionIntegrationIceStatesTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02002206 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Yves Gerey100fe632020-01-17 19:15:53 +01002207 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2208 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2209 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2210
deadbeef1dcb1642017-03-29 21:08:16 -07002211// This test sets up a call between two parties with audio and video.
2212// During the call, the caller restarts ICE and the test verifies that
2213// new ICE candidates are generated and audio and video still can flow, and the
2214// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002215TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07002216 ASSERT_TRUE(CreatePeerConnectionWrappers());
2217 ConnectFakeSignaling();
2218 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08002219 caller()->AddAudioVideoTracks();
2220 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002221 caller()->CreateAndSetAndSignalOffer();
2222 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2223 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2224 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002225 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2226 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07002227
2228 // To verify that the ICE restart actually occurs, get
2229 // ufrag/password/candidates before and after restart.
2230 // Create an SDP string of the first audio candidate for both clients.
2231 const webrtc::IceCandidateCollection* audio_candidates_caller =
2232 caller()->pc()->local_description()->candidates(0);
2233 const webrtc::IceCandidateCollection* audio_candidates_callee =
2234 callee()->pc()->local_description()->candidates(0);
2235 ASSERT_GT(audio_candidates_caller->count(), 0u);
2236 ASSERT_GT(audio_candidates_callee->count(), 0u);
2237 std::string caller_candidate_pre_restart;
2238 ASSERT_TRUE(
2239 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2240 std::string callee_candidate_pre_restart;
2241 ASSERT_TRUE(
2242 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2243 const cricket::SessionDescription* desc =
2244 caller()->pc()->local_description()->description();
2245 std::string caller_ufrag_pre_restart =
2246 desc->transport_infos()[0].description.ice_ufrag;
2247 desc = callee()->pc()->local_description()->description();
2248 std::string callee_ufrag_pre_restart =
2249 desc->transport_infos()[0].description.ice_ufrag;
2250
Alex Drake00c7ecf2019-08-06 10:54:47 -07002251 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002252 // Have the caller initiate an ICE restart.
2253 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2254 caller()->CreateAndSetAndSignalOffer();
2255 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2256 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2257 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002258 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07002259 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2260
2261 // Grab the ufrags/candidates again.
2262 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2263 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2264 ASSERT_GT(audio_candidates_caller->count(), 0u);
2265 ASSERT_GT(audio_candidates_callee->count(), 0u);
2266 std::string caller_candidate_post_restart;
2267 ASSERT_TRUE(
2268 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2269 std::string callee_candidate_post_restart;
2270 ASSERT_TRUE(
2271 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2272 desc = caller()->pc()->local_description()->description();
2273 std::string caller_ufrag_post_restart =
2274 desc->transport_infos()[0].description.ice_ufrag;
2275 desc = callee()->pc()->local_description()->description();
2276 std::string callee_ufrag_post_restart =
2277 desc->transport_infos()[0].description.ice_ufrag;
2278 // Sanity check that an ICE restart was actually negotiated in SDP.
2279 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2280 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2281 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2282 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07002283 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002284
2285 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002286 MediaExpectations media_expectations;
2287 media_expectations.ExpectBidirectionalAudioAndVideo();
2288 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002289}
2290
2291// Verify that audio/video can be received end-to-end when ICE renomination is
2292// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002293TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07002294 PeerConnectionInterface::RTCConfiguration config;
2295 config.enable_ice_renomination = true;
2296 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2297 ConnectFakeSignaling();
2298 // Do normal offer/answer and wait for some frames to be received in each
2299 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002300 caller()->AddAudioVideoTracks();
2301 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002302 caller()->CreateAndSetAndSignalOffer();
2303 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2304 // Sanity check that ICE renomination was actually negotiated.
2305 const cricket::SessionDescription* desc =
2306 caller()->pc()->local_description()->description();
2307 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002308 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002309 }
2310 desc = callee()->pc()->local_description()->description();
2311 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002312 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002313 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08002314 MediaExpectations media_expectations;
2315 media_expectations.ExpectBidirectionalAudioAndVideo();
2316 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002317}
2318
Steve Anton6f25b092017-10-23 09:39:20 -07002319// With a max bundle policy and RTCP muxing, adding a new media description to
2320// the connection should not affect ICE at all because the new media will use
2321// the existing connection.
Rasmus Brandt685be142021-03-15 14:03:38 +01002322// TODO(bugs.webrtc.org/12538): Fails on tsan.
2323#if defined(THREAD_SANITIZER)
2324#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2325 DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2326#else
2327#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2328 AddMediaToConnectedBundleDoesNotRestartIce
2329#endif
Seth Hampson2f0d7022018-02-20 11:54:42 -08002330TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt685be142021-03-15 14:03:38 +01002331 MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07002332 PeerConnectionInterface::RTCConfiguration config;
2333 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2334 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2335 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2336 config, PeerConnectionInterface::RTCConfiguration()));
2337 ConnectFakeSignaling();
2338
Steve Anton15324772018-01-16 10:26:49 -08002339 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002340 caller()->CreateAndSetAndSignalOffer();
2341 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07002342 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2343 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07002344
2345 caller()->clear_ice_connection_state_history();
2346
Steve Anton15324772018-01-16 10:26:49 -08002347 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002348 caller()->CreateAndSetAndSignalOffer();
2349 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2350
2351 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2352}
2353
deadbeef1dcb1642017-03-29 21:08:16 -07002354// This test sets up a call between two parties with audio and video. It then
2355// renegotiates setting the video m-line to "port 0", then later renegotiates
2356// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002357TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002358 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2359 ASSERT_TRUE(CreatePeerConnectionWrappers());
2360 ConnectFakeSignaling();
2361
2362 // Do initial negotiation, only sending media from the caller. Will result in
2363 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08002364 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002365 caller()->CreateAndSetAndSignalOffer();
2366 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2367
2368 // Negotiate again, disabling the video "m=" section (the callee will set the
2369 // port to 0 due to offer_to_receive_video = 0).
Florent Castelli15a38de2022-04-06 00:38:21 +02002370 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002371 PeerConnectionInterface::RTCOfferAnswerOptions options;
2372 options.offer_to_receive_video = 0;
2373 callee()->SetOfferAnswerOptions(options);
2374 } else {
2375 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002376 callee()
2377 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2378 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002379 });
2380 }
deadbeef1dcb1642017-03-29 21:08:16 -07002381 caller()->CreateAndSetAndSignalOffer();
2382 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2383 // Sanity check that video "m=" section was actually rejected.
2384 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2385 callee()->pc()->local_description()->description());
2386 ASSERT_NE(nullptr, answer_video_content);
2387 ASSERT_TRUE(answer_video_content->rejected);
2388
2389 // Enable video and do negotiation again, making sure video is received
2390 // end-to-end, also adding media stream to callee.
Florent Castelli15a38de2022-04-06 00:38:21 +02002391 if (sdp_semantics_ == SdpSemantics::kPlanB_DEPRECATED) {
Seth Hampson2f0d7022018-02-20 11:54:42 -08002392 PeerConnectionInterface::RTCOfferAnswerOptions options;
2393 options.offer_to_receive_video = 1;
2394 callee()->SetOfferAnswerOptions(options);
2395 } else {
2396 // The caller's transceiver is stopped, so we need to add another track.
2397 auto caller_transceiver =
2398 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002399 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002400 caller()->AddVideoTrack();
2401 }
2402 callee()->AddVideoTrack();
2403 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07002404 caller()->CreateAndSetAndSignalOffer();
2405 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002406
deadbeef1dcb1642017-03-29 21:08:16 -07002407 // Verify the caller receives frames from the newly added stream, and the
2408 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002409 MediaExpectations media_expectations;
2410 media_expectations.CalleeExpectsSomeAudio();
2411 media_expectations.ExpectBidirectionalVideo();
2412 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002413}
2414
deadbeef1dcb1642017-03-29 21:08:16 -07002415// This tests that if we negotiate after calling CreateSender but before we
2416// have a track, then set a track later, frames from the newly-set track are
2417// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002418TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07002419 MediaFlowsAfterEarlyWarmupWithCreateSender) {
2420 ASSERT_TRUE(CreatePeerConnectionWrappers());
2421 ConnectFakeSignaling();
2422 auto caller_audio_sender =
2423 caller()->pc()->CreateSender("audio", "caller_stream");
2424 auto caller_video_sender =
2425 caller()->pc()->CreateSender("video", "caller_stream");
2426 auto callee_audio_sender =
2427 callee()->pc()->CreateSender("audio", "callee_stream");
2428 auto callee_video_sender =
2429 callee()->pc()->CreateSender("video", "callee_stream");
2430 caller()->CreateAndSetAndSignalOffer();
2431 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2432 // Wait for ICE to complete, without any tracks being set.
2433 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2434 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2435 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2436 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2437 // Now set the tracks, and expect frames to immediately start flowing.
Niels Möllerafb246b2022-04-20 14:26:50 +02002438 EXPECT_TRUE(
2439 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2440 EXPECT_TRUE(
2441 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2442 EXPECT_TRUE(
2443 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2444 EXPECT_TRUE(
2445 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002446 MediaExpectations media_expectations;
2447 media_expectations.ExpectBidirectionalAudioAndVideo();
2448 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2449}
2450
2451// This tests that if we negotiate after calling AddTransceiver but before we
2452// have a track, then set a track later, frames from the newly-set tracks are
2453// received end-to-end.
2454TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2455 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2456 ASSERT_TRUE(CreatePeerConnectionWrappers());
2457 ConnectFakeSignaling();
2458 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2459 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2460 auto caller_audio_sender = audio_result.MoveValue()->sender();
2461 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2462 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2463 auto caller_video_sender = video_result.MoveValue()->sender();
2464 callee()->SetRemoteOfferHandler([this] {
2465 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02002466 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002467 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002468 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002469 RtpTransceiverDirection::kSendRecv);
2470 });
2471 caller()->CreateAndSetAndSignalOffer();
2472 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2473 // Wait for ICE to complete, without any tracks being set.
2474 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2475 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2476 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2477 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2478 // Now set the tracks, and expect frames to immediately start flowing.
2479 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2480 auto callee_video_sender = callee()->pc()->GetSenders()[1];
Niels Möllerafb246b2022-04-20 14:26:50 +02002481 ASSERT_TRUE(
2482 caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack().get()));
2483 ASSERT_TRUE(
2484 caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack().get()));
2485 ASSERT_TRUE(
2486 callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack().get()));
2487 ASSERT_TRUE(
2488 callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack().get()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002489 MediaExpectations media_expectations;
2490 media_expectations.ExpectBidirectionalAudioAndVideo();
2491 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002492}
2493
2494// This test verifies that a remote video track can be added via AddStream,
2495// and sent end-to-end. For this particular test, it's simply echoed back
2496// from the caller to the callee, rather than being forwarded to a third
2497// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002498TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07002499 ASSERT_TRUE(CreatePeerConnectionWrappers());
2500 ConnectFakeSignaling();
2501 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08002502 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002503 caller()->CreateAndSetAndSignalOffer();
2504 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002505 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07002506
2507 // Echo the stream back, and do a new offer/anwer (initiated by callee this
2508 // time).
2509 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2510 callee()->CreateAndSetAndSignalOffer();
2511 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2512
Seth Hampson2f0d7022018-02-20 11:54:42 -08002513 MediaExpectations media_expectations;
2514 media_expectations.ExpectBidirectionalVideo();
2515 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002516}
2517
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002518#if !defined(THREAD_SANITIZER)
2519// This test provokes TSAN errors. bugs.webrtc.org/11282
2520
deadbeef1dcb1642017-03-29 21:08:16 -07002521// Test that we achieve the expected end-to-end connection time, using a
2522// fake clock and simulated latency on the media and signaling paths.
2523// We use a TURN<->TURN connection because this is usually the quickest to
2524// set up initially, especially when we're confident the connection will work
2525// and can start sending media before we get a STUN response.
2526//
2527// With various optimizations enabled, here are the network delays we expect to
2528// be on the critical path:
2529// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2530// signaling answer (with DTLS fingerprint).
2531// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2532// using TURN<->TURN pair, and DTLS exchange is 4 packets,
2533// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01002534TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2535 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07002536 static constexpr int media_hop_delay_ms = 50;
2537 static constexpr int signaling_trip_delay_ms = 500;
2538 // For explanation of these values, see comment above.
2539 static constexpr int required_media_hops = 9;
2540 static constexpr int required_signaling_trips = 2;
2541 // For internal delays (such as posting an event asychronously).
2542 static constexpr int allowed_internal_delay_ms = 20;
2543 static constexpr int total_connection_time_ms =
2544 media_hop_delay_ms * required_media_hops +
2545 signaling_trip_delay_ms * required_signaling_trips +
2546 allowed_internal_delay_ms;
2547
2548 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2549 3478};
2550 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2551 0};
2552 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2553 3478};
2554 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2555 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002556 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2557 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002558
Seth Hampsonaed71642018-06-11 07:41:32 -07002559 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2560 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07002561 // Bypass permission check on received packets so media can be sent before
2562 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07002563 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
2564 turn_server_1->set_enable_permission_checks(false);
2565 });
2566 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
2567 turn_server_2->set_enable_permission_checks(false);
2568 });
deadbeef1dcb1642017-03-29 21:08:16 -07002569
2570 PeerConnectionInterface::RTCConfiguration client_1_config;
2571 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2572 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2573 ice_server_1.username = "test";
2574 ice_server_1.password = "test";
2575 client_1_config.servers.push_back(ice_server_1);
2576 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2577 client_1_config.presume_writable_when_fully_relayed = true;
2578
2579 PeerConnectionInterface::RTCConfiguration client_2_config;
2580 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2581 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2582 ice_server_2.username = "test";
2583 ice_server_2.password = "test";
2584 client_2_config.servers.push_back(ice_server_2);
2585 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2586 client_2_config.presume_writable_when_fully_relayed = true;
2587
2588 ASSERT_TRUE(
2589 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2590 // Set up the simulated delays.
2591 SetSignalingDelayMs(signaling_trip_delay_ms);
2592 ConnectFakeSignaling();
2593 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2594 virtual_socket_server()->UpdateDelayDistribution();
2595
2596 // Set "offer to receive audio/video" without adding any tracks, so we just
2597 // set up ICE/DTLS with no media.
2598 PeerConnectionInterface::RTCOfferAnswerOptions options;
2599 options.offer_to_receive_audio = 1;
2600 options.offer_to_receive_video = 1;
2601 caller()->SetOfferAnswerOptions(options);
2602 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07002603 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01002604 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002605 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2606 // If this is not done a DCHECK can be hit in ports.cc, because a large
2607 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07002608 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07002609}
2610
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002611#endif // !defined(THREAD_SANITIZER)
2612
Jonas Orelandbdcee282017-10-10 14:01:40 +02002613// Verify that a TurnCustomizer passed in through RTCConfiguration
2614// is actually used by the underlying TURN candidate pair.
2615// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002616TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02002617 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2618 3478};
2619 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2620 0};
2621 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2622 3478};
2623 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2624 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002625 CreateTurnServer(turn_server_1_internal_address,
2626 turn_server_1_external_address);
2627 CreateTurnServer(turn_server_2_internal_address,
2628 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002629
2630 PeerConnectionInterface::RTCConfiguration client_1_config;
2631 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2632 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2633 ice_server_1.username = "test";
2634 ice_server_1.password = "test";
2635 client_1_config.servers.push_back(ice_server_1);
2636 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002637 auto* customizer1 = CreateTurnCustomizer();
2638 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002639
2640 PeerConnectionInterface::RTCConfiguration client_2_config;
2641 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2642 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2643 ice_server_2.username = "test";
2644 ice_server_2.password = "test";
2645 client_2_config.servers.push_back(ice_server_2);
2646 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002647 auto* customizer2 = CreateTurnCustomizer();
2648 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002649
2650 ASSERT_TRUE(
2651 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2652 ConnectFakeSignaling();
2653
2654 // Set "offer to receive audio/video" without adding any tracks, so we just
2655 // set up ICE/DTLS with no media.
2656 PeerConnectionInterface::RTCOfferAnswerOptions options;
2657 options.offer_to_receive_audio = 1;
2658 options.offer_to_receive_video = 1;
2659 caller()->SetOfferAnswerOptions(options);
2660 caller()->CreateAndSetAndSignalOffer();
2661 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2662
Seth Hampsonaed71642018-06-11 07:41:32 -07002663 ExpectTurnCustomizerCountersIncremented(customizer1);
2664 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002665}
2666
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002667// Verifies that you can use TCP instead of UDP to connect to a TURN server and
2668// send media between the caller and the callee.
2669TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2670 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2671 3478};
2672 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2673
2674 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07002675 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2676 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002677
2678 webrtc::PeerConnectionInterface::IceServer ice_server;
2679 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2680 ice_server.username = "test";
2681 ice_server.password = "test";
2682
2683 PeerConnectionInterface::RTCConfiguration client_1_config;
2684 client_1_config.servers.push_back(ice_server);
2685 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2686
2687 PeerConnectionInterface::RTCConfiguration client_2_config;
2688 client_2_config.servers.push_back(ice_server);
2689 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2690
2691 ASSERT_TRUE(
2692 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2693
2694 // Do normal offer/answer and wait for ICE to complete.
2695 ConnectFakeSignaling();
2696 caller()->AddAudioVideoTracks();
2697 callee()->AddAudioVideoTracks();
2698 caller()->CreateAndSetAndSignalOffer();
2699 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2700 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2701 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2702
2703 MediaExpectations media_expectations;
2704 media_expectations.ExpectBidirectionalAudioAndVideo();
2705 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2706}
2707
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002708// Verify that a SSLCertificateVerifier passed in through
2709// PeerConnectionDependencies is actually used by the underlying SSL
2710// implementation to determine whether a certificate presented by the TURN
2711// server is accepted by the client. Note that openssladapter_unittest.cc
2712// contains more detailed, lower-level tests.
2713TEST_P(PeerConnectionIntegrationTest,
2714 SSLCertificateVerifierUsedForTurnConnections) {
2715 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2716 3478};
2717 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2718
2719 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2720 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002721 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2722 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002723
2724 webrtc::PeerConnectionInterface::IceServer ice_server;
2725 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2726 ice_server.username = "test";
2727 ice_server.password = "test";
2728
2729 PeerConnectionInterface::RTCConfiguration client_1_config;
2730 client_1_config.servers.push_back(ice_server);
2731 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2732
2733 PeerConnectionInterface::RTCConfiguration client_2_config;
2734 client_2_config.servers.push_back(ice_server);
2735 // Setting the type to kRelay forces the connection to go through a TURN
2736 // server.
2737 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2738
2739 // Get a copy to the pointer so we can verify calls later.
2740 rtc::TestCertificateVerifier* client_1_cert_verifier =
2741 new rtc::TestCertificateVerifier();
2742 client_1_cert_verifier->verify_certificate_ = true;
2743 rtc::TestCertificateVerifier* client_2_cert_verifier =
2744 new rtc::TestCertificateVerifier();
2745 client_2_cert_verifier->verify_certificate_ = true;
2746
2747 // Create the dependencies with the test certificate verifier.
2748 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2749 client_1_deps.tls_cert_verifier =
2750 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2751 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2752 client_2_deps.tls_cert_verifier =
2753 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2754
2755 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2756 client_1_config, std::move(client_1_deps), client_2_config,
2757 std::move(client_2_deps)));
2758 ConnectFakeSignaling();
2759
2760 // Set "offer to receive audio/video" without adding any tracks, so we just
2761 // set up ICE/DTLS with no media.
2762 PeerConnectionInterface::RTCOfferAnswerOptions options;
2763 options.offer_to_receive_audio = 1;
2764 options.offer_to_receive_video = 1;
2765 caller()->SetOfferAnswerOptions(options);
2766 caller()->CreateAndSetAndSignalOffer();
2767 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2768
2769 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2770 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002771}
2772
2773TEST_P(PeerConnectionIntegrationTest,
2774 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
2775 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2776 3478};
2777 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2778
2779 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2780 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002781 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2782 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002783
2784 webrtc::PeerConnectionInterface::IceServer ice_server;
2785 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2786 ice_server.username = "test";
2787 ice_server.password = "test";
2788
2789 PeerConnectionInterface::RTCConfiguration client_1_config;
2790 client_1_config.servers.push_back(ice_server);
2791 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2792
2793 PeerConnectionInterface::RTCConfiguration client_2_config;
2794 client_2_config.servers.push_back(ice_server);
2795 // Setting the type to kRelay forces the connection to go through a TURN
2796 // server.
2797 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2798
2799 // Get a copy to the pointer so we can verify calls later.
2800 rtc::TestCertificateVerifier* client_1_cert_verifier =
2801 new rtc::TestCertificateVerifier();
2802 client_1_cert_verifier->verify_certificate_ = false;
2803 rtc::TestCertificateVerifier* client_2_cert_verifier =
2804 new rtc::TestCertificateVerifier();
2805 client_2_cert_verifier->verify_certificate_ = false;
2806
2807 // Create the dependencies with the test certificate verifier.
2808 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2809 client_1_deps.tls_cert_verifier =
2810 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2811 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2812 client_2_deps.tls_cert_verifier =
2813 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2814
2815 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2816 client_1_config, std::move(client_1_deps), client_2_config,
2817 std::move(client_2_deps)));
2818 ConnectFakeSignaling();
2819
2820 // Set "offer to receive audio/video" without adding any tracks, so we just
2821 // set up ICE/DTLS with no media.
2822 PeerConnectionInterface::RTCOfferAnswerOptions options;
2823 options.offer_to_receive_audio = 1;
2824 options.offer_to_receive_video = 1;
2825 caller()->SetOfferAnswerOptions(options);
2826 caller()->CreateAndSetAndSignalOffer();
2827 bool wait_res = true;
2828 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
2829 // properly, should be able to just wait for a state of "failed" instead of
2830 // waiting a fixed 10 seconds.
2831 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
2832 ASSERT_FALSE(wait_res);
2833
2834 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2835 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002836}
2837
Qingsi Wang25ec8882019-11-15 12:33:05 -08002838// Test that the injected ICE transport factory is used to create ICE transports
2839// for WebRTC connections.
2840TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2841 PeerConnectionInterface::RTCConfiguration default_config;
2842 PeerConnectionDependencies dependencies(nullptr);
2843 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2844 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2845 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02002846 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2847 std::move(dependencies), nullptr,
2848 /*reset_encoder_factory=*/false,
2849 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08002850 ASSERT_TRUE(wrapper);
2851 wrapper->CreateDataChannel();
Tommi87f70902021-04-27 14:43:08 +02002852 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02002853 wrapper->pc()->SetLocalDescription(observer.get(),
Qingsi Wang25ec8882019-11-15 12:33:05 -08002854 wrapper->CreateOfferAndWait().release());
2855}
2856
deadbeefc964d0b2017-04-03 10:03:35 -07002857// Test that audio and video flow end-to-end when codec names don't use the
2858// expected casing, given that they're supposed to be case insensitive. To test
2859// this, all but one codec is removed from each media description, and its
2860// casing is changed.
2861//
2862// In the past, this has regressed and caused crashes/black video, due to the
2863// fact that code at some layers was doing case-insensitive comparisons and
2864// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002865TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07002866 ASSERT_TRUE(CreatePeerConnectionWrappers());
2867 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002868 caller()->AddAudioVideoTracks();
2869 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07002870
2871 // Remove all but one audio/video codec (opus and VP8), and change the
2872 // casing of the caller's generated offer.
2873 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2874 cricket::AudioContentDescription* audio =
2875 GetFirstAudioContentDescription(description);
2876 ASSERT_NE(nullptr, audio);
2877 auto audio_codecs = audio->codecs();
2878 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2879 [](const cricket::AudioCodec& codec) {
2880 return codec.name != "opus";
2881 }),
2882 audio_codecs.end());
2883 ASSERT_EQ(1u, audio_codecs.size());
2884 audio_codecs[0].name = "OpUs";
2885 audio->set_codecs(audio_codecs);
2886
2887 cricket::VideoContentDescription* video =
2888 GetFirstVideoContentDescription(description);
2889 ASSERT_NE(nullptr, video);
2890 auto video_codecs = video->codecs();
2891 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2892 [](const cricket::VideoCodec& codec) {
2893 return codec.name != "VP8";
2894 }),
2895 video_codecs.end());
2896 ASSERT_EQ(1u, video_codecs.size());
2897 video_codecs[0].name = "vP8";
2898 video->set_codecs(video_codecs);
2899 });
2900
2901 caller()->CreateAndSetAndSignalOffer();
2902 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2903
2904 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002905 MediaExpectations media_expectations;
2906 media_expectations.ExpectBidirectionalAudioAndVideo();
2907 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07002908}
2909
Jonas Oreland49ac5952018-09-26 16:04:32 +02002910TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07002911 ASSERT_TRUE(CreatePeerConnectionWrappers());
2912 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002913 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07002914 caller()->CreateAndSetAndSignalOffer();
2915 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07002916 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002917 MediaExpectations media_expectations;
2918 media_expectations.CalleeExpectsSomeAudio(1);
2919 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02002920 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07002921 auto receiver = callee()->pc()->GetReceivers()[0];
2922 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002923 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07002924 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2925 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02002926 sources[0].source_id());
2927 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2928}
2929
2930TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2931 ASSERT_TRUE(CreatePeerConnectionWrappers());
2932 ConnectFakeSignaling();
2933 caller()->AddVideoTrack();
2934 caller()->CreateAndSetAndSignalOffer();
2935 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2936 // Wait for one video frame to be received by the callee.
2937 MediaExpectations media_expectations;
2938 media_expectations.CalleeExpectsSomeVideo(1);
2939 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2940 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2941 auto receiver = callee()->pc()->GetReceivers()[0];
2942 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2943 auto sources = receiver->GetSources();
2944 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02002945 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002946 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2947 sources[0].source_id());
2948 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07002949}
2950
deadbeef2f425aa2017-04-14 10:41:32 -07002951// Test that if a track is removed and added again with a different stream ID,
2952// the new stream ID is successfully communicated in SDP and media continues to
2953// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002954// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2955// it will not reuse a transceiver that has already been sending. After creating
2956// a new transceiver it tries to create an offer with two senders of the same
2957// track ids and it fails.
2958TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07002959 ASSERT_TRUE(CreatePeerConnectionWrappers());
2960 ConnectFakeSignaling();
2961
deadbeef2f425aa2017-04-14 10:41:32 -07002962 // Add track using stream 1, do offer/answer.
2963 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2964 caller()->CreateLocalAudioTrack();
2965 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07002966 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07002967 caller()->CreateAndSetAndSignalOffer();
2968 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002969 {
2970 MediaExpectations media_expectations;
2971 media_expectations.CalleeExpectsSomeAudio(1);
2972 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2973 }
deadbeef2f425aa2017-04-14 10:41:32 -07002974 // Remove the sender, and create a new one with the new stream.
Harald Alvestrand93dd7632022-01-19 12:28:45 +00002975 caller()->pc()->RemoveTrackOrError(sender);
Steve Antond78323f2018-07-11 11:13:44 -07002976 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07002977 caller()->CreateAndSetAndSignalOffer();
2978 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2979 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002980 {
2981 MediaExpectations media_expectations;
2982 media_expectations.CalleeExpectsSomeAudio();
2983 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2984 }
deadbeef2f425aa2017-04-14 10:41:32 -07002985}
2986
Seth Hampson2f0d7022018-02-20 11:54:42 -08002987TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02002988 ASSERT_TRUE(CreatePeerConnectionWrappers());
2989 ConnectFakeSignaling();
2990
Mirko Bonadei317a1f02019-09-17 17:06:18 +02002991 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002992 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
2993 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02002994 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01002995 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2996 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02002997
Steve Anton15324772018-01-16 10:26:49 -08002998 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02002999 caller()->CreateAndSetAndSignalOffer();
3000 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3001}
3002
Steve Antonede9ca52017-10-16 13:04:27 -07003003// Test that if candidates are only signaled by applying full session
3004// descriptions (instead of using AddIceCandidate), the peers can connect to
3005// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003006TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07003007 ASSERT_TRUE(CreatePeerConnectionWrappers());
3008 // Each side will signal the session descriptions but not candidates.
3009 ConnectFakeSignalingForSdpOnly();
3010
3011 // Add audio video track and exchange the initial offer/answer with media
3012 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08003013 caller()->AddAudioVideoTracks();
3014 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003015 caller()->CreateAndSetAndSignalOffer();
3016
3017 // Wait for all candidates to be gathered on both the caller and callee.
3018 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
3019 caller()->ice_gathering_state(), kDefaultTimeout);
3020 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
3021 callee()->ice_gathering_state(), kDefaultTimeout);
3022
3023 // The candidates will now be included in the session description, so
3024 // signaling them will start the ICE connection.
3025 caller()->CreateAndSetAndSignalOffer();
3026 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3027
3028 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003029 MediaExpectations media_expectations;
3030 media_expectations.ExpectBidirectionalAudioAndVideo();
3031 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07003032}
3033
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00003034#if !defined(THREAD_SANITIZER)
3035// These tests provokes TSAN errors. See bugs.webrtc.org/11305.
3036
henrika5f6bf242017-11-01 11:06:56 +01003037// Test that SetAudioPlayout can be used to disable audio playout from the
3038// start, then later enable it. This may be useful, for example, if the caller
3039// needs to play a local ringtone until some event occurs, after which it
3040// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003041TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01003042 ASSERT_TRUE(CreatePeerConnectionWrappers());
3043 ConnectFakeSignaling();
3044
3045 // Set up audio-only call where audio playout is disabled on caller's side.
3046 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08003047 caller()->AddAudioTrack();
3048 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01003049 caller()->CreateAndSetAndSignalOffer();
3050 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3051
3052 // Pump messages for a second.
3053 WAIT(false, 1000);
3054 // Since audio playout is disabled, the caller shouldn't have received
3055 // anything (at the playout level, at least).
3056 EXPECT_EQ(0, caller()->audio_frames_received());
3057 // As a sanity check, make sure the callee (for which playout isn't disabled)
3058 // did still see frames on its audio level.
3059 ASSERT_GT(callee()->audio_frames_received(), 0);
3060
3061 // Enable playout again, and ensure audio starts flowing.
3062 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003063 MediaExpectations media_expectations;
3064 media_expectations.ExpectBidirectionalAudio();
3065 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01003066}
3067
Harald Alvestrand39993842021-02-17 09:05:31 +00003068double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
henrika5f6bf242017-11-01 11:06:56 +01003069 auto report = pc->NewGetStats();
3070 auto track_stats_list =
3071 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3072 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
3073 for (const auto* track_stats : track_stats_list) {
3074 if (track_stats->remote_source.is_defined() &&
3075 *track_stats->remote_source) {
3076 remote_track_stats = track_stats;
3077 break;
3078 }
3079 }
3080
3081 if (!remote_track_stats->total_audio_energy.is_defined()) {
3082 return 0.0;
3083 }
3084 return *remote_track_stats->total_audio_energy;
3085}
3086
3087// Test that if audio playout is disabled via the SetAudioPlayout() method, then
3088// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003089TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01003090 DisableAudioPlayoutStillGeneratesAudioStats) {
3091 ASSERT_TRUE(CreatePeerConnectionWrappers());
3092 ConnectFakeSignaling();
3093
3094 // Set up audio-only call where playout is disabled but audio-processing is
3095 // still active.
Steve Anton15324772018-01-16 10:26:49 -08003096 caller()->AddAudioTrack();
3097 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01003098 caller()->pc()->SetAudioPlayout(false);
3099
3100 caller()->CreateAndSetAndSignalOffer();
3101 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3102
3103 // Wait for the callee to receive audio stats.
3104 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
3105}
3106
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00003107#endif // !defined(THREAD_SANITIZER)
3108
henrika4f167df2017-11-01 14:45:55 +01003109// Test that SetAudioRecording can be used to disable audio recording from the
3110// start, then later enable it. This may be useful, for example, if the caller
3111// wants to ensure that no audio resources are active before a certain state
3112// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003113TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01003114 ASSERT_TRUE(CreatePeerConnectionWrappers());
3115 ConnectFakeSignaling();
3116
3117 // Set up audio-only call where audio recording is disabled on caller's side.
3118 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08003119 caller()->AddAudioTrack();
3120 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01003121 caller()->CreateAndSetAndSignalOffer();
3122 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3123
3124 // Pump messages for a second.
3125 WAIT(false, 1000);
3126 // Since caller has disabled audio recording, the callee shouldn't have
3127 // received anything.
3128 EXPECT_EQ(0, callee()->audio_frames_received());
3129 // As a sanity check, make sure the caller did still see frames on its
3130 // audio level since audio recording is enabled on the calle side.
3131 ASSERT_GT(caller()->audio_frames_received(), 0);
3132
3133 // Enable audio recording again, and ensure audio starts flowing.
3134 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003135 MediaExpectations media_expectations;
3136 media_expectations.ExpectBidirectionalAudio();
3137 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01003138}
3139
Qingsi Wang7685e862018-06-11 20:15:46 -07003140TEST_P(PeerConnectionIntegrationTest,
3141 IceEventsGeneratedAndLoggedInRtcEventLog) {
3142 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
3143 ConnectFakeSignaling();
3144 PeerConnectionInterface::RTCOfferAnswerOptions options;
3145 options.offer_to_receive_audio = 1;
3146 caller()->SetOfferAnswerOptions(options);
3147 caller()->CreateAndSetAndSignalOffer();
3148 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3149 ASSERT_NE(nullptr, caller()->event_log_factory());
3150 ASSERT_NE(nullptr, callee()->event_log_factory());
3151 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01003152 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07003153 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01003154 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07003155 ASSERT_NE(nullptr, caller_event_log);
3156 ASSERT_NE(nullptr, callee_event_log);
3157 int caller_ice_config_count = caller_event_log->GetEventCount(
3158 webrtc::RtcEvent::Type::IceCandidatePairConfig);
3159 int caller_ice_event_count = caller_event_log->GetEventCount(
3160 webrtc::RtcEvent::Type::IceCandidatePairEvent);
3161 int callee_ice_config_count = callee_event_log->GetEventCount(
3162 webrtc::RtcEvent::Type::IceCandidatePairConfig);
3163 int callee_ice_event_count = callee_event_log->GetEventCount(
3164 webrtc::RtcEvent::Type::IceCandidatePairEvent);
3165 EXPECT_LT(0, caller_ice_config_count);
3166 EXPECT_LT(0, caller_ice_event_count);
3167 EXPECT_LT(0, callee_ice_config_count);
3168 EXPECT_LT(0, callee_ice_event_count);
3169}
3170
Qingsi Wangc129c352019-04-18 10:41:58 -07003171TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07003172 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3173 3478};
3174 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3175
3176 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3177
3178 webrtc::PeerConnectionInterface::IceServer ice_server;
3179 ice_server.urls.push_back("turn:88.88.88.0:3478");
3180 ice_server.username = "test";
3181 ice_server.password = "test";
3182
3183 PeerConnectionInterface::RTCConfiguration caller_config;
3184 caller_config.servers.push_back(ice_server);
3185 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3186 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003187 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003188
3189 PeerConnectionInterface::RTCConfiguration callee_config;
3190 callee_config.servers.push_back(ice_server);
3191 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3192 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003193 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003194
3195 ASSERT_TRUE(
3196 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3197
3198 // Do normal offer/answer and wait for ICE to complete.
3199 ConnectFakeSignaling();
3200 caller()->AddAudioVideoTracks();
3201 callee()->AddAudioVideoTracks();
3202 caller()->CreateAndSetAndSignalOffer();
3203 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3204 // Since we are doing continual gathering, the ICE transport does not reach
3205 // kIceGatheringComplete (see
3206 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
3207 // kIceConnectionComplete.
3208 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3209 caller()->ice_connection_state(), kDefaultTimeout);
3210 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3211 callee()->ice_connection_state(), kDefaultTimeout);
3212 // Note that we cannot use the metric
Artem Titovcfea2182021-08-10 01:22:31 +02003213 // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
Qingsi Wangc129c352019-04-18 10:41:58 -07003214 // metric is only populated when we reach kIceConnectionComplete in the
3215 // current implementation.
3216 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3217 caller()->last_candidate_gathered().type());
3218 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3219 callee()->last_candidate_gathered().type());
3220
3221 // Loosen the caller's candidate filter.
3222 caller_config = caller()->pc()->GetConfiguration();
3223 caller_config.type = webrtc::PeerConnectionInterface::kAll;
3224 caller()->pc()->SetConfiguration(caller_config);
3225 // We should have gathered a new host candidate.
3226 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3227 caller()->last_candidate_gathered().type(), kDefaultTimeout);
3228
3229 // Loosen the callee's candidate filter.
3230 callee_config = callee()->pc()->GetConfiguration();
3231 callee_config.type = webrtc::PeerConnectionInterface::kAll;
3232 callee()->pc()->SetConfiguration(callee_config);
3233 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3234 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02003235
3236 // Create an offer and verify that it does not contain an ICE restart (i.e new
3237 // ice credentials).
3238 std::string caller_ufrag_pre_offer = caller()
3239 ->pc()
3240 ->local_description()
3241 ->description()
3242 ->transport_infos()[0]
3243 .description.ice_ufrag;
3244 caller()->CreateAndSetAndSignalOffer();
3245 std::string caller_ufrag_post_offer = caller()
3246 ->pc()
3247 ->local_description()
3248 ->description()
3249 ->transport_infos()[0]
3250 .description.ice_ufrag;
3251 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07003252}
3253
Eldar Relloda13ea22019-06-01 12:23:43 +03003254TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03003255 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3256 3478};
3257 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3258
3259 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3260
3261 webrtc::PeerConnectionInterface::IceServer ice_server;
3262 ice_server.urls.push_back("turn:88.88.88.0:3478");
3263 ice_server.username = "test";
3264 ice_server.password = "123";
3265
3266 PeerConnectionInterface::RTCConfiguration caller_config;
3267 caller_config.servers.push_back(ice_server);
3268 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3269 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3270
3271 PeerConnectionInterface::RTCConfiguration callee_config;
3272 callee_config.servers.push_back(ice_server);
3273 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3274 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3275
3276 ASSERT_TRUE(
3277 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3278
3279 // Do normal offer/answer and wait for ICE to complete.
3280 ConnectFakeSignaling();
3281 caller()->AddAudioVideoTracks();
3282 callee()->AddAudioVideoTracks();
3283 caller()->CreateAndSetAndSignalOffer();
3284 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3285 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3286 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3287 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02003288 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03003289}
3290
Eldar Rellofa8019c2020-05-14 11:59:33 +03003291TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3292 webrtc::PeerConnectionInterface::IceServer ice_server;
3293 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3294 ice_server.username = "test";
3295 ice_server.password = "test";
3296
3297 PeerConnectionInterface::RTCConfiguration caller_config;
3298 caller_config.servers.push_back(ice_server);
3299 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3300 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3301
3302 PeerConnectionInterface::RTCConfiguration callee_config;
3303 callee_config.servers.push_back(ice_server);
3304 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3305 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3306
3307 ASSERT_TRUE(
3308 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3309
3310 // Do normal offer/answer and wait for ICE to complete.
3311 ConnectFakeSignaling();
3312 caller()->AddAudioVideoTracks();
3313 callee()->AddAudioVideoTracks();
3314 caller()->CreateAndSetAndSignalOffer();
3315 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3316 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3317 EXPECT_EQ(caller()->error_event().address, "");
3318}
3319
Eldar Rello5ab79e62019-10-09 18:29:44 +03003320TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3321 AudioKeepsFlowingAfterImplicitRollback) {
3322 PeerConnectionInterface::RTCConfiguration config;
3323 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3324 config.enable_implicit_rollback = true;
3325 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3326 ConnectFakeSignaling();
3327 caller()->AddAudioTrack();
3328 callee()->AddAudioTrack();
3329 caller()->CreateAndSetAndSignalOffer();
3330 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3331 MediaExpectations media_expectations;
3332 media_expectations.ExpectBidirectionalAudio();
3333 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3334 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
3335 caller()->AddVideoTrack();
3336 callee()->AddVideoTrack();
Tommi87f70902021-04-27 14:43:08 +02003337 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003338 callee()->pc()->SetLocalDescription(observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003339 callee()->CreateOfferAndWait().release());
3340 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3341 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
3342 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3343 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3344}
3345
3346TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3347 ImplicitRollbackVisitsStableState) {
3348 RTCConfiguration config;
3349 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3350 config.enable_implicit_rollback = true;
3351
3352 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3353
Tommi87f70902021-04-27 14:43:08 +02003354 auto sld_observer =
3355 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +02003356 callee()->pc()->SetLocalDescription(sld_observer.get(),
Eldar Rello5ab79e62019-10-09 18:29:44 +03003357 callee()->CreateOfferAndWait().release());
3358 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3359 EXPECT_EQ(sld_observer->error(), "");
3360
Tommi87f70902021-04-27 14:43:08 +02003361 auto srd_observer =
3362 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003363 callee()->pc()->SetRemoteDescription(
Niels Möllerafb246b2022-04-20 14:26:50 +02003364 srd_observer.get(), caller()->CreateOfferAndWait().release());
Eldar Rello5ab79e62019-10-09 18:29:44 +03003365 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3366 EXPECT_EQ(srd_observer->error(), "");
3367
3368 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3369 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3370 PeerConnectionInterface::kStable,
3371 PeerConnectionInterface::kHaveRemoteOffer));
3372}
3373
Eldar Rellobd9c33a2020-10-01 17:52:45 +03003374TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3375 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3376 ASSERT_TRUE(CreatePeerConnectionWrappers());
3377 ConnectFakeSignaling();
3378 caller()->AddVideoTrack();
3379 callee()->AddVideoTrack();
3380 auto munger = [](cricket::SessionDescription* desc) {
3381 cricket::VideoContentDescription* video =
3382 GetFirstVideoContentDescription(desc);
3383 auto codecs = video->codecs();
3384 for (auto&& codec : codecs) {
3385 if (codec.name == "H264") {
3386 std::string value;
3387 // The parameter is not supposed to be present in SDP by default.
3388 EXPECT_FALSE(
3389 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3390 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3391 std::string(""));
3392 }
3393 }
3394 video->set_codecs(codecs);
3395 };
3396 // Munge local offer for SLD.
3397 caller()->SetGeneratedSdpMunger(munger);
3398 // Munge remote answer for SRD.
3399 caller()->SetReceivedSdpMunger(munger);
3400 caller()->CreateAndSetAndSignalOffer();
3401 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3402 // Observe that after munging the parameter is present in generated SDP.
3403 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3404 cricket::VideoContentDescription* video =
3405 GetFirstVideoContentDescription(desc);
3406 for (auto&& codec : video->codecs()) {
3407 if (codec.name == "H264") {
3408 std::string value;
3409 EXPECT_TRUE(
3410 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3411 }
3412 }
3413 });
3414 caller()->CreateOfferAndWait();
3415}
3416
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003417TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00003418 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003419 PeerConnectionInterface::RTCConfiguration config;
3420 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3421 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3422 ConnectFakeSignaling();
3423 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3424
3425 caller()->CreateAndSetAndSignalOffer();
3426 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3427 int current_size = caller()->pc()->GetTransceivers().size();
3428 // Add more tracks until we get close to having issues.
3429 // Issues have been seen at:
3430 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003431 // - 16 tracks on android_arm_dbg (flaky)
3432 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003433 // Double the number of tracks
3434 for (int i = 0; i < current_size; i++) {
3435 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3436 }
3437 current_size = caller()->pc()->GetTransceivers().size();
3438 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3439 auto start_time_ms = rtc::TimeMillis();
3440 caller()->CreateAndSetAndSignalOffer();
3441 // We want to stop when the time exceeds one second.
3442 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3443 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3444 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3445 ASSERT_GT(1000, elapsed_time_ms)
3446 << "Audio transceivers: Negotiation took too long after "
3447 << current_size << " tracks added";
3448 }
3449}
3450
3451TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3452 RenegotiateManyVideoTransceivers) {
3453 PeerConnectionInterface::RTCConfiguration config;
3454 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3455 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3456 ConnectFakeSignaling();
3457 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3458
3459 caller()->CreateAndSetAndSignalOffer();
3460 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3461 int current_size = caller()->pc()->GetTransceivers().size();
3462 // Add more tracks until we get close to having issues.
3463 // Issues have been seen at:
3464 // - 96 on a Linux workstation
3465 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3466 // - 32 on android_arm64_rel and linux_dbg bots
Harald Alvestrand785e23b2021-03-15 21:26:27 +00003467 // - 16 on Android 64 (Nexus 5x)
3468 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003469 // Double the number of tracks
3470 for (int i = 0; i < current_size; i++) {
3471 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3472 }
3473 current_size = caller()->pc()->GetTransceivers().size();
3474 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3475 auto start_time_ms = rtc::TimeMillis();
3476 caller()->CreateAndSetAndSignalOffer();
3477 // We want to stop when the time exceeds one second.
3478 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3479 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3480 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3481 ASSERT_GT(1000, elapsed_time_ms)
3482 << "Video transceivers: Negotiation took too long after "
3483 << current_size << " tracks added";
3484 }
3485}
3486
Harald Alvestrand94324f22021-01-13 12:31:53 +00003487TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3488 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3489 PeerConnectionInterface::RTCConfiguration config;
3490 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3491 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3492 ConnectFakeSignaling();
3493 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003494 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003495 caller()->CreateAndSetAndSignalOffer();
3496 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3497 // Wait until we can see the audio flowing.
3498 MediaExpectations media_expectations;
3499 media_expectations.CalleeExpectsSomeAudio();
3500 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3501
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003502 // Get the baseline numbers for audio_packets and audio_delay
3503 // in both directions.
3504 caller()->StartWatchingDelayStats();
3505 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003506
3507 int current_size = caller()->pc()->GetTransceivers().size();
3508 // Add more tracks until we get close to having issues.
3509 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003510 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00003511 // Double the number of tracks
3512 for (int i = 0; i < current_size; i++) {
3513 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3514 }
3515 current_size = caller()->pc()->GetTransceivers().size();
3516 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3517 auto start_time_ms = rtc::TimeMillis();
3518 caller()->CreateAndSetAndSignalOffer();
3519 // We want to stop when the time exceeds one second.
3520 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3521 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3522 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3523 // This is a guard against the test using excessive amounts of time.
3524 ASSERT_GT(5000, elapsed_time_ms)
3525 << "Video transceivers: Negotiation took too long after "
3526 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003527 caller()->UpdateDelayStats("caller reception", current_size);
3528 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00003529 }
3530}
3531
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003532INSTANTIATE_TEST_SUITE_P(
3533 PeerConnectionIntegrationTest,
3534 PeerConnectionIntegrationTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003535 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003536 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3537 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3538 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Steve Antond3679212018-01-17 17:41:02 -08003539
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003540INSTANTIATE_TEST_SUITE_P(
3541 PeerConnectionIntegrationTest,
3542 PeerConnectionIntegrationTestWithFakeClock,
Florent Castelli15a38de2022-04-06 00:38:21 +02003543 Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003544 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3545 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3546 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Yves Gerey100fe632020-01-17 19:15:53 +01003547
Steve Anton74255ff2018-01-24 18:32:57 -08003548// Tests that verify interoperability between Plan B and Unified Plan
3549// PeerConnections.
3550class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003551 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08003552 public ::testing::WithParamInterface<
3553 std::tuple<SdpSemantics, SdpSemantics>> {
3554 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003555 // Setting the SdpSemantics for the base test to kDefault does not matter
3556 // because we specify not to use the test semantics when creating
Harald Alvestrand39993842021-02-17 09:05:31 +00003557 // PeerConnectionIntegrationWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08003558 PeerConnectionIntegrationInteropTest()
Florent Castelli15a38de2022-04-06 00:38:21 +02003559 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED),
Seth Hampson2f0d7022018-02-20 11:54:42 -08003560 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08003561 callee_semantics_(std::get<1>(GetParam())) {}
3562
3563 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07003564 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3565 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08003566 }
3567
3568 const SdpSemantics caller_semantics_;
3569 const SdpSemantics callee_semantics_;
3570};
3571
3572TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3573 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3574 ConnectFakeSignaling();
3575
3576 caller()->CreateAndSetAndSignalOffer();
3577 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3578}
3579
3580TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3581 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3582 ConnectFakeSignaling();
3583 auto audio_sender = caller()->AddAudioTrack();
3584
3585 caller()->CreateAndSetAndSignalOffer();
3586 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3587
3588 // Verify that one audio receiver has been created on the remote and that it
3589 // has the same track ID as the sending track.
3590 auto receivers = callee()->pc()->GetReceivers();
3591 ASSERT_EQ(1u, receivers.size());
3592 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3593 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3594
Seth Hampson2f0d7022018-02-20 11:54:42 -08003595 MediaExpectations media_expectations;
3596 media_expectations.CalleeExpectsSomeAudio();
3597 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003598}
3599
3600TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3601 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3602 ConnectFakeSignaling();
3603 auto video_sender = caller()->AddVideoTrack();
3604 auto audio_sender = caller()->AddAudioTrack();
3605
3606 caller()->CreateAndSetAndSignalOffer();
3607 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3608
3609 // Verify that one audio and one video receiver have been created on the
3610 // remote and that they have the same track IDs as the sending tracks.
3611 auto audio_receivers =
3612 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3613 ASSERT_EQ(1u, audio_receivers.size());
3614 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3615 auto video_receivers =
3616 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3617 ASSERT_EQ(1u, video_receivers.size());
3618 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3619
Seth Hampson2f0d7022018-02-20 11:54:42 -08003620 MediaExpectations media_expectations;
3621 media_expectations.CalleeExpectsSomeAudioAndVideo();
3622 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003623}
3624
3625TEST_P(PeerConnectionIntegrationInteropTest,
3626 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3627 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3628 ConnectFakeSignaling();
3629 caller()->AddAudioVideoTracks();
3630 callee()->AddAudioVideoTracks();
3631
3632 caller()->CreateAndSetAndSignalOffer();
3633 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3634
Seth Hampson2f0d7022018-02-20 11:54:42 -08003635 MediaExpectations media_expectations;
3636 media_expectations.ExpectBidirectionalAudioAndVideo();
3637 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003638}
3639
3640TEST_P(PeerConnectionIntegrationInteropTest,
3641 ReverseRolesOneAudioLocalToOneVideoRemote) {
3642 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3643 ConnectFakeSignaling();
3644 caller()->AddAudioTrack();
3645 callee()->AddVideoTrack();
3646
3647 caller()->CreateAndSetAndSignalOffer();
3648 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3649
3650 // Verify that only the audio track has been negotiated.
3651 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3652 // Might also check that the callee's NegotiationNeeded flag is set.
3653
3654 // Reverse roles.
3655 callee()->CreateAndSetAndSignalOffer();
3656 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3657
Seth Hampson2f0d7022018-02-20 11:54:42 -08003658 MediaExpectations media_expectations;
3659 media_expectations.CallerExpectsSomeVideo();
3660 media_expectations.CalleeExpectsSomeAudio();
3661 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003662}
3663
Taylor Brandstetter1c7ecef2021-08-11 12:38:35 -07003664TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3665 ASSERT_TRUE(CreatePeerConnectionWrappers());
3666 ConnectFakeSignaling();
3667 caller()->AddAudioVideoTracks();
3668 caller()->CreateAndSetAndSignalOffer();
3669 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3670 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3671 caller()->ExpectCandidates(0);
3672 callee()->ExpectCandidates(0);
3673 caller()->AddAudioTrack();
3674 caller()->CreateAndSetAndSignalOffer();
3675 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3676}
3677
Harald Alvestrand35ba0c52022-05-05 07:37:41 +00003678TEST_P(PeerConnectionIntegrationTest, MediaCallWithoutMediaEngineFails) {
3679 ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
3680 // AddTrack should fail.
3681 EXPECT_FALSE(
3682 caller()->pc()->AddTrack(caller()->CreateLocalAudioTrack(), {}).ok());
3683}
3684
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003685INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07003686 PeerConnectionIntegrationTest,
3687 PeerConnectionIntegrationInteropTest,
Florent Castelli15a38de2022-04-06 00:38:21 +02003688 Values(std::make_tuple(SdpSemantics::kPlanB_DEPRECATED,
3689 SdpSemantics::kUnifiedPlan),
3690 std::make_tuple(SdpSemantics::kUnifiedPlan,
3691 SdpSemantics::kPlanB_DEPRECATED)));
Steve Antonba42e992018-04-09 14:10:01 -07003692
3693// Test that if the Unified Plan side offers two video tracks then the Plan B
3694// side will only see the first one and ignore the second.
3695TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07003696 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
Florent Castelli15a38de2022-04-06 00:38:21 +02003697 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB_DEPRECATED));
Steve Anton74255ff2018-01-24 18:32:57 -08003698 ConnectFakeSignaling();
3699 auto first_sender = caller()->AddVideoTrack();
3700 caller()->AddVideoTrack();
3701
3702 caller()->CreateAndSetAndSignalOffer();
3703 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3704
3705 // Verify that there is only one receiver and it corresponds to the first
3706 // added track.
3707 auto receivers = callee()->pc()->GetReceivers();
3708 ASSERT_EQ(1u, receivers.size());
3709 EXPECT_TRUE(receivers[0]->track()->enabled());
3710 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3711
Seth Hampson2f0d7022018-02-20 11:54:42 -08003712 MediaExpectations media_expectations;
3713 media_expectations.CalleeExpectsSomeVideo();
3714 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003715}
3716
Steve Anton2bed3972019-01-04 17:04:30 -08003717// Test that if the initial offer tagged BUNDLE section is rejected due to its
3718// associated RtpTransceiver being stopped and another transceiver is added,
3719// then renegotiation causes the callee to receive the new video track without
3720// error.
3721// This is a regression test for bugs.webrtc.org/9954
3722TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3723 ReOfferWithStoppedBundleTaggedTransceiver) {
3724 RTCConfiguration config;
3725 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3726 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3727 ConnectFakeSignaling();
3728 auto audio_transceiver_or_error =
3729 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3730 ASSERT_TRUE(audio_transceiver_or_error.ok());
3731 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3732
3733 caller()->CreateAndSetAndSignalOffer();
3734 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3735 {
3736 MediaExpectations media_expectations;
3737 media_expectations.CalleeExpectsSomeAudio();
3738 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3739 }
3740
Harald Alvestrand6060df52020-08-11 09:54:02 +02003741 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08003742 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3743
3744 caller()->CreateAndSetAndSignalOffer();
3745 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3746 {
3747 MediaExpectations media_expectations;
3748 media_expectations.CalleeExpectsSomeVideo();
3749 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3750 }
3751}
3752
Harald Alvestrandbedb6052020-08-20 14:50:10 +02003753TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3754 StopTransceiverRemovesDtlsTransports) {
3755 RTCConfiguration config;
3756 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3757 ConnectFakeSignaling();
3758 auto audio_transceiver_or_error =
3759 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3760 ASSERT_TRUE(audio_transceiver_or_error.ok());
3761 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3762
3763 caller()->CreateAndSetAndSignalOffer();
3764 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3765
3766 audio_transceiver->StopStandard();
3767 caller()->CreateAndSetAndSignalOffer();
3768 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3769 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3770 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3771 caller()->pc()->ice_gathering_state());
3772 EXPECT_THAT(caller()->ice_gathering_state_history(),
3773 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3774 PeerConnectionInterface::kIceGatheringComplete,
3775 PeerConnectionInterface::kIceGatheringNew));
3776}
3777
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003778TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00003779 StopTransceiverStopsAndRemovesTransceivers) {
3780 RTCConfiguration config;
3781 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3782 ConnectFakeSignaling();
3783 auto audio_transceiver_or_error =
3784 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3785 ASSERT_TRUE(audio_transceiver_or_error.ok());
3786 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3787
3788 caller()->CreateAndSetAndSignalOffer();
3789 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3790 caller_transceiver->StopStandard();
3791
3792 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3793 caller()->CreateAndSetAndSignalOffer();
3794 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3795 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3796 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3797 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3798 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3799 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3800 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3801 EXPECT_TRUE(caller_transceiver->stopped());
3802 EXPECT_TRUE(callee_transceiver->stopped());
3803}
3804
3805TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003806 StopTransceiverEndsIncomingAudioTrack) {
3807 RTCConfiguration config;
3808 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3809 ConnectFakeSignaling();
3810 auto audio_transceiver_or_error =
3811 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3812 ASSERT_TRUE(audio_transceiver_or_error.ok());
3813 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3814
3815 caller()->CreateAndSetAndSignalOffer();
3816 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3817 auto caller_track = audio_transceiver->receiver()->track();
3818 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3819 audio_transceiver->StopStandard();
3820 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3821 caller_track->state());
3822 caller()->CreateAndSetAndSignalOffer();
3823 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3824 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3825 callee_track->state());
3826}
3827
3828TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3829 StopTransceiverEndsIncomingVideoTrack) {
3830 RTCConfiguration config;
3831 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3832 ConnectFakeSignaling();
3833 auto audio_transceiver_or_error =
3834 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3835 ASSERT_TRUE(audio_transceiver_or_error.ok());
3836 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3837
3838 caller()->CreateAndSetAndSignalOffer();
3839 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3840 auto caller_track = audio_transceiver->receiver()->track();
3841 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3842 audio_transceiver->StopStandard();
3843 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3844 caller_track->state());
3845 caller()->CreateAndSetAndSignalOffer();
3846 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3847 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3848 callee_track->state());
3849}
3850
Harald Alvestrand89c40e22021-02-17 08:58:35 +00003851} // namespace
Harald Alvestrand39993842021-02-17 09:05:31 +00003852
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01003853} // namespace webrtc