blob: f2e4b1d525cd5a83a78c4b32076980267516308b [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()
135 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB) {}
136};
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();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800538 if (sdp_semantics_ == SdpSemantics::kPlanB) {
539 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();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800568 if (sdp_semantics_ == SdpSemantics::kPlanB) {
569 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());
581 transceivers[1]->sender()->SetTrack(caller()->CreateLocalVideoTrack());
582 transceivers[1]->SetDirectionWithError(
583 RtpTransceiverDirection::kSendRecv);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800584 });
585 }
deadbeef1dcb1642017-03-29 21:08:16 -0700586 callee()->CreateAndSetAndSignalOffer();
587 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800588 {
589 // Expect additional audio frames to be received after the upgrade.
590 MediaExpectations media_expectations;
591 media_expectations.ExpectBidirectionalAudioAndVideo();
592 ASSERT_TRUE(ExpectNewFrames(media_expectations));
593 }
deadbeef1dcb1642017-03-29 21:08:16 -0700594}
595
deadbeef4389b4d2017-09-07 09:07:36 -0700596// Simpler than the above test; just add an audio track to an established
597// video-only connection.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800598TEST_P(PeerConnectionIntegrationTest, AddAudioToVideoOnlyCall) {
deadbeef4389b4d2017-09-07 09:07:36 -0700599 ASSERT_TRUE(CreatePeerConnectionWrappers());
600 ConnectFakeSignaling();
601 // Do initial offer/answer with just a video track.
Steve Anton15324772018-01-16 10:26:49 -0800602 caller()->AddVideoTrack();
603 callee()->AddVideoTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700604 caller()->CreateAndSetAndSignalOffer();
605 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
606 // Now add an audio track and do another offer/answer.
Steve Anton15324772018-01-16 10:26:49 -0800607 caller()->AddAudioTrack();
608 callee()->AddAudioTrack();
deadbeef4389b4d2017-09-07 09:07:36 -0700609 caller()->CreateAndSetAndSignalOffer();
610 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
611 // Ensure both audio and video frames are received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800612 MediaExpectations media_expectations;
613 media_expectations.ExpectBidirectionalAudioAndVideo();
614 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef4389b4d2017-09-07 09:07:36 -0700615}
616
deadbeef1dcb1642017-03-29 21:08:16 -0700617// This test sets up a call that's transferred to a new caller with a different
618// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800619TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
deadbeef1dcb1642017-03-29 21:08:16 -0700620 ASSERT_TRUE(CreatePeerConnectionWrappers());
621 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800622 caller()->AddAudioVideoTracks();
623 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700624 caller()->CreateAndSetAndSignalOffer();
625 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
626
627 // Keep the original peer around which will still send packets to the
628 // receiving client. These SRTP packets will be dropped.
Harald Alvestrand39993842021-02-17 09:05:31 +0000629 std::unique_ptr<PeerConnectionIntegrationWrapper> original_peer(
deadbeef1dcb1642017-03-29 21:08:16 -0700630 SetCallerPcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -0800631 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -0700632 // TODO(deadbeef): Why do we call Close here? That goes against the comment
633 // directly above.
634 original_peer->pc()->Close();
635
636 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800637 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700638 caller()->CreateAndSetAndSignalOffer();
639 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
640 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800641 MediaExpectations media_expectations;
642 media_expectations.ExpectBidirectionalAudioAndVideo();
643 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700644}
645
646// This test sets up a call that's transferred to a new callee with a different
647// DTLS fingerprint.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800648TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
deadbeef1dcb1642017-03-29 21:08:16 -0700649 ASSERT_TRUE(CreatePeerConnectionWrappers());
650 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800651 caller()->AddAudioVideoTracks();
652 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700653 caller()->CreateAndSetAndSignalOffer();
654 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
655
656 // Keep the original peer around which will still send packets to the
657 // receiving client. These SRTP packets will be dropped.
Harald Alvestrand39993842021-02-17 09:05:31 +0000658 std::unique_ptr<PeerConnectionIntegrationWrapper> original_peer(
deadbeef1dcb1642017-03-29 21:08:16 -0700659 SetCalleePcWrapperAndReturnCurrent(
Seth Hampson2f0d7022018-02-20 11:54:42 -0800660 CreatePeerConnectionWrapperWithAlternateKey().release()));
deadbeef1dcb1642017-03-29 21:08:16 -0700661 // TODO(deadbeef): Why do we call Close here? That goes against the comment
662 // directly above.
663 original_peer->pc()->Close();
664
665 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800666 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700667 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
668 caller()->CreateAndSetAndSignalOffer();
669 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
670 // Wait for some additional frames to be transmitted end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800671 MediaExpectations media_expectations;
672 media_expectations.ExpectBidirectionalAudioAndVideo();
673 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -0700674}
675
676// This test sets up a non-bundled call and negotiates bundling at the same
677// time as starting an ICE restart. When bundling is in effect in the restart,
678// the DTLS-SRTP context should be successfully reset.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800679TEST_P(PeerConnectionIntegrationTest, BundlingEnabledWhileIceRestartOccurs) {
deadbeef1dcb1642017-03-29 21:08:16 -0700680 ASSERT_TRUE(CreatePeerConnectionWrappers());
681 ConnectFakeSignaling();
682
Steve Anton15324772018-01-16 10:26:49 -0800683 caller()->AddAudioVideoTracks();
684 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700685 // Remove the bundle group from the SDP received by the callee.
686 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
687 desc->RemoveGroupByName("BUNDLE");
688 });
689 caller()->CreateAndSetAndSignalOffer();
690 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800691 {
692 MediaExpectations media_expectations;
693 media_expectations.ExpectBidirectionalAudioAndVideo();
694 ASSERT_TRUE(ExpectNewFrames(media_expectations));
695 }
deadbeef1dcb1642017-03-29 21:08:16 -0700696 // Now stop removing the BUNDLE group, and trigger an ICE restart.
697 callee()->SetReceivedSdpMunger(nullptr);
698 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
699 caller()->CreateAndSetAndSignalOffer();
700 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
701
702 // Expect additional frames to be received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800703 {
704 MediaExpectations media_expectations;
705 media_expectations.ExpectBidirectionalAudioAndVideo();
706 ASSERT_TRUE(ExpectNewFrames(media_expectations));
707 }
deadbeef1dcb1642017-03-29 21:08:16 -0700708}
709
710// Test CVO (Coordination of Video Orientation). If a video source is rotated
711// and both peers support the CVO RTP header extension, the actual video frames
712// don't need to be encoded in different resolutions, since the rotation is
713// communicated through the RTP header extension.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800714TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700715 ASSERT_TRUE(CreatePeerConnectionWrappers());
716 ConnectFakeSignaling();
717 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800718 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700719 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800720 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700721 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
722
723 // Wait for video frames to be received by both sides.
724 caller()->CreateAndSetAndSignalOffer();
725 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
726 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
727 callee()->min_video_frames_received_per_track() > 0,
728 kMaxWaitForFramesMs);
729
730 // Ensure that the aspect ratio is unmodified.
731 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
732 // not just assumed.
733 EXPECT_EQ(4.0 / 3, caller()->local_rendered_aspect_ratio());
734 EXPECT_EQ(4.0 / 3, caller()->rendered_aspect_ratio());
735 EXPECT_EQ(4.0 / 3, callee()->local_rendered_aspect_ratio());
736 EXPECT_EQ(4.0 / 3, callee()->rendered_aspect_ratio());
737 // Ensure that the CVO bits were surfaced to the renderer.
738 EXPECT_EQ(webrtc::kVideoRotation_270, caller()->rendered_rotation());
739 EXPECT_EQ(webrtc::kVideoRotation_90, callee()->rendered_rotation());
740}
741
742// Test that when the CVO extension isn't supported, video is rotated the
743// old-fashioned way, by encoding rotated frames.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800744TEST_P(PeerConnectionIntegrationTest, RotatedVideoWithoutCVOExtension) {
deadbeef1dcb1642017-03-29 21:08:16 -0700745 ASSERT_TRUE(CreatePeerConnectionWrappers());
746 ConnectFakeSignaling();
747 // Add rotated video tracks.
Steve Anton15324772018-01-16 10:26:49 -0800748 caller()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700749 caller()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_90));
Steve Anton15324772018-01-16 10:26:49 -0800750 callee()->AddTrack(
deadbeef1dcb1642017-03-29 21:08:16 -0700751 callee()->CreateLocalVideoTrackWithRotation(webrtc::kVideoRotation_270));
752
753 // Remove the CVO extension from the offered SDP.
754 callee()->SetReceivedSdpMunger([](cricket::SessionDescription* desc) {
755 cricket::VideoContentDescription* video =
756 GetFirstVideoContentDescription(desc);
757 video->ClearRtpHeaderExtensions();
758 });
759 // Wait for video frames to be received by both sides.
760 caller()->CreateAndSetAndSignalOffer();
761 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
762 ASSERT_TRUE_WAIT(caller()->min_video_frames_received_per_track() > 0 &&
763 callee()->min_video_frames_received_per_track() > 0,
764 kMaxWaitForFramesMs);
765
766 // Expect that the aspect ratio is inversed to account for the 90/270 degree
767 // rotation.
768 // TODO(deadbeef): Where does 4:3 come from? Should be explicit in the test,
769 // not just assumed.
770 EXPECT_EQ(3.0 / 4, caller()->local_rendered_aspect_ratio());
771 EXPECT_EQ(3.0 / 4, caller()->rendered_aspect_ratio());
772 EXPECT_EQ(3.0 / 4, callee()->local_rendered_aspect_ratio());
773 EXPECT_EQ(3.0 / 4, callee()->rendered_aspect_ratio());
774 // Expect that each endpoint is unaware of the rotation of the other endpoint.
775 EXPECT_EQ(webrtc::kVideoRotation_0, caller()->rendered_rotation());
776 EXPECT_EQ(webrtc::kVideoRotation_0, callee()->rendered_rotation());
777}
778
deadbeef1dcb1642017-03-29 21:08:16 -0700779// Test that if the answerer rejects the audio m= section, no audio is sent or
780// received, but video still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800781TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700782 ASSERT_TRUE(CreatePeerConnectionWrappers());
783 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800784 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800785 if (sdp_semantics_ == SdpSemantics::kPlanB) {
786 // Only add video track for callee, and set offer_to_receive_audio to 0, so
787 // it will reject the audio m= section completely.
788 PeerConnectionInterface::RTCOfferAnswerOptions options;
789 options.offer_to_receive_audio = 0;
790 callee()->SetOfferAnswerOptions(options);
791 } else {
792 // Stopping the audio RtpTransceiver will cause the media section to be
793 // rejected in the answer.
794 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200795 callee()
796 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
797 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800798 });
799 }
Steve Anton15324772018-01-16 10:26:49 -0800800 callee()->AddTrack(callee()->CreateLocalVideoTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700801 // Do offer/answer and wait for successful end-to-end video frames.
802 caller()->CreateAndSetAndSignalOffer();
803 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800804 MediaExpectations media_expectations;
805 media_expectations.ExpectBidirectionalVideo();
806 media_expectations.ExpectNoAudio();
807 ASSERT_TRUE(ExpectNewFrames(media_expectations));
808
deadbeef1dcb1642017-03-29 21:08:16 -0700809 // Sanity check that the callee's description has a rejected audio section.
810 ASSERT_NE(nullptr, callee()->pc()->local_description());
811 const ContentInfo* callee_audio_content =
812 GetFirstAudioContent(callee()->pc()->local_description()->description());
813 ASSERT_NE(nullptr, callee_audio_content);
814 EXPECT_TRUE(callee_audio_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800815 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200816 // The caller's transceiver should have stopped after receiving the answer,
817 // and thus no longer listed in transceivers.
818 EXPECT_EQ(nullptr,
819 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800820 }
deadbeef1dcb1642017-03-29 21:08:16 -0700821}
822
823// Test that if the answerer rejects the video m= section, no video is sent or
824// received, but audio still can be.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800825TEST_P(PeerConnectionIntegrationTest, AnswererRejectsVideoSection) {
deadbeef1dcb1642017-03-29 21:08:16 -0700826 ASSERT_TRUE(CreatePeerConnectionWrappers());
827 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800828 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800829 if (sdp_semantics_ == SdpSemantics::kPlanB) {
830 // Only add audio track for callee, and set offer_to_receive_video to 0, so
831 // it will reject the video m= section completely.
832 PeerConnectionInterface::RTCOfferAnswerOptions options;
833 options.offer_to_receive_video = 0;
834 callee()->SetOfferAnswerOptions(options);
835 } else {
836 // Stopping the video RtpTransceiver will cause the media section to be
837 // rejected in the answer.
838 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200839 callee()
840 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
841 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800842 });
843 }
Steve Anton15324772018-01-16 10:26:49 -0800844 callee()->AddTrack(callee()->CreateLocalAudioTrack());
deadbeef1dcb1642017-03-29 21:08:16 -0700845 // Do offer/answer and wait for successful end-to-end audio frames.
846 caller()->CreateAndSetAndSignalOffer();
847 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800848 MediaExpectations media_expectations;
849 media_expectations.ExpectBidirectionalAudio();
850 media_expectations.ExpectNoVideo();
851 ASSERT_TRUE(ExpectNewFrames(media_expectations));
852
deadbeef1dcb1642017-03-29 21:08:16 -0700853 // Sanity check that the callee's description has a rejected video section.
854 ASSERT_NE(nullptr, callee()->pc()->local_description());
855 const ContentInfo* callee_video_content =
856 GetFirstVideoContent(callee()->pc()->local_description()->description());
857 ASSERT_NE(nullptr, callee_video_content);
858 EXPECT_TRUE(callee_video_content->rejected);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800859 if (sdp_semantics_ == SdpSemantics::kUnifiedPlan) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200860 // The caller's transceiver should have stopped after receiving the answer,
861 // and thus is no longer present.
862 EXPECT_EQ(nullptr,
863 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO));
Seth Hampson2f0d7022018-02-20 11:54:42 -0800864 }
deadbeef1dcb1642017-03-29 21:08:16 -0700865}
866
867// Test that if the answerer rejects both audio and video m= sections, nothing
868// bad happens.
869// TODO(deadbeef): Test that a data channel still works. Currently this doesn't
870// test anything but the fact that negotiation succeeds, which doesn't mean
871// much.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800872TEST_P(PeerConnectionIntegrationTest, AnswererRejectsAudioAndVideoSections) {
deadbeef1dcb1642017-03-29 21:08:16 -0700873 ASSERT_TRUE(CreatePeerConnectionWrappers());
874 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800875 caller()->AddAudioVideoTracks();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800876 if (sdp_semantics_ == SdpSemantics::kPlanB) {
877 // Don't give the callee any tracks, and set offer_to_receive_X to 0, so it
878 // will reject both audio and video m= sections.
879 PeerConnectionInterface::RTCOfferAnswerOptions options;
880 options.offer_to_receive_audio = 0;
881 options.offer_to_receive_video = 0;
882 callee()->SetOfferAnswerOptions(options);
883 } else {
884 callee()->SetRemoteOfferHandler([this] {
885 // Stopping all transceivers will cause all media sections to be rejected.
Mirko Bonadei739baf02019-01-27 17:29:42 +0100886 for (const auto& transceiver : callee()->pc()->GetTransceivers()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200887 transceiver->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800888 }
889 });
890 }
deadbeef1dcb1642017-03-29 21:08:16 -0700891 // Do offer/answer and wait for stable signaling state.
892 caller()->CreateAndSetAndSignalOffer();
893 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800894
deadbeef1dcb1642017-03-29 21:08:16 -0700895 // Sanity check that the callee's description has rejected m= sections.
896 ASSERT_NE(nullptr, callee()->pc()->local_description());
897 const ContentInfo* callee_audio_content =
898 GetFirstAudioContent(callee()->pc()->local_description()->description());
899 ASSERT_NE(nullptr, callee_audio_content);
900 EXPECT_TRUE(callee_audio_content->rejected);
901 const ContentInfo* callee_video_content =
902 GetFirstVideoContent(callee()->pc()->local_description()->description());
903 ASSERT_NE(nullptr, callee_video_content);
904 EXPECT_TRUE(callee_video_content->rejected);
905}
906
907// This test sets up an audio and video call between two parties. After the
908// call runs for a while, the caller sends an updated offer with video being
909// rejected. Once the re-negotiation is done, the video flow should stop and
910// the audio flow should continue.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800911TEST_P(PeerConnectionIntegrationTest, VideoRejectedInSubsequentOffer) {
deadbeef1dcb1642017-03-29 21:08:16 -0700912 ASSERT_TRUE(CreatePeerConnectionWrappers());
913 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -0800914 caller()->AddAudioVideoTracks();
915 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -0700916 caller()->CreateAndSetAndSignalOffer();
917 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -0800918 {
919 MediaExpectations media_expectations;
920 media_expectations.ExpectBidirectionalAudioAndVideo();
921 ASSERT_TRUE(ExpectNewFrames(media_expectations));
922 }
deadbeef1dcb1642017-03-29 21:08:16 -0700923 // Renegotiate, rejecting the video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800924 if (sdp_semantics_ == SdpSemantics::kPlanB) {
925 caller()->SetGeneratedSdpMunger(
926 [](cricket::SessionDescription* description) {
927 for (cricket::ContentInfo& content : description->contents()) {
928 if (cricket::IsVideoContent(&content)) {
929 content.rejected = true;
930 }
931 }
932 });
933 } else {
Harald Alvestrand6060df52020-08-11 09:54:02 +0200934 caller()
935 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
936 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -0800937 }
deadbeef1dcb1642017-03-29 21:08:16 -0700938 caller()->CreateAndSetAndSignalOffer();
939 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
940
941 // Sanity check that the caller's description has a rejected video section.
942 ASSERT_NE(nullptr, caller()->pc()->local_description());
943 const ContentInfo* caller_video_content =
944 GetFirstVideoContent(caller()->pc()->local_description()->description());
945 ASSERT_NE(nullptr, caller_video_content);
946 EXPECT_TRUE(caller_video_content->rejected);
deadbeef1dcb1642017-03-29 21:08:16 -0700947 // Wait for some additional audio frames to be received.
Seth Hampson2f0d7022018-02-20 11:54:42 -0800948 {
949 MediaExpectations media_expectations;
950 media_expectations.ExpectBidirectionalAudio();
951 media_expectations.ExpectNoVideo();
952 ASSERT_TRUE(ExpectNewFrames(media_expectations));
953 }
deadbeef1dcb1642017-03-29 21:08:16 -0700954}
955
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700956// Do one offer/answer with audio, another that disables it (rejecting the m=
957// section), and another that re-enables it. Regression test for:
958// bugs.webrtc.org/6023
959TEST_F(PeerConnectionIntegrationTestPlanB, EnableAudioAfterRejecting) {
960 ASSERT_TRUE(CreatePeerConnectionWrappers());
961 ConnectFakeSignaling();
962
963 // Add audio track, do normal offer/answer.
964 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
965 caller()->CreateLocalAudioTrack();
966 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
967 caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
968 caller()->CreateAndSetAndSignalOffer();
969 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
970
971 // Remove audio track, and set offer_to_receive_audio to false to cause the
972 // m= section to be completely disabled, not just "recvonly".
Harald Alvestrand93dd7632022-01-19 12:28:45 +0000973 caller()->pc()->RemoveTrackOrError(sender);
Taylor Brandstetter60c8dc82018-04-11 15:20:27 -0700974 PeerConnectionInterface::RTCOfferAnswerOptions options;
975 options.offer_to_receive_audio = 0;
976 caller()->SetOfferAnswerOptions(options);
977 caller()->CreateAndSetAndSignalOffer();
978 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
979
980 // Add the audio track again, expecting negotiation to succeed and frames to
981 // flow.
982 sender = caller()->pc()->AddTrack(track, {"stream"}).MoveValue();
983 options.offer_to_receive_audio = 1;
984 caller()->SetOfferAnswerOptions(options);
985 caller()->CreateAndSetAndSignalOffer();
986 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
987
988 MediaExpectations media_expectations;
989 media_expectations.CalleeExpectsSomeAudio();
990 EXPECT_TRUE(ExpectNewFrames(media_expectations));
991}
992
deadbeef1dcb1642017-03-29 21:08:16 -0700993// Basic end-to-end test, but without SSRC/MSID signaling. This functionality
994// is needed to support legacy endpoints.
995// TODO(deadbeef): When we support the MID extension and demuxing on MID, also
996// add a test for an end-to-end test without MID signaling either (basically,
997// the minimum acceptable SDP).
Seth Hampson2f0d7022018-02-20 11:54:42 -0800998TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithoutSsrcOrMsidSignaling) {
deadbeef1dcb1642017-03-29 21:08:16 -0700999 ASSERT_TRUE(CreatePeerConnectionWrappers());
1000 ConnectFakeSignaling();
1001 // Add audio and video, testing that packets can be demuxed on payload type.
Steve Anton15324772018-01-16 10:26:49 -08001002 caller()->AddAudioVideoTracks();
1003 callee()->AddAudioVideoTracks();
deadbeefd8ad7882017-04-18 16:01:17 -07001004 // Remove SSRCs and MSIDs from the received offer SDP.
1005 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
deadbeef1dcb1642017-03-29 21:08:16 -07001006 caller()->CreateAndSetAndSignalOffer();
1007 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001008 MediaExpectations media_expectations;
1009 media_expectations.ExpectBidirectionalAudioAndVideo();
1010 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001011}
1012
Seth Hampson5897a6e2018-04-03 11:16:33 -07001013// Basic end-to-end test, without SSRC signaling. This means that the track
1014// was created properly and frames are delivered when the MSIDs are communicated
1015// with a=msid lines and no a=ssrc lines.
1016TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1017 EndToEndCallWithoutSsrcSignaling) {
1018 const char kStreamId[] = "streamId";
1019 ASSERT_TRUE(CreatePeerConnectionWrappers());
1020 ConnectFakeSignaling();
1021 // Add just audio tracks.
1022 caller()->AddTrack(caller()->CreateLocalAudioTrack(), {kStreamId});
1023 callee()->AddAudioTrack();
1024
1025 // Remove SSRCs from the received offer SDP.
1026 callee()->SetReceivedSdpMunger(RemoveSsrcsAndKeepMsids);
1027 caller()->CreateAndSetAndSignalOffer();
1028 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1029 MediaExpectations media_expectations;
1030 media_expectations.ExpectBidirectionalAudio();
1031 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1032}
1033
Johannes Kron3e983682020-03-29 22:17:00 +02001034TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1035 EndToEndCallAddReceiveVideoToSendOnlyCall) {
1036 ASSERT_TRUE(CreatePeerConnectionWrappers());
1037 ConnectFakeSignaling();
1038 // Add one-directional video, from caller to callee.
1039 rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
1040 caller()->CreateLocalVideoTrack();
1041
1042 RtpTransceiverInit video_transceiver_init;
1043 video_transceiver_init.stream_ids = {"video1"};
1044 video_transceiver_init.direction = RtpTransceiverDirection::kSendOnly;
1045 auto video_sender =
1046 caller()->pc()->AddTransceiver(track, video_transceiver_init).MoveValue();
1047 caller()->CreateAndSetAndSignalOffer();
1048 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1049
1050 // Add receive direction.
Harald Alvestrand6060df52020-08-11 09:54:02 +02001051 video_sender->SetDirectionWithError(RtpTransceiverDirection::kSendRecv);
Johannes Kron3e983682020-03-29 22:17:00 +02001052
1053 rtc::scoped_refptr<webrtc::VideoTrackInterface> callee_track =
1054 callee()->CreateLocalVideoTrack();
1055
1056 callee()->AddTrack(callee_track);
1057 caller()->CreateAndSetAndSignalOffer();
1058 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1059 // Ensure that video frames are received end-to-end.
1060 MediaExpectations media_expectations;
1061 media_expectations.ExpectBidirectionalVideo();
1062 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1063}
1064
Steve Antondf527fd2018-04-27 15:52:03 -07001065// Tests that video flows between multiple video tracks when SSRCs are not
1066// signaled. This exercises the MID RTP header extension which is needed to
1067// demux the incoming video tracks.
1068TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1069 EndToEndCallWithTwoVideoTracksAndNoSignaledSsrc) {
1070 ASSERT_TRUE(CreatePeerConnectionWrappers());
1071 ConnectFakeSignaling();
1072 caller()->AddVideoTrack();
1073 caller()->AddVideoTrack();
1074 callee()->AddVideoTrack();
1075 callee()->AddVideoTrack();
1076
1077 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1078 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1079 caller()->CreateAndSetAndSignalOffer();
1080 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1081 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1082 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1083
1084 // Expect video to be received in both directions on both tracks.
1085 MediaExpectations media_expectations;
1086 media_expectations.ExpectBidirectionalVideo();
1087 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1088}
1089
Taylor Brandstetterd3ef4992020-10-15 18:22:57 -07001090// Used for the test below.
1091void RemoveBundleGroupSsrcsAndMidExtension(cricket::SessionDescription* desc) {
1092 RemoveSsrcsAndKeepMsids(desc);
1093 desc->RemoveGroupByName("BUNDLE");
1094 for (ContentInfo& content : desc->contents()) {
1095 cricket::MediaContentDescription* media = content.media_description();
1096 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1097 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1098 [](const RtpExtension& extension) {
1099 return extension.uri ==
1100 RtpExtension::kMidUri;
1101 }),
1102 extensions.end());
1103 media->set_rtp_header_extensions(extensions);
1104 }
1105}
1106
1107// Tests that video flows between multiple video tracks when BUNDLE is not used,
1108// SSRCs are not signaled and the MID RTP header extension is not used. This
1109// relies on demuxing by payload type, which normally doesn't work if you have
1110// multiple media sections using the same payload type, but which should work as
1111// long as the media sections aren't bundled.
1112// Regression test for: http://crbug.com/webrtc/12023
1113TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1114 EndToEndCallWithTwoVideoTracksNoBundleNoSignaledSsrcAndNoMid) {
1115 ASSERT_TRUE(CreatePeerConnectionWrappers());
1116 ConnectFakeSignaling();
1117 caller()->AddVideoTrack();
1118 caller()->AddVideoTrack();
1119 callee()->AddVideoTrack();
1120 callee()->AddVideoTrack();
1121 caller()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1122 callee()->SetReceivedSdpMunger(&RemoveBundleGroupSsrcsAndMidExtension);
1123 caller()->CreateAndSetAndSignalOffer();
1124 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1125 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1126 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1127 // Make sure we are not bundled.
1128 ASSERT_NE(caller()->pc()->GetSenders()[0]->dtls_transport(),
1129 caller()->pc()->GetSenders()[1]->dtls_transport());
1130
1131 // Expect video to be received in both directions on both tracks.
1132 MediaExpectations media_expectations;
1133 media_expectations.ExpectBidirectionalVideo();
1134 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1135}
1136
1137// Used for the test below.
1138void ModifyPayloadTypesAndRemoveMidExtension(
1139 cricket::SessionDescription* desc) {
1140 int pt = 96;
1141 for (ContentInfo& content : desc->contents()) {
1142 cricket::MediaContentDescription* media = content.media_description();
1143 cricket::RtpHeaderExtensions extensions = media->rtp_header_extensions();
1144 extensions.erase(std::remove_if(extensions.begin(), extensions.end(),
1145 [](const RtpExtension& extension) {
1146 return extension.uri ==
1147 RtpExtension::kMidUri;
1148 }),
1149 extensions.end());
1150 media->set_rtp_header_extensions(extensions);
1151 cricket::VideoContentDescription* video = media->as_video();
1152 ASSERT_TRUE(video != nullptr);
1153 std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
1154 video->set_codecs(codecs);
1155 }
1156}
1157
1158// Tests that two video tracks can be demultiplexed by payload type alone, by
1159// using different payload types for the same codec in different m= sections.
1160// This practice is discouraged but historically has been supported.
1161// Regression test for: http://crbug.com/webrtc/12029
1162TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1163 EndToEndCallWithTwoVideoTracksDemultiplexedByPayloadType) {
1164 ASSERT_TRUE(CreatePeerConnectionWrappers());
1165 ConnectFakeSignaling();
1166 caller()->AddVideoTrack();
1167 caller()->AddVideoTrack();
1168 callee()->AddVideoTrack();
1169 callee()->AddVideoTrack();
1170 caller()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1171 callee()->SetGeneratedSdpMunger(&ModifyPayloadTypesAndRemoveMidExtension);
1172 // We can't remove SSRCs from the generated SDP because then no send streams
1173 // would be created.
1174 caller()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1175 callee()->SetReceivedSdpMunger(&RemoveSsrcsAndKeepMsids);
1176 caller()->CreateAndSetAndSignalOffer();
1177 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1178 ASSERT_EQ(2u, caller()->pc()->GetReceivers().size());
1179 ASSERT_EQ(2u, callee()->pc()->GetReceivers().size());
1180 // Make sure we are bundled.
1181 ASSERT_EQ(caller()->pc()->GetSenders()[0]->dtls_transport(),
1182 caller()->pc()->GetSenders()[1]->dtls_transport());
1183
1184 // Expect video to be received in both directions on both tracks.
1185 MediaExpectations media_expectations;
1186 media_expectations.ExpectBidirectionalVideo();
1187 EXPECT_TRUE(ExpectNewFrames(media_expectations));
1188}
1189
Henrik Boström5b147782018-12-04 11:25:05 +01001190TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) {
1191 ASSERT_TRUE(CreatePeerConnectionWrappers());
1192 ConnectFakeSignaling();
1193 caller()->AddAudioTrack();
1194 caller()->AddVideoTrack();
1195 caller()->CreateAndSetAndSignalOffer();
1196 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1197 auto callee_receivers = callee()->pc()->GetReceivers();
1198 ASSERT_EQ(2u, callee_receivers.size());
1199 EXPECT_TRUE(callee_receivers[0]->stream_ids().empty());
1200 EXPECT_TRUE(callee_receivers[1]->stream_ids().empty());
1201}
1202
1203TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) {
1204 ASSERT_TRUE(CreatePeerConnectionWrappers());
1205 ConnectFakeSignaling();
1206 caller()->AddAudioTrack();
1207 caller()->AddVideoTrack();
1208 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1209 caller()->CreateAndSetAndSignalOffer();
1210 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1211 auto callee_receivers = callee()->pc()->GetReceivers();
1212 ASSERT_EQ(2u, callee_receivers.size());
1213 ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size());
1214 ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size());
1215 EXPECT_EQ(callee_receivers[0]->stream_ids()[0],
1216 callee_receivers[1]->stream_ids()[0]);
1217 EXPECT_EQ(callee_receivers[0]->streams()[0],
1218 callee_receivers[1]->streams()[0]);
1219}
1220
deadbeef1dcb1642017-03-29 21:08:16 -07001221// Test that if two video tracks are sent (from caller to callee, in this test),
1222// they're transmitted correctly end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001223TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) {
deadbeef1dcb1642017-03-29 21:08:16 -07001224 ASSERT_TRUE(CreatePeerConnectionWrappers());
1225 ConnectFakeSignaling();
1226 // Add one audio/video stream, and one video-only stream.
Steve Anton15324772018-01-16 10:26:49 -08001227 caller()->AddAudioVideoTracks();
1228 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001229 caller()->CreateAndSetAndSignalOffer();
1230 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton15324772018-01-16 10:26:49 -08001231 ASSERT_EQ(3u, callee()->pc()->GetReceivers().size());
Seth Hampson2f0d7022018-02-20 11:54:42 -08001232
1233 MediaExpectations media_expectations;
1234 media_expectations.CalleeExpectsSomeAudioAndVideo();
1235 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001236}
1237
1238static void MakeSpecCompliantMaxBundleOffer(cricket::SessionDescription* desc) {
1239 bool first = true;
1240 for (cricket::ContentInfo& content : desc->contents()) {
1241 if (first) {
1242 first = false;
1243 continue;
1244 }
1245 content.bundle_only = true;
1246 }
1247 first = true;
1248 for (cricket::TransportInfo& transport : desc->transport_infos()) {
1249 if (first) {
1250 first = false;
1251 continue;
1252 }
1253 transport.description.ice_ufrag.clear();
1254 transport.description.ice_pwd.clear();
1255 transport.description.connection_role = cricket::CONNECTIONROLE_NONE;
1256 transport.description.identity_fingerprint.reset(nullptr);
1257 }
1258}
1259
1260// Test that if applying a true "max bundle" offer, which uses ports of 0,
1261// "a=bundle-only", omitting "a=fingerprint", "a=setup", "a=ice-ufrag" and
1262// "a=ice-pwd" for all but the audio "m=" section, negotiation still completes
1263// successfully and media flows.
1264// TODO(deadbeef): Update this test to also omit "a=rtcp-mux", once that works.
1265// TODO(deadbeef): Won't need this test once we start generating actual
1266// standards-compliant SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001267TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07001268 EndToEndCallWithSpecCompliantMaxBundleOffer) {
1269 ASSERT_TRUE(CreatePeerConnectionWrappers());
1270 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001271 caller()->AddAudioVideoTracks();
1272 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001273 // Do the equivalent of setting the port to 0, adding a=bundle-only, and
1274 // removing a=ice-ufrag, a=ice-pwd, a=fingerprint and a=setup from all
1275 // but the first m= section.
1276 callee()->SetReceivedSdpMunger(MakeSpecCompliantMaxBundleOffer);
1277 caller()->CreateAndSetAndSignalOffer();
1278 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001279 MediaExpectations media_expectations;
1280 media_expectations.ExpectBidirectionalAudioAndVideo();
1281 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001282}
1283
1284// Test that we can receive the audio output level from a remote audio track.
1285// TODO(deadbeef): Use a fake audio source and verify that the output level is
1286// exactly what the source on the other side was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001287TEST_P(PeerConnectionIntegrationTest, GetAudioOutputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001288 ASSERT_TRUE(CreatePeerConnectionWrappers());
1289 ConnectFakeSignaling();
1290 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001291 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001292 caller()->CreateAndSetAndSignalOffer();
1293 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1294
1295 // Get the audio output level stats. Note that the level is not available
1296 // until an RTCP packet has been received.
deadbeefd8ad7882017-04-18 16:01:17 -07001297 EXPECT_TRUE_WAIT(callee()->OldGetStats()->AudioOutputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001298 kMaxWaitForFramesMs);
1299}
1300
1301// Test that an audio input level is reported.
1302// TODO(deadbeef): Use a fake audio source and verify that the input level is
1303// exactly what the source was configured with.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001304TEST_P(PeerConnectionIntegrationTest, GetAudioInputLevelStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001305 ASSERT_TRUE(CreatePeerConnectionWrappers());
1306 ConnectFakeSignaling();
1307 // Just add an audio track.
Steve Anton15324772018-01-16 10:26:49 -08001308 caller()->AddAudioTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07001309 caller()->CreateAndSetAndSignalOffer();
1310 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1311
1312 // Get the audio input level stats. The level should be available very
1313 // soon after the test starts.
deadbeefd8ad7882017-04-18 16:01:17 -07001314 EXPECT_TRUE_WAIT(caller()->OldGetStats()->AudioInputLevel() > 0,
deadbeef1dcb1642017-03-29 21:08:16 -07001315 kMaxWaitForStatsMs);
1316}
1317
1318// Test that we can get incoming byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001319TEST_P(PeerConnectionIntegrationTest, GetBytesReceivedStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001320 ASSERT_TRUE(CreatePeerConnectionWrappers());
1321 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001322 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001323 // Do offer/answer, wait for the callee to receive some frames.
1324 caller()->CreateAndSetAndSignalOffer();
1325 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001326
1327 MediaExpectations media_expectations;
1328 media_expectations.CalleeExpectsSomeAudioAndVideo();
1329 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001330
1331 // Get a handle to the remote tracks created, so they can be used as GetStats
1332 // filters.
Mirko Bonadei739baf02019-01-27 17:29:42 +01001333 for (const auto& receiver : callee()->pc()->GetReceivers()) {
Steve Anton15324772018-01-16 10:26:49 -08001334 // We received frames, so we definitely should have nonzero "received bytes"
1335 // stats at this point.
1336 EXPECT_GT(callee()->OldGetStatsForTrack(receiver->track())->BytesReceived(),
1337 0);
1338 }
deadbeef1dcb1642017-03-29 21:08:16 -07001339}
1340
1341// Test that we can get outgoing byte counts from both audio and video tracks.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001342TEST_P(PeerConnectionIntegrationTest, GetBytesSentStatsWithOldStatsApi) {
deadbeef1dcb1642017-03-29 21:08:16 -07001343 ASSERT_TRUE(CreatePeerConnectionWrappers());
1344 ConnectFakeSignaling();
1345 auto audio_track = caller()->CreateLocalAudioTrack();
1346 auto video_track = caller()->CreateLocalVideoTrack();
Steve Anton15324772018-01-16 10:26:49 -08001347 caller()->AddTrack(audio_track);
1348 caller()->AddTrack(video_track);
deadbeef1dcb1642017-03-29 21:08:16 -07001349 // Do offer/answer, wait for the callee to receive some frames.
1350 caller()->CreateAndSetAndSignalOffer();
1351 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001352 MediaExpectations media_expectations;
1353 media_expectations.CalleeExpectsSomeAudioAndVideo();
1354 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001355
1356 // The callee received frames, so we definitely should have nonzero "sent
1357 // bytes" stats at this point.
deadbeefd8ad7882017-04-18 16:01:17 -07001358 EXPECT_GT(caller()->OldGetStatsForTrack(audio_track)->BytesSent(), 0);
1359 EXPECT_GT(caller()->OldGetStatsForTrack(video_track)->BytesSent(), 0);
1360}
1361
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001362// Test that we can get capture start ntp time.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001363TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001364 ASSERT_TRUE(CreatePeerConnectionWrappers());
1365 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001366 caller()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001367
Steve Anton15324772018-01-16 10:26:49 -08001368 callee()->AddAudioTrack();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001369
1370 // Do offer/answer, wait for the callee to receive some frames.
1371 caller()->CreateAndSetAndSignalOffer();
1372 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1373
1374 // Get the remote audio track created on the receiver, so they can be used as
1375 // GetStats filters.
Steve Antonfc853712018-03-01 13:48:58 -08001376 auto receivers = callee()->pc()->GetReceivers();
1377 ASSERT_EQ(1u, receivers.size());
1378 auto remote_audio_track = receivers[0]->track();
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001379
1380 // Get the audio output level stats. Note that the level is not available
1381 // until an RTCP packet has been received.
Zhi Huange830e682018-03-30 10:48:35 -07001382 EXPECT_TRUE_WAIT(
1383 callee()->OldGetStatsForTrack(remote_audio_track)->CaptureStartNtpTime() >
1384 0,
1385 2 * kMaxWaitForFramesMs);
Fredrik Solenberg73276ad2017-09-14 14:46:47 +02001386}
1387
Steve Antona41959e2018-11-28 11:15:33 -08001388// Test that the track ID is associated with all local and remote SSRC stats
1389// using the old GetStats() and more than 1 audio and more than 1 video track.
1390// This is a regression test for crbug.com/906988
1391TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
1392 OldGetStatsAssociatesTrackIdForManyMediaSections) {
1393 ASSERT_TRUE(CreatePeerConnectionWrappers());
1394 ConnectFakeSignaling();
1395 auto audio_sender_1 = caller()->AddAudioTrack();
1396 auto video_sender_1 = caller()->AddVideoTrack();
1397 auto audio_sender_2 = caller()->AddAudioTrack();
1398 auto video_sender_2 = caller()->AddVideoTrack();
1399 caller()->CreateAndSetAndSignalOffer();
1400 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1401
1402 MediaExpectations media_expectations;
1403 media_expectations.CalleeExpectsSomeAudioAndVideo();
1404 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1405
1406 std::vector<std::string> track_ids = {
1407 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1408 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1409
1410 auto caller_stats = caller()->OldGetStats();
1411 EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1412 auto callee_stats = callee()->OldGetStats();
1413 EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids));
1414}
1415
Steve Antonffa6ce42018-11-30 09:26:08 -08001416// Test that the new GetStats() returns stats for all outgoing/incoming streams
1417// with the correct track IDs if there are more than one audio and more than one
1418// video senders/receivers.
1419TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
1420 ASSERT_TRUE(CreatePeerConnectionWrappers());
1421 ConnectFakeSignaling();
1422 auto audio_sender_1 = caller()->AddAudioTrack();
1423 auto video_sender_1 = caller()->AddVideoTrack();
1424 auto audio_sender_2 = caller()->AddAudioTrack();
1425 auto video_sender_2 = caller()->AddVideoTrack();
1426 caller()->CreateAndSetAndSignalOffer();
1427 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1428
1429 MediaExpectations media_expectations;
1430 media_expectations.CalleeExpectsSomeAudioAndVideo();
1431 ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout);
1432
1433 std::vector<std::string> track_ids = {
1434 audio_sender_1->track()->id(), video_sender_1->track()->id(),
1435 audio_sender_2->track()->id(), video_sender_2->track()->id()};
1436
1437 rtc::scoped_refptr<const webrtc::RTCStatsReport> caller_report =
1438 caller()->NewGetStats();
1439 ASSERT_TRUE(caller_report);
1440 auto outbound_stream_stats =
1441 caller_report->GetStatsOfType<webrtc::RTCOutboundRTPStreamStats>();
Henrik Boströma0ff50c2020-05-05 15:54:46 +02001442 ASSERT_EQ(outbound_stream_stats.size(), 4u);
Steve Antonffa6ce42018-11-30 09:26:08 -08001443 std::vector<std::string> outbound_track_ids;
1444 for (const auto& stat : outbound_stream_stats) {
1445 ASSERT_TRUE(stat->bytes_sent.is_defined());
1446 EXPECT_LT(0u, *stat->bytes_sent);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001447 if (*stat->kind == "video") {
1448 ASSERT_TRUE(stat->key_frames_encoded.is_defined());
1449 EXPECT_GT(*stat->key_frames_encoded, 0u);
1450 ASSERT_TRUE(stat->frames_encoded.is_defined());
1451 EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
1452 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001453 ASSERT_TRUE(stat->track_id.is_defined());
1454 const auto* track_stat =
1455 caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1456 ASSERT_TRUE(track_stat);
1457 outbound_track_ids.push_back(*track_stat->track_identifier);
1458 }
1459 EXPECT_THAT(outbound_track_ids, UnorderedElementsAreArray(track_ids));
1460
1461 rtc::scoped_refptr<const webrtc::RTCStatsReport> callee_report =
1462 callee()->NewGetStats();
1463 ASSERT_TRUE(callee_report);
1464 auto inbound_stream_stats =
1465 callee_report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1466 ASSERT_EQ(4u, inbound_stream_stats.size());
1467 std::vector<std::string> inbound_track_ids;
1468 for (const auto& stat : inbound_stream_stats) {
1469 ASSERT_TRUE(stat->bytes_received.is_defined());
1470 EXPECT_LT(0u, *stat->bytes_received);
Rasmus Brandt2efae772019-06-27 14:29:34 +02001471 if (*stat->kind == "video") {
1472 ASSERT_TRUE(stat->key_frames_decoded.is_defined());
1473 EXPECT_GT(*stat->key_frames_decoded, 0u);
1474 ASSERT_TRUE(stat->frames_decoded.is_defined());
1475 EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
1476 }
Steve Antonffa6ce42018-11-30 09:26:08 -08001477 ASSERT_TRUE(stat->track_id.is_defined());
1478 const auto* track_stat =
1479 callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
1480 ASSERT_TRUE(track_stat);
1481 inbound_track_ids.push_back(*track_stat->track_identifier);
1482 }
1483 EXPECT_THAT(inbound_track_ids, UnorderedElementsAreArray(track_ids));
1484}
1485
1486// Test that we can get stats (using the new stats implementation) for
deadbeefd8ad7882017-04-18 16:01:17 -07001487// unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in
1488// SDP.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001489TEST_P(PeerConnectionIntegrationTest,
deadbeefd8ad7882017-04-18 16:01:17 -07001490 GetStatsForUnsignaledStreamWithNewStatsApi) {
1491 ASSERT_TRUE(CreatePeerConnectionWrappers());
1492 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001493 caller()->AddAudioTrack();
deadbeefd8ad7882017-04-18 16:01:17 -07001494 // Remove SSRCs and MSIDs from the received offer SDP.
1495 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1496 caller()->CreateAndSetAndSignalOffer();
1497 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001498 MediaExpectations media_expectations;
1499 media_expectations.CalleeExpectsSomeAudio(1);
1500 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefd8ad7882017-04-18 16:01:17 -07001501
1502 // We received a frame, so we should have nonzero "bytes received" stats for
1503 // the unsignaled stream, if stats are working for it.
1504 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1505 callee()->NewGetStats();
1506 ASSERT_NE(nullptr, report);
1507 auto inbound_stream_stats =
1508 report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1509 ASSERT_EQ(1U, inbound_stream_stats.size());
1510 ASSERT_TRUE(inbound_stream_stats[0]->bytes_received.is_defined());
1511 ASSERT_GT(*inbound_stream_stats[0]->bytes_received, 0U);
zhihuangf8164932017-05-19 13:09:47 -07001512 ASSERT_TRUE(inbound_stream_stats[0]->track_id.is_defined());
1513}
1514
Taylor Brandstettera4653442018-06-19 09:44:26 -07001515// Same as above but for the legacy stats implementation.
1516TEST_P(PeerConnectionIntegrationTest,
1517 GetStatsForUnsignaledStreamWithOldStatsApi) {
1518 ASSERT_TRUE(CreatePeerConnectionWrappers());
1519 ConnectFakeSignaling();
1520 caller()->AddAudioTrack();
1521 // Remove SSRCs and MSIDs from the received offer SDP.
1522 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1523 caller()->CreateAndSetAndSignalOffer();
1524 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1525
1526 // Note that, since the old stats implementation associates SSRCs with tracks
1527 // using SDP, when SSRCs aren't signaled in SDP these stats won't have an
1528 // associated track ID. So we can't use the track "selector" argument.
1529 //
1530 // Also, we use "EXPECT_TRUE_WAIT" because the stats collector may decide to
1531 // return cached stats if not enough time has passed since the last update.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02001532 EXPECT_TRUE_WAIT(callee()->OldGetStats()->BytesReceived() > 0,
Taylor Brandstettera4653442018-06-19 09:44:26 -07001533 kDefaultTimeout);
1534}
1535
zhihuangf8164932017-05-19 13:09:47 -07001536// Test that we can successfully get the media related stats (audio level
1537// etc.) for the unsignaled stream.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001538TEST_P(PeerConnectionIntegrationTest,
zhihuangf8164932017-05-19 13:09:47 -07001539 GetMediaStatsForUnsignaledStreamWithNewStatsApi) {
1540 ASSERT_TRUE(CreatePeerConnectionWrappers());
1541 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001542 caller()->AddAudioVideoTracks();
zhihuangf8164932017-05-19 13:09:47 -07001543 // Remove SSRCs and MSIDs from the received offer SDP.
1544 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1545 caller()->CreateAndSetAndSignalOffer();
1546 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001547 MediaExpectations media_expectations;
1548 media_expectations.CalleeExpectsSomeAudio(1);
1549 media_expectations.CalleeExpectsSomeVideo(1);
1550 ASSERT_TRUE(ExpectNewFrames(media_expectations));
zhihuangf8164932017-05-19 13:09:47 -07001551
1552 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1553 callee()->NewGetStats();
1554 ASSERT_NE(nullptr, report);
1555
1556 auto media_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1557 auto audio_index = FindFirstMediaStatsIndexByKind("audio", media_stats);
1558 ASSERT_GE(audio_index, 0);
1559 EXPECT_TRUE(media_stats[audio_index]->audio_level.is_defined());
deadbeef1dcb1642017-03-29 21:08:16 -07001560}
1561
deadbeef4e2deab2017-09-20 13:56:21 -07001562// Helper for test below.
1563void ModifySsrcs(cricket::SessionDescription* desc) {
1564 for (ContentInfo& content : desc->contents()) {
Steve Antondf527fd2018-04-27 15:52:03 -07001565 for (StreamParams& stream :
Steve Antonb1c1de12017-12-21 15:14:30 -08001566 content.media_description()->mutable_streams()) {
deadbeef4e2deab2017-09-20 13:56:21 -07001567 for (uint32_t& ssrc : stream.ssrcs) {
1568 ssrc = rtc::CreateRandomId();
1569 }
1570 }
1571 }
1572}
1573
1574// Test that the "RTCMediaSteamTrackStats" object is updated correctly when
1575// SSRCs are unsignaled, and the SSRC of the received (audio) stream changes.
1576// This should result in two "RTCInboundRTPStreamStats", but only one
1577// "RTCMediaStreamTrackStats", whose counters go up continuously rather than
1578// being reset to 0 once the SSRC change occurs.
1579//
1580// Regression test for this bug:
1581// https://bugs.chromium.org/p/webrtc/issues/detail?id=8158
1582//
1583// The bug causes the track stats to only represent one of the two streams:
1584// whichever one has the higher SSRC. So with this bug, there was a 50% chance
1585// that the track stat counters would reset to 0 when the new stream is
1586// received, and a 50% chance that they'll stop updating (while
1587// "concealed_samples" continues increasing, due to silence being generated for
1588// the inactive stream).
Seth Hampson2f0d7022018-02-20 11:54:42 -08001589TEST_P(PeerConnectionIntegrationTest,
Steve Anton83119dd2017-11-10 16:19:52 -08001590 TrackStatsUpdatedCorrectlyWhenUnsignaledSsrcChanges) {
deadbeef4e2deab2017-09-20 13:56:21 -07001591 ASSERT_TRUE(CreatePeerConnectionWrappers());
1592 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001593 caller()->AddAudioTrack();
deadbeef4e2deab2017-09-20 13:56:21 -07001594 // Remove SSRCs and MSIDs from the received offer SDP, simulating an endpoint
1595 // that doesn't signal SSRCs (from the callee's perspective).
1596 callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids);
1597 caller()->CreateAndSetAndSignalOffer();
1598 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1599 // Wait for 50 audio frames (500ms of audio) to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001600 {
1601 MediaExpectations media_expectations;
1602 media_expectations.CalleeExpectsSomeAudio(50);
1603 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1604 }
deadbeef4e2deab2017-09-20 13:56:21 -07001605 // Some audio frames were received, so we should have nonzero "samples
1606 // received" for the track.
1607 rtc::scoped_refptr<const webrtc::RTCStatsReport> report =
1608 callee()->NewGetStats();
1609 ASSERT_NE(nullptr, report);
1610 auto track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1611 ASSERT_EQ(1U, track_stats.size());
1612 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1613 ASSERT_GT(*track_stats[0]->total_samples_received, 0U);
1614 // uint64_t prev_samples_received = *track_stats[0]->total_samples_received;
1615
1616 // Create a new offer and munge it to cause the caller to use a new SSRC.
1617 caller()->SetGeneratedSdpMunger(ModifySsrcs);
1618 caller()->CreateAndSetAndSignalOffer();
1619 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1620 // Wait for 25 more audio frames (250ms of audio) to be received, from the new
1621 // SSRC.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001622 {
1623 MediaExpectations media_expectations;
1624 media_expectations.CalleeExpectsSomeAudio(25);
1625 ASSERT_TRUE(ExpectNewFrames(media_expectations));
1626 }
deadbeef4e2deab2017-09-20 13:56:21 -07001627
1628 report = callee()->NewGetStats();
1629 ASSERT_NE(nullptr, report);
1630 track_stats = report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
1631 ASSERT_EQ(1U, track_stats.size());
1632 ASSERT_TRUE(track_stats[0]->total_samples_received.is_defined());
1633 // The "total samples received" stat should only be greater than it was
1634 // before.
1635 // TODO(deadbeef): Uncomment this assertion once the bug is completely fixed.
1636 // Right now, the new SSRC will cause the counters to reset to 0.
1637 // EXPECT_GT(*track_stats[0]->total_samples_received, prev_samples_received);
1638
1639 // Additionally, the percentage of concealed samples (samples generated to
Steve Anton83119dd2017-11-10 16:19:52 -08001640 // conceal packet loss) should be less than 50%. If it's greater, that's a
deadbeef4e2deab2017-09-20 13:56:21 -07001641 // good sign that we're seeing stats from the old stream that's no longer
1642 // receiving packets, and is generating concealed samples of silence.
Steve Anton83119dd2017-11-10 16:19:52 -08001643 constexpr double kAcceptableConcealedSamplesPercentage = 0.50;
deadbeef4e2deab2017-09-20 13:56:21 -07001644 ASSERT_TRUE(track_stats[0]->concealed_samples.is_defined());
1645 EXPECT_LT(*track_stats[0]->concealed_samples,
1646 *track_stats[0]->total_samples_received *
1647 kAcceptableConcealedSamplesPercentage);
1648
1649 // Also ensure that we have two "RTCInboundRTPStreamStats" as expected, as a
1650 // sanity check that the SSRC really changed.
1651 // TODO(deadbeef): This isn't working right now, because we're not returning
1652 // *any* stats for the inactive stream. Uncomment when the bug is completely
1653 // fixed.
1654 // auto inbound_stream_stats =
1655 // report->GetStatsOfType<webrtc::RTCInboundRTPStreamStats>();
1656 // ASSERT_EQ(2U, inbound_stream_stats.size());
1657}
1658
deadbeef1dcb1642017-03-29 21:08:16 -07001659// Test that DTLS 1.0 is used if both sides only support DTLS 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001660TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001661 PeerConnectionFactory::Options dtls_10_options;
1662 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1663 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1664 dtls_10_options));
1665 ConnectFakeSignaling();
1666 // Do normal offer/answer and wait for some frames to be received in each
1667 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001668 caller()->AddAudioVideoTracks();
1669 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001670 caller()->CreateAndSetAndSignalOffer();
1671 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001672 MediaExpectations media_expectations;
1673 media_expectations.ExpectBidirectionalAudioAndVideo();
1674 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001675}
1676
1677// Test getting cipher stats and UMA metrics when DTLS 1.0 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001678TEST_P(PeerConnectionIntegrationTest, Dtls10CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001679 PeerConnectionFactory::Options dtls_10_options;
1680 dtls_10_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1681 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_10_options,
1682 dtls_10_options));
1683 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001684 caller()->AddAudioVideoTracks();
1685 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001686 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001687 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001688 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001689 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001690 kDefaultTimeout);
1691 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001692 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001693 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001694 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1695 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1696 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001697}
1698
1699// Test getting cipher stats and UMA metrics when DTLS 1.2 is negotiated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001700TEST_P(PeerConnectionIntegrationTest, Dtls12CipherStatsAndUmaMetrics) {
deadbeef1dcb1642017-03-29 21:08:16 -07001701 PeerConnectionFactory::Options dtls_12_options;
1702 dtls_12_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1703 ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(dtls_12_options,
1704 dtls_12_options));
1705 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08001706 caller()->AddAudioVideoTracks();
1707 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001708 caller()->CreateAndSetAndSignalOffer();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001709 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001710 EXPECT_TRUE_WAIT(rtc::SSLStreamAdapter::IsAcceptableCipher(
deadbeefd8ad7882017-04-18 16:01:17 -07001711 caller()->OldGetStats()->DtlsCipher(), rtc::KT_DEFAULT),
deadbeef1dcb1642017-03-29 21:08:16 -07001712 kDefaultTimeout);
1713 EXPECT_EQ_WAIT(rtc::SrtpCryptoSuiteToName(kDefaultSrtpCryptoSuite),
deadbeefd8ad7882017-04-18 16:01:17 -07001714 caller()->OldGetStats()->SrtpCipher(), kDefaultTimeout);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07001715 // TODO(bugs.webrtc.org/9456): Fix it.
Ying Wangef3998f2019-12-09 13:06:53 +01001716 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1717 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
1718 kDefaultSrtpCryptoSuite));
deadbeef1dcb1642017-03-29 21:08:16 -07001719}
1720
1721// Test that DTLS 1.0 can be used if the caller supports DTLS 1.2 and the
1722// callee only supports 1.0.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001723TEST_P(PeerConnectionIntegrationTest, CallerDtls12ToCalleeDtls10) {
deadbeef1dcb1642017-03-29 21:08:16 -07001724 PeerConnectionFactory::Options caller_options;
1725 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1726 PeerConnectionFactory::Options callee_options;
1727 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1728 ASSERT_TRUE(
1729 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1730 ConnectFakeSignaling();
1731 // Do normal offer/answer and wait for some frames to be received in each
1732 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001733 caller()->AddAudioVideoTracks();
1734 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001735 caller()->CreateAndSetAndSignalOffer();
1736 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001737 MediaExpectations media_expectations;
1738 media_expectations.ExpectBidirectionalAudioAndVideo();
1739 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001740}
1741
1742// Test that DTLS 1.0 can be used if the caller only supports DTLS 1.0 and the
1743// callee supports 1.2.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001744TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
deadbeef1dcb1642017-03-29 21:08:16 -07001745 PeerConnectionFactory::Options caller_options;
1746 caller_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
1747 PeerConnectionFactory::Options callee_options;
1748 callee_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
1749 ASSERT_TRUE(
1750 CreatePeerConnectionWrappersWithOptions(caller_options, callee_options));
1751 ConnectFakeSignaling();
1752 // Do normal offer/answer and wait for some frames to be received in each
1753 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001754 caller()->AddAudioVideoTracks();
1755 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001756 caller()->CreateAndSetAndSignalOffer();
1757 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001758 MediaExpectations media_expectations;
1759 media_expectations.ExpectBidirectionalAudioAndVideo();
1760 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07001761}
1762
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001763// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
1764// works as expected; the cipher should only be used if enabled by both sides.
1765TEST_P(PeerConnectionIntegrationTest,
1766 Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
1767 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001768 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001769 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001770 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1771 false;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001772 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001773 TestNegotiatedCipherSuite(caller_options, callee_options,
1774 expected_cipher_suite);
1775}
1776
1777TEST_P(PeerConnectionIntegrationTest,
1778 Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
1779 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001780 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher =
1781 false;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001782 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001783 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001784 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_80;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001785 TestNegotiatedCipherSuite(caller_options, callee_options,
1786 expected_cipher_suite);
1787}
1788
1789TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
1790 PeerConnectionFactory::Options caller_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001791 caller_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001792 PeerConnectionFactory::Options callee_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001793 callee_options.crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher = true;
Mirko Bonadei7750d802021-07-26 17:27:42 +02001794 int expected_cipher_suite = rtc::kSrtpAes128CmSha1_32;
Taylor Brandstetter5e55fe82018-03-23 11:50:16 -07001795 TestNegotiatedCipherSuite(caller_options, callee_options,
1796 expected_cipher_suite);
1797}
1798
deadbeef1dcb1642017-03-29 21:08:16 -07001799// Test that a non-GCM cipher is used if both sides only support non-GCM.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001800TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001801 bool local_gcm_enabled = false;
1802 bool remote_gcm_enabled = false;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001803 bool aes_ctr_enabled = true;
deadbeef1dcb1642017-03-29 21:08:16 -07001804 int expected_cipher_suite = kDefaultSrtpCryptoSuite;
1805 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001806 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001807}
1808
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001809// Test that a GCM cipher is used if both ends support it and non-GCM is
1810// disabled.
1811TEST_P(PeerConnectionIntegrationTest, GcmCipherUsedWhenOnlyGcmSupported) {
deadbeef1dcb1642017-03-29 21:08:16 -07001812 bool local_gcm_enabled = true;
1813 bool remote_gcm_enabled = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001814 bool aes_ctr_enabled = false;
deadbeef1dcb1642017-03-29 21:08:16 -07001815 int expected_cipher_suite = kDefaultSrtpCryptoSuiteGcm;
1816 TestGcmNegotiationUsesCipherSuite(local_gcm_enabled, remote_gcm_enabled,
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001817 aes_ctr_enabled, expected_cipher_suite);
deadbeef1dcb1642017-03-29 21:08:16 -07001818}
1819
deadbeef7914b8c2017-04-21 03:23:33 -07001820// Verify that media can be transmitted end-to-end when GCM crypto suites are
1821// enabled. Note that the above tests, such as GcmCipherUsedWhenGcmSupported,
1822// only verify that a GCM cipher is negotiated, and not necessarily that SRTP
1823// works with it.
Seth Hampson2f0d7022018-02-20 11:54:42 -08001824TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithGcmCipher) {
deadbeef7914b8c2017-04-21 03:23:33 -07001825 PeerConnectionFactory::Options gcm_options;
Benjamin Wrighta54daf12018-10-11 15:33:17 -07001826 gcm_options.crypto_options.srtp.enable_gcm_crypto_suites = true;
Philipp Hancke2ebbff82019-10-26 06:12:55 +02001827 gcm_options.crypto_options.srtp.enable_aes128_sha1_80_crypto_cipher = false;
deadbeef7914b8c2017-04-21 03:23:33 -07001828 ASSERT_TRUE(
1829 CreatePeerConnectionWrappersWithOptions(gcm_options, gcm_options));
1830 ConnectFakeSignaling();
1831 // Do normal offer/answer and wait for some frames to be received in each
1832 // direction.
Steve Anton15324772018-01-16 10:26:49 -08001833 caller()->AddAudioVideoTracks();
1834 callee()->AddAudioVideoTracks();
deadbeef7914b8c2017-04-21 03:23:33 -07001835 caller()->CreateAndSetAndSignalOffer();
1836 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08001837 MediaExpectations media_expectations;
1838 media_expectations.ExpectBidirectionalAudioAndVideo();
1839 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef7914b8c2017-04-21 03:23:33 -07001840}
1841
deadbeef1dcb1642017-03-29 21:08:16 -07001842// Test that the ICE connection and gathering states eventually reach
1843// "complete".
Seth Hampson2f0d7022018-02-20 11:54:42 -08001844TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) {
deadbeef1dcb1642017-03-29 21:08:16 -07001845 ASSERT_TRUE(CreatePeerConnectionWrappers());
1846 ConnectFakeSignaling();
1847 // Do normal offer/answer.
Steve Anton15324772018-01-16 10:26:49 -08001848 caller()->AddAudioVideoTracks();
1849 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07001850 caller()->CreateAndSetAndSignalOffer();
1851 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1852 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1853 caller()->ice_gathering_state(), kMaxWaitForFramesMs);
1854 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceGatheringComplete,
1855 callee()->ice_gathering_state(), kMaxWaitForFramesMs);
1856 // After the best candidate pair is selected and all candidates are signaled,
1857 // the ICE connection state should reach "complete".
1858 // TODO(deadbeef): Currently, the ICE "controlled" agent (the
1859 // answerer/"callee" by default) only reaches "connected". When this is
1860 // fixed, this test should be updated.
1861 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1862 caller()->ice_connection_state(), kDefaultTimeout);
Alex Loiko9289eda2018-11-23 16:18:59 +00001863 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1864 callee()->ice_connection_state(), kDefaultTimeout);
deadbeef1dcb1642017-03-29 21:08:16 -07001865}
1866
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001867#if !defined(THREAD_SANITIZER)
1868// This test provokes TSAN errors. See bugs.webrtc.org/3608
1869
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001870constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
1871 cricket::PORTALLOCATOR_DISABLE_RELAY |
1872 cricket::PORTALLOCATOR_DISABLE_TCP;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001873
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001874// Use a mock resolver to resolve the hostname back to the original IP on both
1875// sides and check that the ICE connection connects.
Markus Handell56910532021-04-10 11:23:14 +00001876// TODO(bugs.webrtc.org/12590): Flaky on Windows and on Linux MSAN.
1877#if defined(WEBRTC_WIN) || defined(WEBRTC_LINUX)
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001878#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1879 DISABLED_IceStatesReachCompletionWithRemoteHostname
1880#else
1881#define MAYBE_IceStatesReachCompletionWithRemoteHostname \
1882 IceStatesReachCompletionWithRemoteHostname
1883#endif
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001884TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt32af25b2021-03-17 13:40:21 +01001885 MAYBE_IceStatesReachCompletionWithRemoteHostname) {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001886 auto caller_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001887 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001888 auto callee_resolver_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001889 std::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001890 NiceMock<rtc::MockAsyncResolver> callee_async_resolver;
1891 NiceMock<rtc::MockAsyncResolver> caller_async_resolver;
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001892
1893 // This also verifies that the injected AsyncResolverFactory is used by
1894 // P2PTransportChannel.
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001895 EXPECT_CALL(*caller_resolver_factory, Create())
1896 .WillOnce(Return(&caller_async_resolver));
1897 webrtc::PeerConnectionDependencies caller_deps(nullptr);
1898 caller_deps.async_resolver_factory = std::move(caller_resolver_factory);
1899
1900 EXPECT_CALL(*callee_resolver_factory, Create())
1901 .WillOnce(Return(&callee_async_resolver));
1902 webrtc::PeerConnectionDependencies callee_deps(nullptr);
1903 callee_deps.async_resolver_factory = std::move(callee_resolver_factory);
1904
1905 PeerConnectionInterface::RTCConfiguration config;
1906 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
1907 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
1908
1909 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
1910 config, std::move(caller_deps), config, std::move(callee_deps)));
1911
1912 caller()->SetRemoteAsyncResolver(&callee_async_resolver);
1913 callee()->SetRemoteAsyncResolver(&caller_async_resolver);
1914
1915 // Enable hostname candidates with mDNS names.
Qingsi Wangecd30542019-05-22 14:34:56 -07001916 caller()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001917 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wangecd30542019-05-22 14:34:56 -07001918 callee()->SetMdnsResponder(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001919 std::make_unique<webrtc::FakeMdnsResponder>(network_thread()));
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001920
1921 SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts);
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001922
1923 ConnectFakeSignaling();
1924 caller()->AddAudioVideoTracks();
1925 callee()->AddAudioVideoTracks();
1926 caller()->CreateAndSetAndSignalOffer();
1927 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
1928 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
1929 caller()->ice_connection_state(), kDefaultTimeout);
1930 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
1931 callee()->ice_connection_state(), kDefaultTimeout);
Jeroen de Borst833979f2018-12-13 08:25:54 -08001932
Ying Wangef3998f2019-12-09 13:06:53 +01001933 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
1934 "WebRTC.PeerConnection.CandidatePairType_UDP",
1935 webrtc::kIceCandidatePairHostNameHostName));
Zach Stein6fcdc2f2018-08-23 16:25:55 -07001936}
1937
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00001938#endif // !defined(THREAD_SANITIZER)
1939
Steve Antonede9ca52017-10-16 13:04:27 -07001940// Test that firewalling the ICE connection causes the clients to identify the
1941// disconnected state and then removing the firewall causes them to reconnect.
1942class PeerConnectionIntegrationIceStatesTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08001943 : public PeerConnectionIntegrationBaseTest,
1944 public ::testing::WithParamInterface<
1945 std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
Steve Antonede9ca52017-10-16 13:04:27 -07001946 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08001947 PeerConnectionIntegrationIceStatesTest()
1948 : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
1949 port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
Steve Antonede9ca52017-10-16 13:04:27 -07001950 }
1951
1952 void StartStunServer(const SocketAddress& server_address) {
1953 stun_server_.reset(
Niels Möller091617d2020-12-02 15:32:08 +01001954 cricket::TestStunServer::Create(firewall(), server_address));
Steve Antonede9ca52017-10-16 13:04:27 -07001955 }
1956
1957 bool TestIPv6() {
1958 return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
1959 }
1960
1961 void SetPortAllocatorFlags() {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08001962 PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
1963 port_allocator_flags_, port_allocator_flags_);
Steve Antonede9ca52017-10-16 13:04:27 -07001964 }
1965
1966 std::vector<SocketAddress> CallerAddresses() {
1967 std::vector<SocketAddress> addresses;
1968 addresses.push_back(SocketAddress("1.1.1.1", 0));
1969 if (TestIPv6()) {
1970 addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
1971 }
1972 return addresses;
1973 }
1974
1975 std::vector<SocketAddress> CalleeAddresses() {
1976 std::vector<SocketAddress> addresses;
1977 addresses.push_back(SocketAddress("2.2.2.2", 0));
1978 if (TestIPv6()) {
1979 addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
1980 }
1981 return addresses;
1982 }
1983
1984 void SetUpNetworkInterfaces() {
1985 // Remove the default interfaces added by the test infrastructure.
Qingsi Wangecd30542019-05-22 14:34:56 -07001986 caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
1987 callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
Steve Antonede9ca52017-10-16 13:04:27 -07001988
1989 // Add network addresses for test.
1990 for (const auto& caller_address : CallerAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001991 caller()->network_manager()->AddInterface(caller_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001992 }
1993 for (const auto& callee_address : CalleeAddresses()) {
Qingsi Wangecd30542019-05-22 14:34:56 -07001994 callee()->network_manager()->AddInterface(callee_address);
Steve Antonede9ca52017-10-16 13:04:27 -07001995 }
1996 }
1997
1998 private:
1999 uint32_t port_allocator_flags_;
2000 std::unique_ptr<cricket::TestStunServer> stun_server_;
2001};
2002
Yves Gerey100fe632020-01-17 19:15:53 +01002003// Ensure FakeClockForTest is constructed first (see class for rationale).
2004class PeerConnectionIntegrationIceStatesTestWithFakeClock
2005 : public FakeClockForTest,
2006 public PeerConnectionIntegrationIceStatesTest {};
2007
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002008#if !defined(THREAD_SANITIZER)
2009// This test provokes TSAN errors. bugs.webrtc.org/11282
2010
Steve Antonede9ca52017-10-16 13:04:27 -07002011// Tests that the PeerConnection goes through all the ICE gathering/connection
2012// states over the duration of the call. This includes Disconnected and Failed
2013// states, induced by putting a firewall between the peers and waiting for them
2014// to time out.
Yves Gerey100fe632020-01-17 19:15:53 +01002015TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) {
Steve Antonede9ca52017-10-16 13:04:27 -07002016 const SocketAddress kStunServerAddress =
2017 SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
2018 StartStunServer(kStunServerAddress);
2019
2020 PeerConnectionInterface::RTCConfiguration config;
2021 PeerConnectionInterface::IceServer ice_stun_server;
2022 ice_stun_server.urls.push_back(
2023 "stun:" + kStunServerAddress.HostAsURIString() + ":" +
2024 kStunServerAddress.PortAsString());
2025 config.servers.push_back(ice_stun_server);
2026
2027 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2028 ConnectFakeSignaling();
2029 SetPortAllocatorFlags();
2030 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08002031 caller()->AddAudioVideoTracks();
2032 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002033
2034 // Initial state before anything happens.
2035 ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
2036 caller()->ice_gathering_state());
2037 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
2038 caller()->ice_connection_state());
Jonas Olsson7a6739e2019-01-15 16:31:55 +01002039 ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
2040 caller()->standardized_ice_connection_state());
Steve Antonede9ca52017-10-16 13:04:27 -07002041
2042 // Start the call by creating the offer, setting it as the local description,
2043 // then sending it to the peer who will respond with an answer. This happens
2044 // asynchronously so that we can watch the states as it runs in the
2045 // background.
2046 caller()->CreateAndSetAndSignalOffer();
2047
Steve Antona9b67ce2020-01-16 14:00:44 -08002048 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2049 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002050 FakeClock());
Steve Antona9b67ce2020-01-16 14:00:44 -08002051 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2052 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002053 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002054
2055 // Verify that the observer was notified of the intermediate transitions.
2056 EXPECT_THAT(caller()->ice_connection_state_history(),
2057 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
2058 PeerConnectionInterface::kIceConnectionConnected,
2059 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olssonacd8ae72019-02-25 15:26:24 +01002060 EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
2061 ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
2062 PeerConnectionInterface::kIceConnectionConnected,
2063 PeerConnectionInterface::kIceConnectionCompleted));
Jonas Olsson635474e2018-10-18 15:58:17 +02002064 EXPECT_THAT(
2065 caller()->peer_connection_state_history(),
2066 ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
Jonas Olsson635474e2018-10-18 15:58:17 +02002067 PeerConnectionInterface::PeerConnectionState::kConnected));
Steve Antonede9ca52017-10-16 13:04:27 -07002068 EXPECT_THAT(caller()->ice_gathering_state_history(),
2069 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
2070 PeerConnectionInterface::kIceGatheringComplete));
2071
2072 // Block connections to/from the caller and wait for ICE to become
2073 // disconnected.
2074 for (const auto& caller_address : CallerAddresses()) {
2075 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2076 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01002077 RTC_LOG(LS_INFO) << "Firewall rules applied";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002078 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2079 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002080 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002081 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
2082 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002083 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002084
2085 // Let ICE re-establish by removing the firewall rules.
2086 firewall()->ClearRules();
Mirko Bonadei675513b2017-11-09 11:09:25 +01002087 RTC_LOG(LS_INFO) << "Firewall rules cleared";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002088 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2089 caller()->ice_connection_state(), kDefaultTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002090 FakeClock());
Jonas Olssonacd8ae72019-02-25 15:26:24 +01002091 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002092 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002093 kDefaultTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002094
2095 // According to RFC7675, if there is no response within 30 seconds then the
2096 // peer should consider the other side to have rejected the connection. This
Steve Anton83119dd2017-11-10 16:19:52 -08002097 // is signaled by the state transitioning to "failed".
Steve Antonede9ca52017-10-16 13:04:27 -07002098 constexpr int kConsentTimeout = 30000;
2099 for (const auto& caller_address : CallerAddresses()) {
2100 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2101 }
Mirko Bonadei675513b2017-11-09 11:09:25 +01002102 RTC_LOG(LS_INFO) << "Firewall rules applied again";
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002103 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2104 caller()->ice_connection_state(), kConsentTimeout,
Yves Gerey100fe632020-01-17 19:15:53 +01002105 FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002106 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2107 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002108 kConsentTimeout, FakeClock());
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002109}
2110
2111// Tests that if the connection doesn't get set up properly we eventually reach
2112// the "failed" iceConnectionState.
Yves Gerey100fe632020-01-17 19:15:53 +01002113TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,
2114 IceStateSetupFailure) {
Jonas Olssonb75d9e92019-02-22 10:33:29 +01002115 // Block connections to/from the caller and wait for ICE to become
2116 // disconnected.
2117 for (const auto& caller_address : CallerAddresses()) {
2118 firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
2119 }
2120
2121 ASSERT_TRUE(CreatePeerConnectionWrappers());
2122 ConnectFakeSignaling();
2123 SetPortAllocatorFlags();
2124 SetUpNetworkInterfaces();
2125 caller()->AddAudioVideoTracks();
2126 caller()->CreateAndSetAndSignalOffer();
2127
2128 // According to RFC7675, if there is no response within 30 seconds then the
2129 // peer should consider the other side to have rejected the connection. This
2130 // is signaled by the state transitioning to "failed".
2131 constexpr int kConsentTimeout = 30000;
2132 ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
2133 caller()->standardized_ice_connection_state(),
Yves Gerey100fe632020-01-17 19:15:53 +01002134 kConsentTimeout, FakeClock());
Steve Antonede9ca52017-10-16 13:04:27 -07002135}
2136
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002137#endif // !defined(THREAD_SANITIZER)
2138
Steve Antonede9ca52017-10-16 13:04:27 -07002139// Tests that the best connection is set to the appropriate IPv4/IPv6 connection
2140// and that the statistics in the metric observers are updated correctly.
Rasmus Brandt32af25b2021-03-17 13:40:21 +01002141// TODO(bugs.webrtc.org/12591): Flaky on Windows.
2142#if defined(WEBRTC_WIN)
2143#define MAYBE_VerifyBestConnection DISABLED_VerifyBestConnection
2144#else
2145#define MAYBE_VerifyBestConnection VerifyBestConnection
2146#endif
2147TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
Steve Antonede9ca52017-10-16 13:04:27 -07002148 ASSERT_TRUE(CreatePeerConnectionWrappers());
2149 ConnectFakeSignaling();
2150 SetPortAllocatorFlags();
2151 SetUpNetworkInterfaces();
Steve Anton15324772018-01-16 10:26:49 -08002152 caller()->AddAudioVideoTracks();
2153 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07002154 caller()->CreateAndSetAndSignalOffer();
2155
2156 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Anton692f3c72020-01-16 14:12:31 -08002157 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2158 caller()->ice_connection_state(), kDefaultTimeout);
2159 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2160 callee()->ice_connection_state(), kDefaultTimeout);
Steve Antonede9ca52017-10-16 13:04:27 -07002161
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002162 // TODO(bugs.webrtc.org/9456): Fix it.
2163 const int num_best_ipv4 = webrtc::metrics::NumEvents(
2164 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
2165 const int num_best_ipv6 = webrtc::metrics::NumEvents(
2166 "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002167 if (TestIPv6()) {
2168 // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4
2169 // connection.
Ying Wangef3998f2019-12-09 13:06:53 +01002170 EXPECT_METRIC_EQ(0, num_best_ipv4);
2171 EXPECT_METRIC_EQ(1, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002172 } else {
Ying Wangef3998f2019-12-09 13:06:53 +01002173 EXPECT_METRIC_EQ(1, num_best_ipv4);
2174 EXPECT_METRIC_EQ(0, num_best_ipv6);
Steve Antonede9ca52017-10-16 13:04:27 -07002175 }
2176
Ying Wangef3998f2019-12-09 13:06:53 +01002177 EXPECT_METRIC_EQ(0, webrtc::metrics::NumEvents(
2178 "WebRTC.PeerConnection.CandidatePairType_UDP",
2179 webrtc::kIceCandidatePairHostHost));
2180 EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
2181 "WebRTC.PeerConnection.CandidatePairType_UDP",
2182 webrtc::kIceCandidatePairHostPublicHostPublic));
Steve Antonede9ca52017-10-16 13:04:27 -07002183}
2184
2185constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
2186 cricket::PORTALLOCATOR_DISABLE_STUN |
2187 cricket::PORTALLOCATOR_DISABLE_RELAY;
2188constexpr uint32_t kFlagsIPv6NoStun =
2189 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
2190 cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
2191constexpr uint32_t kFlagsIPv4Stun =
2192 cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
2193
Mirko Bonadeic84f6612019-01-31 12:20:57 +01002194INSTANTIATE_TEST_SUITE_P(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002195 PeerConnectionIntegrationTest,
2196 PeerConnectionIntegrationIceStatesTest,
2197 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
2198 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2199 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2200 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
Steve Antonede9ca52017-10-16 13:04:27 -07002201
Yves Gerey100fe632020-01-17 19:15:53 +01002202INSTANTIATE_TEST_SUITE_P(
2203 PeerConnectionIntegrationTest,
2204 PeerConnectionIntegrationIceStatesTestWithFakeClock,
2205 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
2206 Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
2207 std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
2208 std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
2209
deadbeef1dcb1642017-03-29 21:08:16 -07002210// This test sets up a call between two parties with audio and video.
2211// During the call, the caller restarts ICE and the test verifies that
2212// new ICE candidates are generated and audio and video still can flow, and the
2213// ICE state reaches completed again.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002214TEST_P(PeerConnectionIntegrationTest, MediaContinuesFlowingAfterIceRestart) {
deadbeef1dcb1642017-03-29 21:08:16 -07002215 ASSERT_TRUE(CreatePeerConnectionWrappers());
2216 ConnectFakeSignaling();
2217 // Do normal offer/answer and wait for ICE to complete.
Steve Anton15324772018-01-16 10:26:49 -08002218 caller()->AddAudioVideoTracks();
2219 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002220 caller()->CreateAndSetAndSignalOffer();
2221 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2222 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2223 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002224 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2225 callee()->ice_connection_state(), kMaxWaitForFramesMs);
deadbeef1dcb1642017-03-29 21:08:16 -07002226
2227 // To verify that the ICE restart actually occurs, get
2228 // ufrag/password/candidates before and after restart.
2229 // Create an SDP string of the first audio candidate for both clients.
2230 const webrtc::IceCandidateCollection* audio_candidates_caller =
2231 caller()->pc()->local_description()->candidates(0);
2232 const webrtc::IceCandidateCollection* audio_candidates_callee =
2233 callee()->pc()->local_description()->candidates(0);
2234 ASSERT_GT(audio_candidates_caller->count(), 0u);
2235 ASSERT_GT(audio_candidates_callee->count(), 0u);
2236 std::string caller_candidate_pre_restart;
2237 ASSERT_TRUE(
2238 audio_candidates_caller->at(0)->ToString(&caller_candidate_pre_restart));
2239 std::string callee_candidate_pre_restart;
2240 ASSERT_TRUE(
2241 audio_candidates_callee->at(0)->ToString(&callee_candidate_pre_restart));
2242 const cricket::SessionDescription* desc =
2243 caller()->pc()->local_description()->description();
2244 std::string caller_ufrag_pre_restart =
2245 desc->transport_infos()[0].description.ice_ufrag;
2246 desc = callee()->pc()->local_description()->description();
2247 std::string callee_ufrag_pre_restart =
2248 desc->transport_infos()[0].description.ice_ufrag;
2249
Alex Drake00c7ecf2019-08-06 10:54:47 -07002250 EXPECT_EQ(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002251 // Have the caller initiate an ICE restart.
2252 caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
2253 caller()->CreateAndSetAndSignalOffer();
2254 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2255 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2256 caller()->ice_connection_state(), kMaxWaitForFramesMs);
Alex Loiko9289eda2018-11-23 16:18:59 +00002257 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
deadbeef1dcb1642017-03-29 21:08:16 -07002258 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2259
2260 // Grab the ufrags/candidates again.
2261 audio_candidates_caller = caller()->pc()->local_description()->candidates(0);
2262 audio_candidates_callee = callee()->pc()->local_description()->candidates(0);
2263 ASSERT_GT(audio_candidates_caller->count(), 0u);
2264 ASSERT_GT(audio_candidates_callee->count(), 0u);
2265 std::string caller_candidate_post_restart;
2266 ASSERT_TRUE(
2267 audio_candidates_caller->at(0)->ToString(&caller_candidate_post_restart));
2268 std::string callee_candidate_post_restart;
2269 ASSERT_TRUE(
2270 audio_candidates_callee->at(0)->ToString(&callee_candidate_post_restart));
2271 desc = caller()->pc()->local_description()->description();
2272 std::string caller_ufrag_post_restart =
2273 desc->transport_infos()[0].description.ice_ufrag;
2274 desc = callee()->pc()->local_description()->description();
2275 std::string callee_ufrag_post_restart =
2276 desc->transport_infos()[0].description.ice_ufrag;
2277 // Sanity check that an ICE restart was actually negotiated in SDP.
2278 ASSERT_NE(caller_candidate_pre_restart, caller_candidate_post_restart);
2279 ASSERT_NE(callee_candidate_pre_restart, callee_candidate_post_restart);
2280 ASSERT_NE(caller_ufrag_pre_restart, caller_ufrag_post_restart);
2281 ASSERT_NE(callee_ufrag_pre_restart, callee_ufrag_post_restart);
Alex Drake00c7ecf2019-08-06 10:54:47 -07002282 EXPECT_GT(caller()->ice_candidate_pair_change_history().size(), 1u);
deadbeef1dcb1642017-03-29 21:08:16 -07002283
2284 // Ensure that additional frames are received after the ICE restart.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002285 MediaExpectations media_expectations;
2286 media_expectations.ExpectBidirectionalAudioAndVideo();
2287 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002288}
2289
2290// Verify that audio/video can be received end-to-end when ICE renomination is
2291// enabled.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002292TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithIceRenomination) {
deadbeef1dcb1642017-03-29 21:08:16 -07002293 PeerConnectionInterface::RTCConfiguration config;
2294 config.enable_ice_renomination = true;
2295 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
2296 ConnectFakeSignaling();
2297 // Do normal offer/answer and wait for some frames to be received in each
2298 // direction.
Steve Anton15324772018-01-16 10:26:49 -08002299 caller()->AddAudioVideoTracks();
2300 callee()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002301 caller()->CreateAndSetAndSignalOffer();
2302 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2303 // Sanity check that ICE renomination was actually negotiated.
2304 const cricket::SessionDescription* desc =
2305 caller()->pc()->local_description()->description();
2306 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002307 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002308 }
2309 desc = callee()->pc()->local_description()->description();
2310 for (const cricket::TransportInfo& info : desc->transport_infos()) {
Steve Anton64b626b2019-01-28 17:25:26 -08002311 ASSERT_THAT(info.description.transport_options, Contains("renomination"));
deadbeef1dcb1642017-03-29 21:08:16 -07002312 }
Seth Hampson2f0d7022018-02-20 11:54:42 -08002313 MediaExpectations media_expectations;
2314 media_expectations.ExpectBidirectionalAudioAndVideo();
2315 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002316}
2317
Steve Anton6f25b092017-10-23 09:39:20 -07002318// With a max bundle policy and RTCP muxing, adding a new media description to
2319// the connection should not affect ICE at all because the new media will use
2320// the existing connection.
Rasmus Brandt685be142021-03-15 14:03:38 +01002321// TODO(bugs.webrtc.org/12538): Fails on tsan.
2322#if defined(THREAD_SANITIZER)
2323#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2324 DISABLED_AddMediaToConnectedBundleDoesNotRestartIce
2325#else
2326#define MAYBE_AddMediaToConnectedBundleDoesNotRestartIce \
2327 AddMediaToConnectedBundleDoesNotRestartIce
2328#endif
Seth Hampson2f0d7022018-02-20 11:54:42 -08002329TEST_P(PeerConnectionIntegrationTest,
Rasmus Brandt685be142021-03-15 14:03:38 +01002330 MAYBE_AddMediaToConnectedBundleDoesNotRestartIce) {
Steve Anton6f25b092017-10-23 09:39:20 -07002331 PeerConnectionInterface::RTCConfiguration config;
2332 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
2333 config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
2334 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
2335 config, PeerConnectionInterface::RTCConfiguration()));
2336 ConnectFakeSignaling();
2337
Steve Anton15324772018-01-16 10:26:49 -08002338 caller()->AddAudioTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002339 caller()->CreateAndSetAndSignalOffer();
2340 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Steve Antonff52f1b2017-10-26 12:24:50 -07002341 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
2342 caller()->ice_connection_state(), kDefaultTimeout);
Steve Anton6f25b092017-10-23 09:39:20 -07002343
2344 caller()->clear_ice_connection_state_history();
2345
Steve Anton15324772018-01-16 10:26:49 -08002346 caller()->AddVideoTrack();
Steve Anton6f25b092017-10-23 09:39:20 -07002347 caller()->CreateAndSetAndSignalOffer();
2348 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2349
2350 EXPECT_EQ(0u, caller()->ice_connection_state_history().size());
2351}
2352
deadbeef1dcb1642017-03-29 21:08:16 -07002353// This test sets up a call between two parties with audio and video. It then
2354// renegotiates setting the video m-line to "port 0", then later renegotiates
2355// again, enabling video.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002356TEST_P(PeerConnectionIntegrationTest,
deadbeef1dcb1642017-03-29 21:08:16 -07002357 VideoFlowsAfterMediaSectionIsRejectedAndRecycled) {
2358 ASSERT_TRUE(CreatePeerConnectionWrappers());
2359 ConnectFakeSignaling();
2360
2361 // Do initial negotiation, only sending media from the caller. Will result in
2362 // video and audio recvonly "m=" sections.
Steve Anton15324772018-01-16 10:26:49 -08002363 caller()->AddAudioVideoTracks();
deadbeef1dcb1642017-03-29 21:08:16 -07002364 caller()->CreateAndSetAndSignalOffer();
2365 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2366
2367 // Negotiate again, disabling the video "m=" section (the callee will set the
2368 // port to 0 due to offer_to_receive_video = 0).
Seth Hampson2f0d7022018-02-20 11:54:42 -08002369 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2370 PeerConnectionInterface::RTCOfferAnswerOptions options;
2371 options.offer_to_receive_video = 0;
2372 callee()->SetOfferAnswerOptions(options);
2373 } else {
2374 callee()->SetRemoteOfferHandler([this] {
Harald Alvestrand6060df52020-08-11 09:54:02 +02002375 callee()
2376 ->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
2377 ->StopInternal();
Seth Hampson2f0d7022018-02-20 11:54:42 -08002378 });
2379 }
deadbeef1dcb1642017-03-29 21:08:16 -07002380 caller()->CreateAndSetAndSignalOffer();
2381 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2382 // Sanity check that video "m=" section was actually rejected.
2383 const ContentInfo* answer_video_content = cricket::GetFirstVideoContent(
2384 callee()->pc()->local_description()->description());
2385 ASSERT_NE(nullptr, answer_video_content);
2386 ASSERT_TRUE(answer_video_content->rejected);
2387
2388 // Enable video and do negotiation again, making sure video is received
2389 // end-to-end, also adding media stream to callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002390 if (sdp_semantics_ == SdpSemantics::kPlanB) {
2391 PeerConnectionInterface::RTCOfferAnswerOptions options;
2392 options.offer_to_receive_video = 1;
2393 callee()->SetOfferAnswerOptions(options);
2394 } else {
2395 // The caller's transceiver is stopped, so we need to add another track.
2396 auto caller_transceiver =
2397 caller()->GetFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002398 EXPECT_EQ(nullptr, caller_transceiver.get());
Seth Hampson2f0d7022018-02-20 11:54:42 -08002399 caller()->AddVideoTrack();
2400 }
2401 callee()->AddVideoTrack();
2402 callee()->SetRemoteOfferHandler(nullptr);
deadbeef1dcb1642017-03-29 21:08:16 -07002403 caller()->CreateAndSetAndSignalOffer();
2404 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002405
deadbeef1dcb1642017-03-29 21:08:16 -07002406 // Verify the caller receives frames from the newly added stream, and the
2407 // callee receives additional frames from the re-enabled video m= section.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002408 MediaExpectations media_expectations;
2409 media_expectations.CalleeExpectsSomeAudio();
2410 media_expectations.ExpectBidirectionalVideo();
2411 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002412}
2413
deadbeef1dcb1642017-03-29 21:08:16 -07002414// This tests that if we negotiate after calling CreateSender but before we
2415// have a track, then set a track later, frames from the newly-set track are
2416// received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002417TEST_F(PeerConnectionIntegrationTestPlanB,
deadbeef1dcb1642017-03-29 21:08:16 -07002418 MediaFlowsAfterEarlyWarmupWithCreateSender) {
2419 ASSERT_TRUE(CreatePeerConnectionWrappers());
2420 ConnectFakeSignaling();
2421 auto caller_audio_sender =
2422 caller()->pc()->CreateSender("audio", "caller_stream");
2423 auto caller_video_sender =
2424 caller()->pc()->CreateSender("video", "caller_stream");
2425 auto callee_audio_sender =
2426 callee()->pc()->CreateSender("audio", "callee_stream");
2427 auto callee_video_sender =
2428 callee()->pc()->CreateSender("video", "callee_stream");
2429 caller()->CreateAndSetAndSignalOffer();
2430 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2431 // Wait for ICE to complete, without any tracks being set.
2432 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2433 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2434 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2435 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2436 // Now set the tracks, and expect frames to immediately start flowing.
2437 EXPECT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
2438 EXPECT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
2439 EXPECT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
2440 EXPECT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
Seth Hampson2f0d7022018-02-20 11:54:42 -08002441 MediaExpectations media_expectations;
2442 media_expectations.ExpectBidirectionalAudioAndVideo();
2443 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2444}
2445
2446// This tests that if we negotiate after calling AddTransceiver but before we
2447// have a track, then set a track later, frames from the newly-set tracks are
2448// received end-to-end.
2449TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
2450 MediaFlowsAfterEarlyWarmupWithAddTransceiver) {
2451 ASSERT_TRUE(CreatePeerConnectionWrappers());
2452 ConnectFakeSignaling();
2453 auto audio_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
2454 ASSERT_EQ(RTCErrorType::NONE, audio_result.error().type());
2455 auto caller_audio_sender = audio_result.MoveValue()->sender();
2456 auto video_result = caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
2457 ASSERT_EQ(RTCErrorType::NONE, video_result.error().type());
2458 auto caller_video_sender = video_result.MoveValue()->sender();
2459 callee()->SetRemoteOfferHandler([this] {
2460 ASSERT_EQ(2u, callee()->pc()->GetTransceivers().size());
Harald Alvestrand6060df52020-08-11 09:54:02 +02002461 callee()->pc()->GetTransceivers()[0]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002462 RtpTransceiverDirection::kSendRecv);
Harald Alvestrand6060df52020-08-11 09:54:02 +02002463 callee()->pc()->GetTransceivers()[1]->SetDirectionWithError(
Seth Hampson2f0d7022018-02-20 11:54:42 -08002464 RtpTransceiverDirection::kSendRecv);
2465 });
2466 caller()->CreateAndSetAndSignalOffer();
2467 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2468 // Wait for ICE to complete, without any tracks being set.
2469 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionCompleted,
2470 caller()->ice_connection_state(), kMaxWaitForFramesMs);
2471 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2472 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2473 // Now set the tracks, and expect frames to immediately start flowing.
2474 auto callee_audio_sender = callee()->pc()->GetSenders()[0];
2475 auto callee_video_sender = callee()->pc()->GetSenders()[1];
2476 ASSERT_TRUE(caller_audio_sender->SetTrack(caller()->CreateLocalAudioTrack()));
2477 ASSERT_TRUE(caller_video_sender->SetTrack(caller()->CreateLocalVideoTrack()));
2478 ASSERT_TRUE(callee_audio_sender->SetTrack(callee()->CreateLocalAudioTrack()));
2479 ASSERT_TRUE(callee_video_sender->SetTrack(callee()->CreateLocalVideoTrack()));
2480 MediaExpectations media_expectations;
2481 media_expectations.ExpectBidirectionalAudioAndVideo();
2482 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002483}
2484
2485// This test verifies that a remote video track can be added via AddStream,
2486// and sent end-to-end. For this particular test, it's simply echoed back
2487// from the caller to the callee, rather than being forwarded to a third
2488// PeerConnection.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002489TEST_F(PeerConnectionIntegrationTestPlanB, CanSendRemoteVideoTrack) {
deadbeef1dcb1642017-03-29 21:08:16 -07002490 ASSERT_TRUE(CreatePeerConnectionWrappers());
2491 ConnectFakeSignaling();
2492 // Just send a video track from the caller.
Steve Anton15324772018-01-16 10:26:49 -08002493 caller()->AddVideoTrack();
deadbeef1dcb1642017-03-29 21:08:16 -07002494 caller()->CreateAndSetAndSignalOffer();
2495 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +02002496 ASSERT_EQ(1U, callee()->remote_streams()->count());
deadbeef1dcb1642017-03-29 21:08:16 -07002497
2498 // Echo the stream back, and do a new offer/anwer (initiated by callee this
2499 // time).
2500 callee()->pc()->AddStream(callee()->remote_streams()->at(0));
2501 callee()->CreateAndSetAndSignalOffer();
2502 ASSERT_TRUE_WAIT(SignalingStateStable(), kMaxWaitForActivationMs);
2503
Seth Hampson2f0d7022018-02-20 11:54:42 -08002504 MediaExpectations media_expectations;
2505 media_expectations.ExpectBidirectionalVideo();
2506 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeef1dcb1642017-03-29 21:08:16 -07002507}
2508
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002509#if !defined(THREAD_SANITIZER)
2510// This test provokes TSAN errors. bugs.webrtc.org/11282
2511
deadbeef1dcb1642017-03-29 21:08:16 -07002512// Test that we achieve the expected end-to-end connection time, using a
2513// fake clock and simulated latency on the media and signaling paths.
2514// We use a TURN<->TURN connection because this is usually the quickest to
2515// set up initially, especially when we're confident the connection will work
2516// and can start sending media before we get a STUN response.
2517//
2518// With various optimizations enabled, here are the network delays we expect to
2519// be on the critical path:
2520// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
2521// signaling answer (with DTLS fingerprint).
2522// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
2523// using TURN<->TURN pair, and DTLS exchange is 4 packets,
2524// the first of which should have arrived before the answer.
Yves Gerey100fe632020-01-17 19:15:53 +01002525TEST_P(PeerConnectionIntegrationTestWithFakeClock,
2526 EndToEndConnectionTimeWithTurnTurnPair) {
deadbeef1dcb1642017-03-29 21:08:16 -07002527 static constexpr int media_hop_delay_ms = 50;
2528 static constexpr int signaling_trip_delay_ms = 500;
2529 // For explanation of these values, see comment above.
2530 static constexpr int required_media_hops = 9;
2531 static constexpr int required_signaling_trips = 2;
2532 // For internal delays (such as posting an event asychronously).
2533 static constexpr int allowed_internal_delay_ms = 20;
2534 static constexpr int total_connection_time_ms =
2535 media_hop_delay_ms * required_media_hops +
2536 signaling_trip_delay_ms * required_signaling_trips +
2537 allowed_internal_delay_ms;
2538
2539 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2540 3478};
2541 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2542 0};
2543 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2544 3478};
2545 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2546 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002547 cricket::TestTurnServer* turn_server_1 = CreateTurnServer(
2548 turn_server_1_internal_address, turn_server_1_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002549
Seth Hampsonaed71642018-06-11 07:41:32 -07002550 cricket::TestTurnServer* turn_server_2 = CreateTurnServer(
2551 turn_server_2_internal_address, turn_server_2_external_address);
deadbeef1dcb1642017-03-29 21:08:16 -07002552 // Bypass permission check on received packets so media can be sent before
2553 // the candidate is signaled.
Seth Hampsonaed71642018-06-11 07:41:32 -07002554 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_1] {
2555 turn_server_1->set_enable_permission_checks(false);
2556 });
2557 network_thread()->Invoke<void>(RTC_FROM_HERE, [turn_server_2] {
2558 turn_server_2->set_enable_permission_checks(false);
2559 });
deadbeef1dcb1642017-03-29 21:08:16 -07002560
2561 PeerConnectionInterface::RTCConfiguration client_1_config;
2562 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2563 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2564 ice_server_1.username = "test";
2565 ice_server_1.password = "test";
2566 client_1_config.servers.push_back(ice_server_1);
2567 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2568 client_1_config.presume_writable_when_fully_relayed = true;
2569
2570 PeerConnectionInterface::RTCConfiguration client_2_config;
2571 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2572 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2573 ice_server_2.username = "test";
2574 ice_server_2.password = "test";
2575 client_2_config.servers.push_back(ice_server_2);
2576 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2577 client_2_config.presume_writable_when_fully_relayed = true;
2578
2579 ASSERT_TRUE(
2580 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2581 // Set up the simulated delays.
2582 SetSignalingDelayMs(signaling_trip_delay_ms);
2583 ConnectFakeSignaling();
2584 virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
2585 virtual_socket_server()->UpdateDelayDistribution();
2586
2587 // Set "offer to receive audio/video" without adding any tracks, so we just
2588 // set up ICE/DTLS with no media.
2589 PeerConnectionInterface::RTCOfferAnswerOptions options;
2590 options.offer_to_receive_audio = 1;
2591 options.offer_to_receive_video = 1;
2592 caller()->SetOfferAnswerOptions(options);
2593 caller()->CreateAndSetAndSignalOffer();
deadbeef71452802017-05-07 17:21:01 -07002594 EXPECT_TRUE_SIMULATED_WAIT(DtlsConnected(), total_connection_time_ms,
Yves Gerey100fe632020-01-17 19:15:53 +01002595 FakeClock());
Seth Hampson1d4a76d2018-06-19 14:31:41 -07002596 // Closing the PeerConnections destroys the ports before the ScopedFakeClock.
2597 // If this is not done a DCHECK can be hit in ports.cc, because a large
2598 // negative number is calculated for the rtt due to the global clock changing.
Steve Antond91969e2019-05-30 12:27:03 -07002599 ClosePeerConnections();
deadbeef1dcb1642017-03-29 21:08:16 -07002600}
2601
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00002602#endif // !defined(THREAD_SANITIZER)
2603
Jonas Orelandbdcee282017-10-10 14:01:40 +02002604// Verify that a TurnCustomizer passed in through RTCConfiguration
2605// is actually used by the underlying TURN candidate pair.
2606// Note that turnport_unittest.cc contains more detailed, lower-level tests.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002607TEST_P(PeerConnectionIntegrationTest, TurnCustomizerUsedForTurnConnections) {
Jonas Orelandbdcee282017-10-10 14:01:40 +02002608 static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
2609 3478};
2610 static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
2611 0};
2612 static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
2613 3478};
2614 static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
2615 0};
Seth Hampsonaed71642018-06-11 07:41:32 -07002616 CreateTurnServer(turn_server_1_internal_address,
2617 turn_server_1_external_address);
2618 CreateTurnServer(turn_server_2_internal_address,
2619 turn_server_2_external_address);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002620
2621 PeerConnectionInterface::RTCConfiguration client_1_config;
2622 webrtc::PeerConnectionInterface::IceServer ice_server_1;
2623 ice_server_1.urls.push_back("turn:88.88.88.0:3478");
2624 ice_server_1.username = "test";
2625 ice_server_1.password = "test";
2626 client_1_config.servers.push_back(ice_server_1);
2627 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002628 auto* customizer1 = CreateTurnCustomizer();
2629 client_1_config.turn_customizer = customizer1;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002630
2631 PeerConnectionInterface::RTCConfiguration client_2_config;
2632 webrtc::PeerConnectionInterface::IceServer ice_server_2;
2633 ice_server_2.urls.push_back("turn:99.99.99.0:3478");
2634 ice_server_2.username = "test";
2635 ice_server_2.password = "test";
2636 client_2_config.servers.push_back(ice_server_2);
2637 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
Seth Hampsonaed71642018-06-11 07:41:32 -07002638 auto* customizer2 = CreateTurnCustomizer();
2639 client_2_config.turn_customizer = customizer2;
Jonas Orelandbdcee282017-10-10 14:01:40 +02002640
2641 ASSERT_TRUE(
2642 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2643 ConnectFakeSignaling();
2644
2645 // Set "offer to receive audio/video" without adding any tracks, so we just
2646 // set up ICE/DTLS with no media.
2647 PeerConnectionInterface::RTCOfferAnswerOptions options;
2648 options.offer_to_receive_audio = 1;
2649 options.offer_to_receive_video = 1;
2650 caller()->SetOfferAnswerOptions(options);
2651 caller()->CreateAndSetAndSignalOffer();
2652 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2653
Seth Hampsonaed71642018-06-11 07:41:32 -07002654 ExpectTurnCustomizerCountersIncremented(customizer1);
2655 ExpectTurnCustomizerCountersIncremented(customizer2);
Jonas Orelandbdcee282017-10-10 14:01:40 +02002656}
2657
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002658// Verifies that you can use TCP instead of UDP to connect to a TURN server and
2659// send media between the caller and the callee.
2660TEST_P(PeerConnectionIntegrationTest, TCPUsedForTurnConnections) {
2661 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2662 3478};
2663 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2664
2665 // Enable TCP for the fake turn server.
Seth Hampsonaed71642018-06-11 07:41:32 -07002666 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2667 cricket::PROTO_TCP);
Benjamin Wright2d5f3cb2018-05-22 14:46:06 -07002668
2669 webrtc::PeerConnectionInterface::IceServer ice_server;
2670 ice_server.urls.push_back("turn:88.88.88.0:3478?transport=tcp");
2671 ice_server.username = "test";
2672 ice_server.password = "test";
2673
2674 PeerConnectionInterface::RTCConfiguration client_1_config;
2675 client_1_config.servers.push_back(ice_server);
2676 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2677
2678 PeerConnectionInterface::RTCConfiguration client_2_config;
2679 client_2_config.servers.push_back(ice_server);
2680 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2681
2682 ASSERT_TRUE(
2683 CreatePeerConnectionWrappersWithConfig(client_1_config, client_2_config));
2684
2685 // Do normal offer/answer and wait for ICE to complete.
2686 ConnectFakeSignaling();
2687 caller()->AddAudioVideoTracks();
2688 callee()->AddAudioVideoTracks();
2689 caller()->CreateAndSetAndSignalOffer();
2690 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2691 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
2692 callee()->ice_connection_state(), kMaxWaitForFramesMs);
2693
2694 MediaExpectations media_expectations;
2695 media_expectations.ExpectBidirectionalAudioAndVideo();
2696 EXPECT_TRUE(ExpectNewFrames(media_expectations));
2697}
2698
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002699// Verify that a SSLCertificateVerifier passed in through
2700// PeerConnectionDependencies is actually used by the underlying SSL
2701// implementation to determine whether a certificate presented by the TURN
2702// server is accepted by the client. Note that openssladapter_unittest.cc
2703// contains more detailed, lower-level tests.
2704TEST_P(PeerConnectionIntegrationTest,
2705 SSLCertificateVerifierUsedForTurnConnections) {
2706 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2707 3478};
2708 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2709
2710 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2711 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002712 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2713 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002714
2715 webrtc::PeerConnectionInterface::IceServer ice_server;
2716 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2717 ice_server.username = "test";
2718 ice_server.password = "test";
2719
2720 PeerConnectionInterface::RTCConfiguration client_1_config;
2721 client_1_config.servers.push_back(ice_server);
2722 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2723
2724 PeerConnectionInterface::RTCConfiguration client_2_config;
2725 client_2_config.servers.push_back(ice_server);
2726 // Setting the type to kRelay forces the connection to go through a TURN
2727 // server.
2728 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2729
2730 // Get a copy to the pointer so we can verify calls later.
2731 rtc::TestCertificateVerifier* client_1_cert_verifier =
2732 new rtc::TestCertificateVerifier();
2733 client_1_cert_verifier->verify_certificate_ = true;
2734 rtc::TestCertificateVerifier* client_2_cert_verifier =
2735 new rtc::TestCertificateVerifier();
2736 client_2_cert_verifier->verify_certificate_ = true;
2737
2738 // Create the dependencies with the test certificate verifier.
2739 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2740 client_1_deps.tls_cert_verifier =
2741 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2742 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2743 client_2_deps.tls_cert_verifier =
2744 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2745
2746 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2747 client_1_config, std::move(client_1_deps), client_2_config,
2748 std::move(client_2_deps)));
2749 ConnectFakeSignaling();
2750
2751 // Set "offer to receive audio/video" without adding any tracks, so we just
2752 // set up ICE/DTLS with no media.
2753 PeerConnectionInterface::RTCOfferAnswerOptions options;
2754 options.offer_to_receive_audio = 1;
2755 options.offer_to_receive_video = 1;
2756 caller()->SetOfferAnswerOptions(options);
2757 caller()->CreateAndSetAndSignalOffer();
2758 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
2759
2760 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2761 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002762}
2763
2764TEST_P(PeerConnectionIntegrationTest,
2765 SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
2766 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
2767 3478};
2768 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
2769
2770 // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
2771 // that host name verification passes on the fake certificate.
Seth Hampsonaed71642018-06-11 07:41:32 -07002772 CreateTurnServer(turn_server_internal_address, turn_server_external_address,
2773 cricket::PROTO_TLS, "88.88.88.0");
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002774
2775 webrtc::PeerConnectionInterface::IceServer ice_server;
2776 ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
2777 ice_server.username = "test";
2778 ice_server.password = "test";
2779
2780 PeerConnectionInterface::RTCConfiguration client_1_config;
2781 client_1_config.servers.push_back(ice_server);
2782 client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
2783
2784 PeerConnectionInterface::RTCConfiguration client_2_config;
2785 client_2_config.servers.push_back(ice_server);
2786 // Setting the type to kRelay forces the connection to go through a TURN
2787 // server.
2788 client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
2789
2790 // Get a copy to the pointer so we can verify calls later.
2791 rtc::TestCertificateVerifier* client_1_cert_verifier =
2792 new rtc::TestCertificateVerifier();
2793 client_1_cert_verifier->verify_certificate_ = false;
2794 rtc::TestCertificateVerifier* client_2_cert_verifier =
2795 new rtc::TestCertificateVerifier();
2796 client_2_cert_verifier->verify_certificate_ = false;
2797
2798 // Create the dependencies with the test certificate verifier.
2799 webrtc::PeerConnectionDependencies client_1_deps(nullptr);
2800 client_1_deps.tls_cert_verifier =
2801 std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
2802 webrtc::PeerConnectionDependencies client_2_deps(nullptr);
2803 client_2_deps.tls_cert_verifier =
2804 std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
2805
2806 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
2807 client_1_config, std::move(client_1_deps), client_2_config,
2808 std::move(client_2_deps)));
2809 ConnectFakeSignaling();
2810
2811 // Set "offer to receive audio/video" without adding any tracks, so we just
2812 // set up ICE/DTLS with no media.
2813 PeerConnectionInterface::RTCOfferAnswerOptions options;
2814 options.offer_to_receive_audio = 1;
2815 options.offer_to_receive_video = 1;
2816 caller()->SetOfferAnswerOptions(options);
2817 caller()->CreateAndSetAndSignalOffer();
2818 bool wait_res = true;
2819 // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
2820 // properly, should be able to just wait for a state of "failed" instead of
2821 // waiting a fixed 10 seconds.
2822 WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
2823 ASSERT_FALSE(wait_res);
2824
2825 EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
2826 EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002827}
2828
Qingsi Wang25ec8882019-11-15 12:33:05 -08002829// Test that the injected ICE transport factory is used to create ICE transports
2830// for WebRTC connections.
2831TEST_P(PeerConnectionIntegrationTest, IceTransportFactoryUsedForConnections) {
2832 PeerConnectionInterface::RTCConfiguration default_config;
2833 PeerConnectionDependencies dependencies(nullptr);
2834 auto ice_transport_factory = std::make_unique<MockIceTransportFactory>();
2835 EXPECT_CALL(*ice_transport_factory, RecordIceTransportCreated()).Times(1);
2836 dependencies.ice_transport_factory = std::move(ice_transport_factory);
Niels Möller2a707032020-06-16 16:39:13 +02002837 auto wrapper = CreatePeerConnectionWrapper("Caller", nullptr, &default_config,
2838 std::move(dependencies), nullptr,
2839 /*reset_encoder_factory=*/false,
2840 /*reset_decoder_factory=*/false);
Qingsi Wang25ec8882019-11-15 12:33:05 -08002841 ASSERT_TRUE(wrapper);
2842 wrapper->CreateDataChannel();
Tommi87f70902021-04-27 14:43:08 +02002843 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Qingsi Wang25ec8882019-11-15 12:33:05 -08002844 wrapper->pc()->SetLocalDescription(observer,
2845 wrapper->CreateOfferAndWait().release());
2846}
2847
deadbeefc964d0b2017-04-03 10:03:35 -07002848// Test that audio and video flow end-to-end when codec names don't use the
2849// expected casing, given that they're supposed to be case insensitive. To test
2850// this, all but one codec is removed from each media description, and its
2851// casing is changed.
2852//
2853// In the past, this has regressed and caused crashes/black video, due to the
2854// fact that code at some layers was doing case-insensitive comparisons and
2855// code at other layers was not.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002856TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
deadbeefc964d0b2017-04-03 10:03:35 -07002857 ASSERT_TRUE(CreatePeerConnectionWrappers());
2858 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002859 caller()->AddAudioVideoTracks();
2860 callee()->AddAudioVideoTracks();
deadbeefc964d0b2017-04-03 10:03:35 -07002861
2862 // Remove all but one audio/video codec (opus and VP8), and change the
2863 // casing of the caller's generated offer.
2864 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
2865 cricket::AudioContentDescription* audio =
2866 GetFirstAudioContentDescription(description);
2867 ASSERT_NE(nullptr, audio);
2868 auto audio_codecs = audio->codecs();
2869 audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
2870 [](const cricket::AudioCodec& codec) {
2871 return codec.name != "opus";
2872 }),
2873 audio_codecs.end());
2874 ASSERT_EQ(1u, audio_codecs.size());
2875 audio_codecs[0].name = "OpUs";
2876 audio->set_codecs(audio_codecs);
2877
2878 cricket::VideoContentDescription* video =
2879 GetFirstVideoContentDescription(description);
2880 ASSERT_NE(nullptr, video);
2881 auto video_codecs = video->codecs();
2882 video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
2883 [](const cricket::VideoCodec& codec) {
2884 return codec.name != "VP8";
2885 }),
2886 video_codecs.end());
2887 ASSERT_EQ(1u, video_codecs.size());
2888 video_codecs[0].name = "vP8";
2889 video->set_codecs(video_codecs);
2890 });
2891
2892 caller()->CreateAndSetAndSignalOffer();
2893 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2894
2895 // Verify frames are still received end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002896 MediaExpectations media_expectations;
2897 media_expectations.ExpectBidirectionalAudioAndVideo();
2898 ASSERT_TRUE(ExpectNewFrames(media_expectations));
deadbeefc964d0b2017-04-03 10:03:35 -07002899}
2900
Jonas Oreland49ac5952018-09-26 16:04:32 +02002901TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
hbos8d609f62017-04-10 07:39:05 -07002902 ASSERT_TRUE(CreatePeerConnectionWrappers());
2903 ConnectFakeSignaling();
Steve Anton15324772018-01-16 10:26:49 -08002904 caller()->AddAudioTrack();
hbos8d609f62017-04-10 07:39:05 -07002905 caller()->CreateAndSetAndSignalOffer();
2906 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
deadbeefd8ad7882017-04-18 16:01:17 -07002907 // Wait for one audio frame to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002908 MediaExpectations media_expectations;
2909 media_expectations.CalleeExpectsSomeAudio(1);
2910 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Jonas Oreland49ac5952018-09-26 16:04:32 +02002911 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
hbos8d609f62017-04-10 07:39:05 -07002912 auto receiver = callee()->pc()->GetReceivers()[0];
2913 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002914 auto sources = receiver->GetSources();
hbos8d609f62017-04-10 07:39:05 -07002915 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
2916 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
Jonas Oreland49ac5952018-09-26 16:04:32 +02002917 sources[0].source_id());
2918 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
2919}
2920
2921TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
2922 ASSERT_TRUE(CreatePeerConnectionWrappers());
2923 ConnectFakeSignaling();
2924 caller()->AddVideoTrack();
2925 caller()->CreateAndSetAndSignalOffer();
2926 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2927 // Wait for one video frame to be received by the callee.
2928 MediaExpectations media_expectations;
2929 media_expectations.CalleeExpectsSomeVideo(1);
2930 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2931 ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
2932 auto receiver = callee()->pc()->GetReceivers()[0];
2933 ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
2934 auto sources = receiver->GetSources();
2935 ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
Yves Gereyf781bb52019-07-23 19:15:39 +02002936 ASSERT_GT(sources.size(), 0u);
Jonas Oreland49ac5952018-09-26 16:04:32 +02002937 EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
2938 sources[0].source_id());
2939 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
hbos8d609f62017-04-10 07:39:05 -07002940}
2941
deadbeef2f425aa2017-04-14 10:41:32 -07002942// Test that if a track is removed and added again with a different stream ID,
2943// the new stream ID is successfully communicated in SDP and media continues to
2944// flow end-to-end.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002945// TODO(webrtc.bugs.org/8734): This test does not work for Unified Plan because
2946// it will not reuse a transceiver that has already been sending. After creating
2947// a new transceiver it tries to create an offer with two senders of the same
2948// track ids and it fails.
2949TEST_F(PeerConnectionIntegrationTestPlanB, RemoveAndAddTrackWithNewStreamId) {
deadbeef2f425aa2017-04-14 10:41:32 -07002950 ASSERT_TRUE(CreatePeerConnectionWrappers());
2951 ConnectFakeSignaling();
2952
deadbeef2f425aa2017-04-14 10:41:32 -07002953 // Add track using stream 1, do offer/answer.
2954 rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
2955 caller()->CreateLocalAudioTrack();
2956 rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
Steve Antond78323f2018-07-11 11:13:44 -07002957 caller()->AddTrack(track, {"stream_1"});
deadbeef2f425aa2017-04-14 10:41:32 -07002958 caller()->CreateAndSetAndSignalOffer();
2959 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
Seth Hampson2f0d7022018-02-20 11:54:42 -08002960 {
2961 MediaExpectations media_expectations;
2962 media_expectations.CalleeExpectsSomeAudio(1);
2963 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2964 }
deadbeef2f425aa2017-04-14 10:41:32 -07002965 // Remove the sender, and create a new one with the new stream.
Harald Alvestrand93dd7632022-01-19 12:28:45 +00002966 caller()->pc()->RemoveTrackOrError(sender);
Steve Antond78323f2018-07-11 11:13:44 -07002967 sender = caller()->AddTrack(track, {"stream_2"});
deadbeef2f425aa2017-04-14 10:41:32 -07002968 caller()->CreateAndSetAndSignalOffer();
2969 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2970 // Wait for additional audio frames to be received by the callee.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002971 {
2972 MediaExpectations media_expectations;
2973 media_expectations.CalleeExpectsSomeAudio();
2974 ASSERT_TRUE(ExpectNewFrames(media_expectations));
2975 }
deadbeef2f425aa2017-04-14 10:41:32 -07002976}
2977
Seth Hampson2f0d7022018-02-20 11:54:42 -08002978TEST_P(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) {
Elad Alon99c3fe52017-10-13 16:29:40 +02002979 ASSERT_TRUE(CreatePeerConnectionWrappers());
2980 ConnectFakeSignaling();
2981
Mirko Bonadei317a1f02019-09-17 17:06:18 +02002982 auto output = std::make_unique<testing::NiceMock<MockRtcEventLogOutput>>();
Mirko Bonadei6a489f22019-04-09 15:11:12 +02002983 ON_CALL(*output, IsActive()).WillByDefault(::testing::Return(true));
2984 ON_CALL(*output, Write(::testing::_)).WillByDefault(::testing::Return(true));
Elad Alon99c3fe52017-10-13 16:29:40 +02002985 EXPECT_CALL(*output, Write(::testing::_)).Times(::testing::AtLeast(1));
Bjorn Tereliusde939432017-11-20 17:38:14 +01002986 EXPECT_TRUE(caller()->pc()->StartRtcEventLog(
2987 std::move(output), webrtc::RtcEventLog::kImmediateOutput));
Elad Alon99c3fe52017-10-13 16:29:40 +02002988
Steve Anton15324772018-01-16 10:26:49 -08002989 caller()->AddAudioVideoTracks();
Elad Alon99c3fe52017-10-13 16:29:40 +02002990 caller()->CreateAndSetAndSignalOffer();
2991 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
2992}
2993
Steve Antonede9ca52017-10-16 13:04:27 -07002994// Test that if candidates are only signaled by applying full session
2995// descriptions (instead of using AddIceCandidate), the peers can connect to
2996// each other and exchange media.
Seth Hampson2f0d7022018-02-20 11:54:42 -08002997TEST_P(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) {
Steve Antonede9ca52017-10-16 13:04:27 -07002998 ASSERT_TRUE(CreatePeerConnectionWrappers());
2999 // Each side will signal the session descriptions but not candidates.
3000 ConnectFakeSignalingForSdpOnly();
3001
3002 // Add audio video track and exchange the initial offer/answer with media
3003 // information only. This will start ICE gathering on each side.
Steve Anton15324772018-01-16 10:26:49 -08003004 caller()->AddAudioVideoTracks();
3005 callee()->AddAudioVideoTracks();
Steve Antonede9ca52017-10-16 13:04:27 -07003006 caller()->CreateAndSetAndSignalOffer();
3007
3008 // Wait for all candidates to be gathered on both the caller and callee.
3009 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
3010 caller()->ice_gathering_state(), kDefaultTimeout);
3011 ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
3012 callee()->ice_gathering_state(), kDefaultTimeout);
3013
3014 // The candidates will now be included in the session description, so
3015 // signaling them will start the ICE connection.
3016 caller()->CreateAndSetAndSignalOffer();
3017 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3018
3019 // Ensure that media flows in both directions.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003020 MediaExpectations media_expectations;
3021 media_expectations.ExpectBidirectionalAudioAndVideo();
3022 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Antonede9ca52017-10-16 13:04:27 -07003023}
3024
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00003025#if !defined(THREAD_SANITIZER)
3026// These tests provokes TSAN errors. See bugs.webrtc.org/11305.
3027
henrika5f6bf242017-11-01 11:06:56 +01003028// Test that SetAudioPlayout can be used to disable audio playout from the
3029// start, then later enable it. This may be useful, for example, if the caller
3030// needs to play a local ringtone until some event occurs, after which it
3031// switches to playing the received audio.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003032TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioPlayout) {
henrika5f6bf242017-11-01 11:06:56 +01003033 ASSERT_TRUE(CreatePeerConnectionWrappers());
3034 ConnectFakeSignaling();
3035
3036 // Set up audio-only call where audio playout is disabled on caller's side.
3037 caller()->pc()->SetAudioPlayout(false);
Steve Anton15324772018-01-16 10:26:49 -08003038 caller()->AddAudioTrack();
3039 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01003040 caller()->CreateAndSetAndSignalOffer();
3041 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3042
3043 // Pump messages for a second.
3044 WAIT(false, 1000);
3045 // Since audio playout is disabled, the caller shouldn't have received
3046 // anything (at the playout level, at least).
3047 EXPECT_EQ(0, caller()->audio_frames_received());
3048 // As a sanity check, make sure the callee (for which playout isn't disabled)
3049 // did still see frames on its audio level.
3050 ASSERT_GT(callee()->audio_frames_received(), 0);
3051
3052 // Enable playout again, and ensure audio starts flowing.
3053 caller()->pc()->SetAudioPlayout(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003054 MediaExpectations media_expectations;
3055 media_expectations.ExpectBidirectionalAudio();
3056 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika5f6bf242017-11-01 11:06:56 +01003057}
3058
Harald Alvestrand39993842021-02-17 09:05:31 +00003059double GetAudioEnergyStat(PeerConnectionIntegrationWrapper* pc) {
henrika5f6bf242017-11-01 11:06:56 +01003060 auto report = pc->NewGetStats();
3061 auto track_stats_list =
3062 report->GetStatsOfType<webrtc::RTCMediaStreamTrackStats>();
3063 const webrtc::RTCMediaStreamTrackStats* remote_track_stats = nullptr;
3064 for (const auto* track_stats : track_stats_list) {
3065 if (track_stats->remote_source.is_defined() &&
3066 *track_stats->remote_source) {
3067 remote_track_stats = track_stats;
3068 break;
3069 }
3070 }
3071
3072 if (!remote_track_stats->total_audio_energy.is_defined()) {
3073 return 0.0;
3074 }
3075 return *remote_track_stats->total_audio_energy;
3076}
3077
3078// Test that if audio playout is disabled via the SetAudioPlayout() method, then
3079// incoming audio is still processed and statistics are generated.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003080TEST_P(PeerConnectionIntegrationTest,
henrika5f6bf242017-11-01 11:06:56 +01003081 DisableAudioPlayoutStillGeneratesAudioStats) {
3082 ASSERT_TRUE(CreatePeerConnectionWrappers());
3083 ConnectFakeSignaling();
3084
3085 // Set up audio-only call where playout is disabled but audio-processing is
3086 // still active.
Steve Anton15324772018-01-16 10:26:49 -08003087 caller()->AddAudioTrack();
3088 callee()->AddAudioTrack();
henrika5f6bf242017-11-01 11:06:56 +01003089 caller()->pc()->SetAudioPlayout(false);
3090
3091 caller()->CreateAndSetAndSignalOffer();
3092 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3093
3094 // Wait for the callee to receive audio stats.
3095 EXPECT_TRUE_WAIT(GetAudioEnergyStat(caller()) > 0, kMaxWaitForFramesMs);
3096}
3097
Harald Alvestrandec23d6d2021-02-11 10:47:22 +00003098#endif // !defined(THREAD_SANITIZER)
3099
henrika4f167df2017-11-01 14:45:55 +01003100// Test that SetAudioRecording can be used to disable audio recording from the
3101// start, then later enable it. This may be useful, for example, if the caller
3102// wants to ensure that no audio resources are active before a certain state
3103// is reached.
Seth Hampson2f0d7022018-02-20 11:54:42 -08003104TEST_P(PeerConnectionIntegrationTest, DisableAndEnableAudioRecording) {
henrika4f167df2017-11-01 14:45:55 +01003105 ASSERT_TRUE(CreatePeerConnectionWrappers());
3106 ConnectFakeSignaling();
3107
3108 // Set up audio-only call where audio recording is disabled on caller's side.
3109 caller()->pc()->SetAudioRecording(false);
Steve Anton15324772018-01-16 10:26:49 -08003110 caller()->AddAudioTrack();
3111 callee()->AddAudioTrack();
henrika4f167df2017-11-01 14:45:55 +01003112 caller()->CreateAndSetAndSignalOffer();
3113 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3114
3115 // Pump messages for a second.
3116 WAIT(false, 1000);
3117 // Since caller has disabled audio recording, the callee shouldn't have
3118 // received anything.
3119 EXPECT_EQ(0, callee()->audio_frames_received());
3120 // As a sanity check, make sure the caller did still see frames on its
3121 // audio level since audio recording is enabled on the calle side.
3122 ASSERT_GT(caller()->audio_frames_received(), 0);
3123
3124 // Enable audio recording again, and ensure audio starts flowing.
3125 caller()->pc()->SetAudioRecording(true);
Seth Hampson2f0d7022018-02-20 11:54:42 -08003126 MediaExpectations media_expectations;
3127 media_expectations.ExpectBidirectionalAudio();
3128 ASSERT_TRUE(ExpectNewFrames(media_expectations));
henrika4f167df2017-11-01 14:45:55 +01003129}
3130
Qingsi Wang7685e862018-06-11 20:15:46 -07003131TEST_P(PeerConnectionIntegrationTest,
3132 IceEventsGeneratedAndLoggedInRtcEventLog) {
3133 ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog());
3134 ConnectFakeSignaling();
3135 PeerConnectionInterface::RTCOfferAnswerOptions options;
3136 options.offer_to_receive_audio = 1;
3137 caller()->SetOfferAnswerOptions(options);
3138 caller()->CreateAndSetAndSignalOffer();
3139 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3140 ASSERT_NE(nullptr, caller()->event_log_factory());
3141 ASSERT_NE(nullptr, callee()->event_log_factory());
3142 webrtc::FakeRtcEventLog* caller_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01003143 caller()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07003144 webrtc::FakeRtcEventLog* callee_event_log =
Danil Chapovalov4f281f12021-01-18 13:29:00 +01003145 callee()->event_log_factory()->last_log_created();
Qingsi Wang7685e862018-06-11 20:15:46 -07003146 ASSERT_NE(nullptr, caller_event_log);
3147 ASSERT_NE(nullptr, callee_event_log);
3148 int caller_ice_config_count = caller_event_log->GetEventCount(
3149 webrtc::RtcEvent::Type::IceCandidatePairConfig);
3150 int caller_ice_event_count = caller_event_log->GetEventCount(
3151 webrtc::RtcEvent::Type::IceCandidatePairEvent);
3152 int callee_ice_config_count = callee_event_log->GetEventCount(
3153 webrtc::RtcEvent::Type::IceCandidatePairConfig);
3154 int callee_ice_event_count = callee_event_log->GetEventCount(
3155 webrtc::RtcEvent::Type::IceCandidatePairEvent);
3156 EXPECT_LT(0, caller_ice_config_count);
3157 EXPECT_LT(0, caller_ice_event_count);
3158 EXPECT_LT(0, callee_ice_config_count);
3159 EXPECT_LT(0, callee_ice_event_count);
3160}
3161
Qingsi Wangc129c352019-04-18 10:41:58 -07003162TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) {
Qingsi Wangc129c352019-04-18 10:41:58 -07003163 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3164 3478};
3165 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3166
3167 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3168
3169 webrtc::PeerConnectionInterface::IceServer ice_server;
3170 ice_server.urls.push_back("turn:88.88.88.0:3478");
3171 ice_server.username = "test";
3172 ice_server.password = "test";
3173
3174 PeerConnectionInterface::RTCConfiguration caller_config;
3175 caller_config.servers.push_back(ice_server);
3176 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3177 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003178 caller_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003179
3180 PeerConnectionInterface::RTCConfiguration callee_config;
3181 callee_config.servers.push_back(ice_server);
3182 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3183 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
Qingsi Wang1fe119f2019-05-31 16:55:33 -07003184 callee_config.surface_ice_candidates_on_ice_transport_type_changed = true;
Qingsi Wangc129c352019-04-18 10:41:58 -07003185
3186 ASSERT_TRUE(
3187 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3188
3189 // Do normal offer/answer and wait for ICE to complete.
3190 ConnectFakeSignaling();
3191 caller()->AddAudioVideoTracks();
3192 callee()->AddAudioVideoTracks();
3193 caller()->CreateAndSetAndSignalOffer();
3194 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3195 // Since we are doing continual gathering, the ICE transport does not reach
3196 // kIceGatheringComplete (see
3197 // P2PTransportChannel::OnCandidatesAllocationDone), and consequently not
3198 // kIceConnectionComplete.
3199 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3200 caller()->ice_connection_state(), kDefaultTimeout);
3201 EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
3202 callee()->ice_connection_state(), kDefaultTimeout);
3203 // Note that we cannot use the metric
Artem Titovcfea2182021-08-10 01:22:31 +02003204 // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this
Qingsi Wangc129c352019-04-18 10:41:58 -07003205 // metric is only populated when we reach kIceConnectionComplete in the
3206 // current implementation.
3207 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3208 caller()->last_candidate_gathered().type());
3209 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
3210 callee()->last_candidate_gathered().type());
3211
3212 // Loosen the caller's candidate filter.
3213 caller_config = caller()->pc()->GetConfiguration();
3214 caller_config.type = webrtc::PeerConnectionInterface::kAll;
3215 caller()->pc()->SetConfiguration(caller_config);
3216 // We should have gathered a new host candidate.
3217 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3218 caller()->last_candidate_gathered().type(), kDefaultTimeout);
3219
3220 // Loosen the callee's candidate filter.
3221 callee_config = callee()->pc()->GetConfiguration();
3222 callee_config.type = webrtc::PeerConnectionInterface::kAll;
3223 callee()->pc()->SetConfiguration(callee_config);
3224 EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE,
3225 callee()->last_candidate_gathered().type(), kDefaultTimeout);
Jonas Orelande3096512020-05-27 09:01:05 +02003226
3227 // Create an offer and verify that it does not contain an ICE restart (i.e new
3228 // ice credentials).
3229 std::string caller_ufrag_pre_offer = caller()
3230 ->pc()
3231 ->local_description()
3232 ->description()
3233 ->transport_infos()[0]
3234 .description.ice_ufrag;
3235 caller()->CreateAndSetAndSignalOffer();
3236 std::string caller_ufrag_post_offer = caller()
3237 ->pc()
3238 ->local_description()
3239 ->description()
3240 ->transport_infos()[0]
3241 .description.ice_ufrag;
3242 EXPECT_EQ(caller_ufrag_pre_offer, caller_ufrag_post_offer);
Qingsi Wangc129c352019-04-18 10:41:58 -07003243}
3244
Eldar Relloda13ea22019-06-01 12:23:43 +03003245TEST_P(PeerConnectionIntegrationTest, OnIceCandidateError) {
Eldar Relloda13ea22019-06-01 12:23:43 +03003246 static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
3247 3478};
3248 static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
3249
3250 CreateTurnServer(turn_server_internal_address, turn_server_external_address);
3251
3252 webrtc::PeerConnectionInterface::IceServer ice_server;
3253 ice_server.urls.push_back("turn:88.88.88.0:3478");
3254 ice_server.username = "test";
3255 ice_server.password = "123";
3256
3257 PeerConnectionInterface::RTCConfiguration caller_config;
3258 caller_config.servers.push_back(ice_server);
3259 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3260 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3261
3262 PeerConnectionInterface::RTCConfiguration callee_config;
3263 callee_config.servers.push_back(ice_server);
3264 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3265 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3266
3267 ASSERT_TRUE(
3268 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3269
3270 // Do normal offer/answer and wait for ICE to complete.
3271 ConnectFakeSignaling();
3272 caller()->AddAudioVideoTracks();
3273 callee()->AddAudioVideoTracks();
3274 caller()->CreateAndSetAndSignalOffer();
3275 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3276 EXPECT_EQ_WAIT(401, caller()->error_event().error_code, kDefaultTimeout);
3277 EXPECT_EQ("Unauthorized", caller()->error_event().error_text);
3278 EXPECT_EQ("turn:88.88.88.0:3478?transport=udp", caller()->error_event().url);
Eldar Rello0095d372019-12-02 22:22:07 +02003279 EXPECT_NE(caller()->error_event().address, "");
Eldar Relloda13ea22019-06-01 12:23:43 +03003280}
3281
Eldar Rellofa8019c2020-05-14 11:59:33 +03003282TEST_P(PeerConnectionIntegrationTest, OnIceCandidateErrorWithEmptyAddress) {
3283 webrtc::PeerConnectionInterface::IceServer ice_server;
3284 ice_server.urls.push_back("turn:127.0.0.1:3478?transport=tcp");
3285 ice_server.username = "test";
3286 ice_server.password = "test";
3287
3288 PeerConnectionInterface::RTCConfiguration caller_config;
3289 caller_config.servers.push_back(ice_server);
3290 caller_config.type = webrtc::PeerConnectionInterface::kRelay;
3291 caller_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3292
3293 PeerConnectionInterface::RTCConfiguration callee_config;
3294 callee_config.servers.push_back(ice_server);
3295 callee_config.type = webrtc::PeerConnectionInterface::kRelay;
3296 callee_config.continual_gathering_policy = PeerConnection::GATHER_CONTINUALLY;
3297
3298 ASSERT_TRUE(
3299 CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
3300
3301 // Do normal offer/answer and wait for ICE to complete.
3302 ConnectFakeSignaling();
3303 caller()->AddAudioVideoTracks();
3304 callee()->AddAudioVideoTracks();
3305 caller()->CreateAndSetAndSignalOffer();
3306 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3307 EXPECT_EQ_WAIT(701, caller()->error_event().error_code, kDefaultTimeout);
3308 EXPECT_EQ(caller()->error_event().address, "");
3309}
3310
Eldar Rello5ab79e62019-10-09 18:29:44 +03003311TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3312 AudioKeepsFlowingAfterImplicitRollback) {
3313 PeerConnectionInterface::RTCConfiguration config;
3314 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3315 config.enable_implicit_rollback = true;
3316 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3317 ConnectFakeSignaling();
3318 caller()->AddAudioTrack();
3319 callee()->AddAudioTrack();
3320 caller()->CreateAndSetAndSignalOffer();
3321 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3322 MediaExpectations media_expectations;
3323 media_expectations.ExpectBidirectionalAudio();
3324 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3325 SetSignalIceCandidates(false); // Workaround candidate outrace sdp.
3326 caller()->AddVideoTrack();
3327 callee()->AddVideoTrack();
Tommi87f70902021-04-27 14:43:08 +02003328 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003329 callee()->pc()->SetLocalDescription(observer,
3330 callee()->CreateOfferAndWait().release());
3331 EXPECT_TRUE_WAIT(observer->called(), kDefaultTimeout);
3332 caller()->CreateAndSetAndSignalOffer(); // Implicit rollback.
3333 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3334 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3335}
3336
3337TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3338 ImplicitRollbackVisitsStableState) {
3339 RTCConfiguration config;
3340 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3341 config.enable_implicit_rollback = true;
3342
3343 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3344
Tommi87f70902021-04-27 14:43:08 +02003345 auto sld_observer =
3346 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003347 callee()->pc()->SetLocalDescription(sld_observer,
3348 callee()->CreateOfferAndWait().release());
3349 EXPECT_TRUE_WAIT(sld_observer->called(), kDefaultTimeout);
3350 EXPECT_EQ(sld_observer->error(), "");
3351
Tommi87f70902021-04-27 14:43:08 +02003352 auto srd_observer =
3353 rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Eldar Rello5ab79e62019-10-09 18:29:44 +03003354 callee()->pc()->SetRemoteDescription(
3355 srd_observer, caller()->CreateOfferAndWait().release());
3356 EXPECT_TRUE_WAIT(srd_observer->called(), kDefaultTimeout);
3357 EXPECT_EQ(srd_observer->error(), "");
3358
3359 EXPECT_THAT(callee()->peer_connection_signaling_state_history(),
3360 ElementsAre(PeerConnectionInterface::kHaveLocalOffer,
3361 PeerConnectionInterface::kStable,
3362 PeerConnectionInterface::kHaveRemoteOffer));
3363}
3364
Eldar Rellobd9c33a2020-10-01 17:52:45 +03003365TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3366 H264FmtpSpsPpsIdrInKeyframeParameterUsage) {
3367 ASSERT_TRUE(CreatePeerConnectionWrappers());
3368 ConnectFakeSignaling();
3369 caller()->AddVideoTrack();
3370 callee()->AddVideoTrack();
3371 auto munger = [](cricket::SessionDescription* desc) {
3372 cricket::VideoContentDescription* video =
3373 GetFirstVideoContentDescription(desc);
3374 auto codecs = video->codecs();
3375 for (auto&& codec : codecs) {
3376 if (codec.name == "H264") {
3377 std::string value;
3378 // The parameter is not supposed to be present in SDP by default.
3379 EXPECT_FALSE(
3380 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3381 codec.SetParam(std::string(cricket::kH264FmtpSpsPpsIdrInKeyframe),
3382 std::string(""));
3383 }
3384 }
3385 video->set_codecs(codecs);
3386 };
3387 // Munge local offer for SLD.
3388 caller()->SetGeneratedSdpMunger(munger);
3389 // Munge remote answer for SRD.
3390 caller()->SetReceivedSdpMunger(munger);
3391 caller()->CreateAndSetAndSignalOffer();
3392 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3393 // Observe that after munging the parameter is present in generated SDP.
3394 caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* desc) {
3395 cricket::VideoContentDescription* video =
3396 GetFirstVideoContentDescription(desc);
3397 for (auto&& codec : video->codecs()) {
3398 if (codec.name == "H264") {
3399 std::string value;
3400 EXPECT_TRUE(
3401 codec.GetParam(cricket::kH264FmtpSpsPpsIdrInKeyframe, &value));
3402 }
3403 }
3404 });
3405 caller()->CreateOfferAndWait();
3406}
3407
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003408TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand94324f22021-01-13 12:31:53 +00003409 RenegotiateManyAudioTransceivers) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003410 PeerConnectionInterface::RTCConfiguration config;
3411 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3412 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3413 ConnectFakeSignaling();
3414 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3415
3416 caller()->CreateAndSetAndSignalOffer();
3417 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3418 int current_size = caller()->pc()->GetTransceivers().size();
3419 // Add more tracks until we get close to having issues.
3420 // Issues have been seen at:
3421 // - 32 tracks on android_arm64_rel and android_arm_dbg bots
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003422 // - 16 tracks on android_arm_dbg (flaky)
3423 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003424 // Double the number of tracks
3425 for (int i = 0; i < current_size; i++) {
3426 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
3427 }
3428 current_size = caller()->pc()->GetTransceivers().size();
3429 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3430 auto start_time_ms = rtc::TimeMillis();
3431 caller()->CreateAndSetAndSignalOffer();
3432 // We want to stop when the time exceeds one second.
3433 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3434 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3435 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3436 ASSERT_GT(1000, elapsed_time_ms)
3437 << "Audio transceivers: Negotiation took too long after "
3438 << current_size << " tracks added";
3439 }
3440}
3441
3442TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3443 RenegotiateManyVideoTransceivers) {
3444 PeerConnectionInterface::RTCConfiguration config;
3445 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3446 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3447 ConnectFakeSignaling();
3448 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3449
3450 caller()->CreateAndSetAndSignalOffer();
3451 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3452 int current_size = caller()->pc()->GetTransceivers().size();
3453 // Add more tracks until we get close to having issues.
3454 // Issues have been seen at:
3455 // - 96 on a Linux workstation
3456 // - 64 at win_x86_more_configs and win_x64_msvc_dbg
3457 // - 32 on android_arm64_rel and linux_dbg bots
Harald Alvestrand785e23b2021-03-15 21:26:27 +00003458 // - 16 on Android 64 (Nexus 5x)
3459 while (current_size < 8) {
Harald Alvestrand1a9be302020-12-11 14:53:59 +00003460 // Double the number of tracks
3461 for (int i = 0; i < current_size; i++) {
3462 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3463 }
3464 current_size = caller()->pc()->GetTransceivers().size();
3465 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3466 auto start_time_ms = rtc::TimeMillis();
3467 caller()->CreateAndSetAndSignalOffer();
3468 // We want to stop when the time exceeds one second.
3469 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3470 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3471 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3472 ASSERT_GT(1000, elapsed_time_ms)
3473 << "Video transceivers: Negotiation took too long after "
3474 << current_size << " tracks added";
3475 }
3476}
3477
Harald Alvestrand94324f22021-01-13 12:31:53 +00003478TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3479 RenegotiateManyVideoTransceiversAndWatchAudioDelay) {
3480 PeerConnectionInterface::RTCConfiguration config;
3481 config.sdp_semantics = SdpSemantics::kUnifiedPlan;
3482 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3483 ConnectFakeSignaling();
3484 caller()->AddAudioTrack();
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003485 callee()->AddAudioTrack();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003486 caller()->CreateAndSetAndSignalOffer();
3487 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3488 // Wait until we can see the audio flowing.
3489 MediaExpectations media_expectations;
3490 media_expectations.CalleeExpectsSomeAudio();
3491 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3492
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003493 // Get the baseline numbers for audio_packets and audio_delay
3494 // in both directions.
3495 caller()->StartWatchingDelayStats();
3496 callee()->StartWatchingDelayStats();
Harald Alvestrand94324f22021-01-13 12:31:53 +00003497
3498 int current_size = caller()->pc()->GetTransceivers().size();
3499 // Add more tracks until we get close to having issues.
3500 // Making this number very large makes the test very slow.
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003501 while (current_size < 16) {
Harald Alvestrand94324f22021-01-13 12:31:53 +00003502 // Double the number of tracks
3503 for (int i = 0; i < current_size; i++) {
3504 caller()->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
3505 }
3506 current_size = caller()->pc()->GetTransceivers().size();
3507 RTC_LOG(LS_INFO) << "Renegotiating with " << current_size << " tracks";
3508 auto start_time_ms = rtc::TimeMillis();
3509 caller()->CreateAndSetAndSignalOffer();
3510 // We want to stop when the time exceeds one second.
3511 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3512 auto elapsed_time_ms = rtc::TimeMillis() - start_time_ms;
3513 RTC_LOG(LS_INFO) << "Renegotiating took " << elapsed_time_ms << " ms";
3514 // This is a guard against the test using excessive amounts of time.
3515 ASSERT_GT(5000, elapsed_time_ms)
3516 << "Video transceivers: Negotiation took too long after "
3517 << current_size << " tracks added";
Harald Alvestrandcc6ae442021-01-18 08:06:23 +00003518 caller()->UpdateDelayStats("caller reception", current_size);
3519 callee()->UpdateDelayStats("callee reception", current_size);
Harald Alvestrand94324f22021-01-13 12:31:53 +00003520 }
3521}
3522
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003523INSTANTIATE_TEST_SUITE_P(
3524 PeerConnectionIntegrationTest,
3525 PeerConnectionIntegrationTest,
3526 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3527 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3528 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3529 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Steve Antond3679212018-01-17 17:41:02 -08003530
Evan Shrubsole7619b7c2022-03-01 10:42:44 +01003531INSTANTIATE_TEST_SUITE_P(
3532 PeerConnectionIntegrationTest,
3533 PeerConnectionIntegrationTestWithFakeClock,
3534 Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3535 Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
3536 "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
3537 "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
Yves Gerey100fe632020-01-17 19:15:53 +01003538
Steve Anton74255ff2018-01-24 18:32:57 -08003539// Tests that verify interoperability between Plan B and Unified Plan
3540// PeerConnections.
3541class PeerConnectionIntegrationInteropTest
Seth Hampson2f0d7022018-02-20 11:54:42 -08003542 : public PeerConnectionIntegrationBaseTest,
Steve Anton74255ff2018-01-24 18:32:57 -08003543 public ::testing::WithParamInterface<
3544 std::tuple<SdpSemantics, SdpSemantics>> {
3545 protected:
Seth Hampson2f0d7022018-02-20 11:54:42 -08003546 // Setting the SdpSemantics for the base test to kDefault does not matter
3547 // because we specify not to use the test semantics when creating
Harald Alvestrand39993842021-02-17 09:05:31 +00003548 // PeerConnectionIntegrationWrappers.
Steve Anton74255ff2018-01-24 18:32:57 -08003549 PeerConnectionIntegrationInteropTest()
Steve Anton3acffc32018-04-12 17:21:03 -07003550 : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB),
Seth Hampson2f0d7022018-02-20 11:54:42 -08003551 caller_semantics_(std::get<0>(GetParam())),
Steve Anton74255ff2018-01-24 18:32:57 -08003552 callee_semantics_(std::get<1>(GetParam())) {}
3553
3554 bool CreatePeerConnectionWrappersWithSemantics() {
Steve Anton3acffc32018-04-12 17:21:03 -07003555 return CreatePeerConnectionWrappersWithSdpSemantics(caller_semantics_,
3556 callee_semantics_);
Steve Anton74255ff2018-01-24 18:32:57 -08003557 }
3558
3559 const SdpSemantics caller_semantics_;
3560 const SdpSemantics callee_semantics_;
3561};
3562
3563TEST_P(PeerConnectionIntegrationInteropTest, NoMediaLocalToNoMediaRemote) {
3564 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3565 ConnectFakeSignaling();
3566
3567 caller()->CreateAndSetAndSignalOffer();
3568 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3569}
3570
3571TEST_P(PeerConnectionIntegrationInteropTest, OneAudioLocalToNoMediaRemote) {
3572 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3573 ConnectFakeSignaling();
3574 auto audio_sender = caller()->AddAudioTrack();
3575
3576 caller()->CreateAndSetAndSignalOffer();
3577 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3578
3579 // Verify that one audio receiver has been created on the remote and that it
3580 // has the same track ID as the sending track.
3581 auto receivers = callee()->pc()->GetReceivers();
3582 ASSERT_EQ(1u, receivers.size());
3583 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, receivers[0]->media_type());
3584 EXPECT_EQ(receivers[0]->track()->id(), audio_sender->track()->id());
3585
Seth Hampson2f0d7022018-02-20 11:54:42 -08003586 MediaExpectations media_expectations;
3587 media_expectations.CalleeExpectsSomeAudio();
3588 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003589}
3590
3591TEST_P(PeerConnectionIntegrationInteropTest, OneAudioOneVideoToNoMediaRemote) {
3592 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3593 ConnectFakeSignaling();
3594 auto video_sender = caller()->AddVideoTrack();
3595 auto audio_sender = caller()->AddAudioTrack();
3596
3597 caller()->CreateAndSetAndSignalOffer();
3598 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3599
3600 // Verify that one audio and one video receiver have been created on the
3601 // remote and that they have the same track IDs as the sending tracks.
3602 auto audio_receivers =
3603 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_AUDIO);
3604 ASSERT_EQ(1u, audio_receivers.size());
3605 EXPECT_EQ(audio_receivers[0]->track()->id(), audio_sender->track()->id());
3606 auto video_receivers =
3607 callee()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO);
3608 ASSERT_EQ(1u, video_receivers.size());
3609 EXPECT_EQ(video_receivers[0]->track()->id(), video_sender->track()->id());
3610
Seth Hampson2f0d7022018-02-20 11:54:42 -08003611 MediaExpectations media_expectations;
3612 media_expectations.CalleeExpectsSomeAudioAndVideo();
3613 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003614}
3615
3616TEST_P(PeerConnectionIntegrationInteropTest,
3617 OneAudioOneVideoLocalToOneAudioOneVideoRemote) {
3618 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3619 ConnectFakeSignaling();
3620 caller()->AddAudioVideoTracks();
3621 callee()->AddAudioVideoTracks();
3622
3623 caller()->CreateAndSetAndSignalOffer();
3624 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3625
Seth Hampson2f0d7022018-02-20 11:54:42 -08003626 MediaExpectations media_expectations;
3627 media_expectations.ExpectBidirectionalAudioAndVideo();
3628 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003629}
3630
3631TEST_P(PeerConnectionIntegrationInteropTest,
3632 ReverseRolesOneAudioLocalToOneVideoRemote) {
3633 ASSERT_TRUE(CreatePeerConnectionWrappersWithSemantics());
3634 ConnectFakeSignaling();
3635 caller()->AddAudioTrack();
3636 callee()->AddVideoTrack();
3637
3638 caller()->CreateAndSetAndSignalOffer();
3639 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3640
3641 // Verify that only the audio track has been negotiated.
3642 EXPECT_EQ(0u, caller()->GetReceiversOfType(cricket::MEDIA_TYPE_VIDEO).size());
3643 // Might also check that the callee's NegotiationNeeded flag is set.
3644
3645 // Reverse roles.
3646 callee()->CreateAndSetAndSignalOffer();
3647 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3648
Seth Hampson2f0d7022018-02-20 11:54:42 -08003649 MediaExpectations media_expectations;
3650 media_expectations.CallerExpectsSomeVideo();
3651 media_expectations.CalleeExpectsSomeAudio();
3652 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003653}
3654
Taylor Brandstetter1c7ecef2021-08-11 12:38:35 -07003655TEST_P(PeerConnectionIntegrationTest, NewTracksDoNotCauseNewCandidates) {
3656 ASSERT_TRUE(CreatePeerConnectionWrappers());
3657 ConnectFakeSignaling();
3658 caller()->AddAudioVideoTracks();
3659 caller()->CreateAndSetAndSignalOffer();
3660 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3661 ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
3662 caller()->ExpectCandidates(0);
3663 callee()->ExpectCandidates(0);
3664 caller()->AddAudioTrack();
3665 caller()->CreateAndSetAndSignalOffer();
3666 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3667}
3668
Mirko Bonadeic84f6612019-01-31 12:20:57 +01003669INSTANTIATE_TEST_SUITE_P(
Steve Antonba42e992018-04-09 14:10:01 -07003670 PeerConnectionIntegrationTest,
3671 PeerConnectionIntegrationInteropTest,
3672 Values(std::make_tuple(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
3673 std::make_tuple(SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB)));
3674
3675// Test that if the Unified Plan side offers two video tracks then the Plan B
3676// side will only see the first one and ignore the second.
3677TEST_F(PeerConnectionIntegrationTestPlanB, TwoVideoUnifiedPlanToNoMediaPlanB) {
Steve Anton3acffc32018-04-12 17:21:03 -07003678 ASSERT_TRUE(CreatePeerConnectionWrappersWithSdpSemantics(
3679 SdpSemantics::kUnifiedPlan, SdpSemantics::kPlanB));
Steve Anton74255ff2018-01-24 18:32:57 -08003680 ConnectFakeSignaling();
3681 auto first_sender = caller()->AddVideoTrack();
3682 caller()->AddVideoTrack();
3683
3684 caller()->CreateAndSetAndSignalOffer();
3685 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3686
3687 // Verify that there is only one receiver and it corresponds to the first
3688 // added track.
3689 auto receivers = callee()->pc()->GetReceivers();
3690 ASSERT_EQ(1u, receivers.size());
3691 EXPECT_TRUE(receivers[0]->track()->enabled());
3692 EXPECT_EQ(first_sender->track()->id(), receivers[0]->track()->id());
3693
Seth Hampson2f0d7022018-02-20 11:54:42 -08003694 MediaExpectations media_expectations;
3695 media_expectations.CalleeExpectsSomeVideo();
3696 ASSERT_TRUE(ExpectNewFrames(media_expectations));
Steve Anton74255ff2018-01-24 18:32:57 -08003697}
3698
Steve Anton2bed3972019-01-04 17:04:30 -08003699// Test that if the initial offer tagged BUNDLE section is rejected due to its
3700// associated RtpTransceiver being stopped and another transceiver is added,
3701// then renegotiation causes the callee to receive the new video track without
3702// error.
3703// This is a regression test for bugs.webrtc.org/9954
3704TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3705 ReOfferWithStoppedBundleTaggedTransceiver) {
3706 RTCConfiguration config;
3707 config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
3708 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3709 ConnectFakeSignaling();
3710 auto audio_transceiver_or_error =
3711 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3712 ASSERT_TRUE(audio_transceiver_or_error.ok());
3713 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3714
3715 caller()->CreateAndSetAndSignalOffer();
3716 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3717 {
3718 MediaExpectations media_expectations;
3719 media_expectations.CalleeExpectsSomeAudio();
3720 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3721 }
3722
Harald Alvestrand6060df52020-08-11 09:54:02 +02003723 audio_transceiver->StopInternal();
Steve Anton2bed3972019-01-04 17:04:30 -08003724 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3725
3726 caller()->CreateAndSetAndSignalOffer();
3727 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3728 {
3729 MediaExpectations media_expectations;
3730 media_expectations.CalleeExpectsSomeVideo();
3731 ASSERT_TRUE(ExpectNewFrames(media_expectations));
3732 }
3733}
3734
Harald Alvestrandbedb6052020-08-20 14:50:10 +02003735TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3736 StopTransceiverRemovesDtlsTransports) {
3737 RTCConfiguration config;
3738 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3739 ConnectFakeSignaling();
3740 auto audio_transceiver_or_error =
3741 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3742 ASSERT_TRUE(audio_transceiver_or_error.ok());
3743 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3744
3745 caller()->CreateAndSetAndSignalOffer();
3746 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3747
3748 audio_transceiver->StopStandard();
3749 caller()->CreateAndSetAndSignalOffer();
3750 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3751 ASSERT_EQ(0U, caller()->pc()->GetTransceivers().size());
3752 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
3753 caller()->pc()->ice_gathering_state());
3754 EXPECT_THAT(caller()->ice_gathering_state_history(),
3755 ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
3756 PeerConnectionInterface::kIceGatheringComplete,
3757 PeerConnectionInterface::kIceGatheringNew));
3758}
3759
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003760TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand45be0a92020-09-30 06:55:23 +00003761 StopTransceiverStopsAndRemovesTransceivers) {
3762 RTCConfiguration config;
3763 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3764 ConnectFakeSignaling();
3765 auto audio_transceiver_or_error =
3766 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3767 ASSERT_TRUE(audio_transceiver_or_error.ok());
3768 auto caller_transceiver = audio_transceiver_or_error.MoveValue();
3769
3770 caller()->CreateAndSetAndSignalOffer();
3771 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3772 caller_transceiver->StopStandard();
3773
3774 auto callee_transceiver = callee()->pc()->GetTransceivers()[0];
3775 caller()->CreateAndSetAndSignalOffer();
3776 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3777 EXPECT_EQ(0U, caller()->pc()->GetTransceivers().size());
3778 EXPECT_EQ(0U, callee()->pc()->GetTransceivers().size());
3779 EXPECT_EQ(0U, caller()->pc()->GetSenders().size());
3780 EXPECT_EQ(0U, callee()->pc()->GetSenders().size());
3781 EXPECT_EQ(0U, caller()->pc()->GetReceivers().size());
3782 EXPECT_EQ(0U, callee()->pc()->GetReceivers().size());
3783 EXPECT_TRUE(caller_transceiver->stopped());
3784 EXPECT_TRUE(callee_transceiver->stopped());
3785}
3786
3787TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
Harald Alvestrand1ee33252020-09-24 13:31:15 +00003788 StopTransceiverEndsIncomingAudioTrack) {
3789 RTCConfiguration config;
3790 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3791 ConnectFakeSignaling();
3792 auto audio_transceiver_or_error =
3793 caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
3794 ASSERT_TRUE(audio_transceiver_or_error.ok());
3795 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3796
3797 caller()->CreateAndSetAndSignalOffer();
3798 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3799 auto caller_track = audio_transceiver->receiver()->track();
3800 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3801 audio_transceiver->StopStandard();
3802 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3803 caller_track->state());
3804 caller()->CreateAndSetAndSignalOffer();
3805 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3806 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3807 callee_track->state());
3808}
3809
3810TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
3811 StopTransceiverEndsIncomingVideoTrack) {
3812 RTCConfiguration config;
3813 ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
3814 ConnectFakeSignaling();
3815 auto audio_transceiver_or_error =
3816 caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack());
3817 ASSERT_TRUE(audio_transceiver_or_error.ok());
3818 auto audio_transceiver = audio_transceiver_or_error.MoveValue();
3819
3820 caller()->CreateAndSetAndSignalOffer();
3821 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3822 auto caller_track = audio_transceiver->receiver()->track();
3823 auto callee_track = callee()->pc()->GetReceivers()[0]->track();
3824 audio_transceiver->StopStandard();
3825 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3826 caller_track->state());
3827 caller()->CreateAndSetAndSignalOffer();
3828 ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
3829 EXPECT_EQ(MediaStreamTrackInterface::TrackState::kEnded,
3830 callee_track->state());
3831}
3832
Harald Alvestrand89c40e22021-02-17 08:58:35 +00003833} // namespace
Harald Alvestrand39993842021-02-17 09:05:31 +00003834
Mirko Bonadeiab64e8a2018-12-12 12:10:18 +01003835} // namespace webrtc