blob: 08e3cb1848b54ed5069ed9131595532ce9705e03 [file] [log] [blame]
wu@webrtc.org364f2042013-11-20 21:49:41 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2013 The WebRTC project authors. All Rights Reserved.
wu@webrtc.org364f2042013-11-20 21:49:41 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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.
wu@webrtc.org364f2042013-11-20 21:49:41 +00009 */
10
Harald Alvestrandc24a2182022-02-23 13:44:59 +000011#include <stdint.h>
12
13#include <cstddef>
14#include <limits>
kwibergd1fe2812016-04-27 06:47:29 -070015#include <memory>
Harald Alvestrandc24a2182022-02-23 13:44:59 +000016#include <string>
17#include <type_traits>
18#include <utility>
19#include <vector>
kwibergd1fe2812016-04-27 06:47:29 -070020
Niels Möller2edab4c2018-10-22 09:48:08 +020021#include "absl/strings/match.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000022#include "absl/types/optional.h"
Karl Wibergc5bb00b2017-10-10 23:17:17 +020023#include "api/audio_codecs/L16/audio_decoder_L16.h"
24#include "api/audio_codecs/L16/audio_encoder_L16.h"
Karl Wiberg17668ec2018-03-01 15:13:27 +010025#include "api/audio_codecs/audio_codec_pair_id.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000026#include "api/audio_codecs/audio_decoder.h"
27#include "api/audio_codecs/audio_decoder_factory.h"
Karl Wibergc5bb00b2017-10-10 23:17:17 +020028#include "api/audio_codecs/audio_decoder_factory_template.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000029#include "api/audio_codecs/audio_encoder.h"
30#include "api/audio_codecs/audio_encoder_factory.h"
Karl Wibergc5bb00b2017-10-10 23:17:17 +020031#include "api/audio_codecs/audio_encoder_factory_template.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000032#include "api/audio_codecs/audio_format.h"
Karl Wiberg44d7ec02019-11-26 14:00:41 +010033#include "api/audio_codecs/opus_audio_decoder_factory.h"
34#include "api/audio_codecs/opus_audio_encoder_factory.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000035#include "api/audio_options.h"
36#include "api/data_channel_interface.h"
37#include "api/media_stream_interface.h"
38#include "api/peer_connection_interface.h"
39#include "api/rtc_error.h"
40#include "api/scoped_refptr.h"
Harald Alvestrand1f928d32019-03-28 11:29:38 +010041#include "media/sctp/sctp_transport_internal.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000042#include "rtc_base/checks.h"
43#include "rtc_base/copy_on_write_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020044#include "rtc_base/gunit.h"
Niels Möllerbf753212021-11-22 09:12:04 +010045#include "rtc_base/physical_socket_server.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000046#include "rtc_base/ref_counted_object.h"
47#include "rtc_base/third_party/sigslot/sigslot.h"
48#include "rtc_base/thread.h"
49#include "test/gmock.h"
50#include "test/gtest.h"
Patrik Höglund563934e2017-09-15 09:04:28 +020051
ossu7bb87ee2017-01-23 04:56:25 -080052#ifdef WEBRTC_ANDROID
Steve Anton10542f22019-01-11 09:11:00 -080053#include "pc/test/android_test_initializer.h"
ossu7bb87ee2017-01-23 04:56:25 -080054#endif
Steve Anton10542f22019-01-11 09:11:00 -080055#include "pc/test/peer_connection_test_wrapper.h"
ossu7bb87ee2017-01-23 04:56:25 -080056// Notice that mockpeerconnectionobservers.h must be included after the above!
Steve Anton10542f22019-01-11 09:11:00 -080057#include "pc/test/mock_peer_connection_observers.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020058#include "test/mock_audio_decoder.h"
59#include "test/mock_audio_decoder_factory.h"
Karl Wibergbc4cf892018-11-13 13:20:51 +010060#include "test/mock_audio_encoder_factory.h"
kwiberg9e5b11e2017-04-19 03:47:57 -070061
Mirko Bonadei6a489f22019-04-09 15:11:12 +020062using ::testing::_;
63using ::testing::AtLeast;
64using ::testing::Invoke;
65using ::testing::StrictMock;
66using ::testing::Values;
wu@webrtc.org364f2042013-11-20 21:49:41 +000067
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000068using webrtc::DataChannelInterface;
wu@webrtc.org364f2042013-11-20 21:49:41 +000069using webrtc::MediaStreamInterface;
70using webrtc::PeerConnectionInterface;
Steve Anton191c39f2018-01-24 19:35:55 -080071using webrtc::SdpSemantics;
wu@webrtc.org364f2042013-11-20 21:49:41 +000072
73namespace {
74
Jeroen de Borst4f6d2332018-07-18 11:25:12 -070075const int kMaxWait = 25000;
wu@webrtc.org364f2042013-11-20 21:49:41 +000076
wu@webrtc.org364f2042013-11-20 21:49:41 +000077} // namespace
78
Steve Anton191c39f2018-01-24 19:35:55 -080079class PeerConnectionEndToEndBaseTest : public sigslot::has_slots<>,
Mirko Bonadei6a489f22019-04-09 15:11:12 +020080 public ::testing::Test {
wu@webrtc.org364f2042013-11-20 21:49:41 +000081 public:
Yves Gerey665174f2018-06-19 15:03:05 +020082 typedef std::vector<rtc::scoped_refptr<DataChannelInterface>> DataChannelList;
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000083
Niels Möllerbf753212021-11-22 09:12:04 +010084 explicit PeerConnectionEndToEndBaseTest(SdpSemantics sdp_semantics)
85 : network_thread_(std::make_unique<rtc::Thread>(&pss_)),
86 worker_thread_(rtc::Thread::Create()) {
tommie7251592017-07-14 14:44:46 -070087 RTC_CHECK(network_thread_->Start());
88 RTC_CHECK(worker_thread_->Start());
Niels Möllere7cc8832022-01-04 15:20:03 +010089 caller_ = rtc::make_ref_counted<PeerConnectionTestWrapper>(
tommie7251592017-07-14 14:44:46 -070090 "caller", network_thread_.get(), worker_thread_.get());
Niels Möllere7cc8832022-01-04 15:20:03 +010091 callee_ = rtc::make_ref_counted<PeerConnectionTestWrapper>(
tommie7251592017-07-14 14:44:46 -070092 "callee", network_thread_.get(), worker_thread_.get());
zhihuang9763d562016-08-05 11:14:50 -070093 webrtc::PeerConnectionInterface::IceServer ice_server;
94 ice_server.uri = "stun:stun.l.google.com:19302";
95 config_.servers.push_back(ice_server);
Steve Anton191c39f2018-01-24 19:35:55 -080096 config_.sdp_semantics = sdp_semantics;
zhihuang9763d562016-08-05 11:14:50 -070097
phoglund37ebcf02016-01-08 05:04:57 -080098#ifdef WEBRTC_ANDROID
99 webrtc::InitializeAndroidObjects();
100#endif
wu@webrtc.org364f2042013-11-20 21:49:41 +0000101 }
102
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100103 void CreatePcs(
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100104 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory1,
105 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory1,
106 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory2,
107 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory2) {
Niels Möllerf06f9232018-08-07 12:32:18 +0200108 EXPECT_TRUE(caller_->CreatePc(config_, audio_encoder_factory1,
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100109 audio_decoder_factory1));
Niels Möllerf06f9232018-08-07 12:32:18 +0200110 EXPECT_TRUE(callee_->CreatePc(config_, audio_encoder_factory2,
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100111 audio_decoder_factory2));
wu@webrtc.org364f2042013-11-20 21:49:41 +0000112 PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000113
114 caller_->SignalOnDataChannel.connect(
Steve Anton191c39f2018-01-24 19:35:55 -0800115 this, &PeerConnectionEndToEndBaseTest::OnCallerAddedDataChanel);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000116 callee_->SignalOnDataChannel.connect(
Steve Anton191c39f2018-01-24 19:35:55 -0800117 this, &PeerConnectionEndToEndBaseTest::OnCalleeAddedDataChannel);
wu@webrtc.org364f2042013-11-20 21:49:41 +0000118 }
119
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100120 void CreatePcs(
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100121 rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
122 rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory) {
Niels Möllerf06f9232018-08-07 12:32:18 +0200123 CreatePcs(audio_encoder_factory, audio_decoder_factory,
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100124 audio_encoder_factory, audio_decoder_factory);
125 }
126
wu@webrtc.org364f2042013-11-20 21:49:41 +0000127 void GetAndAddUserMedia() {
Niels Möller2d02e082018-05-21 11:23:35 +0200128 cricket::AudioOptions audio_options;
Niels Möller5c4ddad2019-02-12 12:30:58 +0100129 GetAndAddUserMedia(true, audio_options, true);
wu@webrtc.org364f2042013-11-20 21:49:41 +0000130 }
131
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100132 void GetAndAddUserMedia(bool audio,
Niels Möller2d02e082018-05-21 11:23:35 +0200133 const cricket::AudioOptions& audio_options,
Niels Möller5c4ddad2019-02-12 12:30:58 +0100134 bool video) {
135 caller_->GetAndAddUserMedia(audio, audio_options, video);
136 callee_->GetAndAddUserMedia(audio, audio_options, video);
wu@webrtc.org364f2042013-11-20 21:49:41 +0000137 }
138
Niels Möllerf06f9232018-08-07 12:32:18 +0200139 void Negotiate() {
140 caller_->CreateOffer(
141 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
142 }
wu@webrtc.org364f2042013-11-20 21:49:41 +0000143
144 void WaitForCallEstablished() {
145 caller_->WaitForCallEstablished();
146 callee_->WaitForCallEstablished();
147 }
148
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000149 void WaitForConnection() {
150 caller_->WaitForConnection();
151 callee_->WaitForConnection();
152 }
153
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000154 void OnCallerAddedDataChanel(DataChannelInterface* dc) {
Niels Möllere7cc8832022-01-04 15:20:03 +0100155 caller_signaled_data_channels_.push_back(
156 rtc::scoped_refptr<DataChannelInterface>(dc));
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000157 }
158
159 void OnCalleeAddedDataChannel(DataChannelInterface* dc) {
Niels Möllere7cc8832022-01-04 15:20:03 +0100160 callee_signaled_data_channels_.push_back(
161 rtc::scoped_refptr<DataChannelInterface>(dc));
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000162 }
163
Artem Titov880fa812021-07-30 22:30:23 +0200164 // Tests that `dc1` and `dc2` can send to and receive from each other.
Yves Gerey665174f2018-06-19 15:03:05 +0200165 void TestDataChannelSendAndReceive(DataChannelInterface* dc1,
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700166 DataChannelInterface* dc2,
167 size_t size = 6) {
kwibergd1fe2812016-04-27 06:47:29 -0700168 std::unique_ptr<webrtc::MockDataChannelObserver> dc1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000169 new webrtc::MockDataChannelObserver(dc1));
170
kwibergd1fe2812016-04-27 06:47:29 -0700171 std::unique_ptr<webrtc::MockDataChannelObserver> dc2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000172 new webrtc::MockDataChannelObserver(dc2));
173
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700174 static const std::string kDummyData =
175 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
176 webrtc::DataBuffer buffer("");
177
178 size_t sizeLeft = size;
179 while (sizeLeft > 0) {
180 size_t chunkSize =
181 sizeLeft > kDummyData.length() ? kDummyData.length() : sizeLeft;
182 buffer.data.AppendData(kDummyData.data(), chunkSize);
183 sizeLeft -= chunkSize;
184 }
185
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000186 EXPECT_TRUE(dc1->Send(buffer));
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700187 EXPECT_EQ_WAIT(buffer.data,
188 rtc::CopyOnWriteBuffer(dc2_observer->last_message()),
189 kMaxWait);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000190
191 EXPECT_TRUE(dc2->Send(buffer));
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700192 EXPECT_EQ_WAIT(buffer.data,
193 rtc::CopyOnWriteBuffer(dc1_observer->last_message()),
194 kMaxWait);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000195
196 EXPECT_EQ(1U, dc1_observer->received_message_count());
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700197 EXPECT_EQ(size, dc1_observer->last_message().length());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000198 EXPECT_EQ(1U, dc2_observer->received_message_count());
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700199 EXPECT_EQ(size, dc2_observer->last_message().length());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000200 }
201
202 void WaitForDataChannelsToOpen(DataChannelInterface* local_dc,
203 const DataChannelList& remote_dc_list,
204 size_t remote_dc_index) {
205 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, local_dc->state(), kMaxWait);
206
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700207 ASSERT_TRUE_WAIT(remote_dc_list.size() > remote_dc_index, kMaxWait);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000208 EXPECT_EQ_WAIT(DataChannelInterface::kOpen,
Yves Gerey665174f2018-06-19 15:03:05 +0200209 remote_dc_list[remote_dc_index]->state(), kMaxWait);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000210 EXPECT_EQ(local_dc->id(), remote_dc_list[remote_dc_index]->id());
211 }
212
213 void CloseDataChannels(DataChannelInterface* local_dc,
214 const DataChannelList& remote_dc_list,
215 size_t remote_dc_index) {
216 local_dc->Close();
217 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, local_dc->state(), kMaxWait);
218 EXPECT_EQ_WAIT(DataChannelInterface::kClosed,
Yves Gerey665174f2018-06-19 15:03:05 +0200219 remote_dc_list[remote_dc_index]->state(), kMaxWait);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000220 }
221
wu@webrtc.org364f2042013-11-20 21:49:41 +0000222 protected:
Niels Möllerbf753212021-11-22 09:12:04 +0100223 rtc::PhysicalSocketServer pss_;
tommie7251592017-07-14 14:44:46 -0700224 std::unique_ptr<rtc::Thread> network_thread_;
225 std::unique_ptr<rtc::Thread> worker_thread_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000226 rtc::scoped_refptr<PeerConnectionTestWrapper> caller_;
227 rtc::scoped_refptr<PeerConnectionTestWrapper> callee_;
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000228 DataChannelList caller_signaled_data_channels_;
229 DataChannelList callee_signaled_data_channels_;
zhihuang9763d562016-08-05 11:14:50 -0700230 webrtc::PeerConnectionInterface::RTCConfiguration config_;
wu@webrtc.org364f2042013-11-20 21:49:41 +0000231};
232
Steve Anton191c39f2018-01-24 19:35:55 -0800233class PeerConnectionEndToEndTest
234 : public PeerConnectionEndToEndBaseTest,
235 public ::testing::WithParamInterface<SdpSemantics> {
236 protected:
237 PeerConnectionEndToEndTest() : PeerConnectionEndToEndBaseTest(GetParam()) {}
238};
239
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200240namespace {
241
kwiberg9e5b11e2017-04-19 03:47:57 -0700242std::unique_ptr<webrtc::AudioDecoder> CreateForwardingMockDecoder(
243 std::unique_ptr<webrtc::AudioDecoder> real_decoder) {
244 class ForwardingMockDecoder : public StrictMock<webrtc::MockAudioDecoder> {
245 public:
Steve Anton36b29d12017-10-30 09:57:42 -0700246 explicit ForwardingMockDecoder(std::unique_ptr<AudioDecoder> decoder)
kwiberg9e5b11e2017-04-19 03:47:57 -0700247 : decoder_(std::move(decoder)) {}
248
249 private:
250 std::unique_ptr<AudioDecoder> decoder_;
251 };
252
253 const auto dec = real_decoder.get(); // For lambda capturing.
254 auto mock_decoder =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200255 std::make_unique<ForwardingMockDecoder>(std::move(real_decoder));
kwiberg9e5b11e2017-04-19 03:47:57 -0700256 EXPECT_CALL(*mock_decoder, Channels())
257 .Times(AtLeast(1))
258 .WillRepeatedly(Invoke([dec] { return dec->Channels(); }));
259 EXPECT_CALL(*mock_decoder, DecodeInternal(_, _, _, _, _))
260 .Times(AtLeast(1))
261 .WillRepeatedly(
262 Invoke([dec](const uint8_t* encoded, size_t encoded_len,
263 int sample_rate_hz, int16_t* decoded,
264 webrtc::AudioDecoder::SpeechType* speech_type) {
265 return dec->Decode(encoded, encoded_len, sample_rate_hz,
266 std::numeric_limits<size_t>::max(), decoded,
267 speech_type);
268 }));
269 EXPECT_CALL(*mock_decoder, Die());
270 EXPECT_CALL(*mock_decoder, HasDecodePlc()).WillRepeatedly(Invoke([dec] {
271 return dec->HasDecodePlc();
272 }));
kwiberg9e5b11e2017-04-19 03:47:57 -0700273 EXPECT_CALL(*mock_decoder, PacketDuration(_, _))
274 .Times(AtLeast(1))
275 .WillRepeatedly(Invoke([dec](const uint8_t* encoded, size_t encoded_len) {
276 return dec->PacketDuration(encoded, encoded_len);
277 }));
278 EXPECT_CALL(*mock_decoder, SampleRateHz())
279 .Times(AtLeast(1))
280 .WillRepeatedly(Invoke([dec] { return dec->SampleRateHz(); }));
281
282 return std::move(mock_decoder);
283}
284
285rtc::scoped_refptr<webrtc::AudioDecoderFactory>
286CreateForwardingMockDecoderFactory(
287 webrtc::AudioDecoderFactory* real_decoder_factory) {
288 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
Niels Möllere7cc8832022-01-04 15:20:03 +0100289 rtc::make_ref_counted<StrictMock<webrtc::MockAudioDecoderFactory>>();
kwiberg9e5b11e2017-04-19 03:47:57 -0700290 EXPECT_CALL(*mock_decoder_factory, GetSupportedDecoders())
291 .Times(AtLeast(1))
292 .WillRepeatedly(Invoke([real_decoder_factory] {
293 return real_decoder_factory->GetSupportedDecoders();
294 }));
295 EXPECT_CALL(*mock_decoder_factory, IsSupportedDecoder(_))
296 .Times(AtLeast(1))
297 .WillRepeatedly(
298 Invoke([real_decoder_factory](const webrtc::SdpAudioFormat& format) {
299 return real_decoder_factory->IsSupportedDecoder(format);
300 }));
Karl Wibergd6fbf2a2018-02-27 13:37:31 +0100301 EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _, _))
kwiberg9e5b11e2017-04-19 03:47:57 -0700302 .Times(AtLeast(2))
303 .WillRepeatedly(
304 Invoke([real_decoder_factory](
305 const webrtc::SdpAudioFormat& format,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200306 absl::optional<webrtc::AudioCodecPairId> codec_pair_id,
kwiberg9e5b11e2017-04-19 03:47:57 -0700307 std::unique_ptr<webrtc::AudioDecoder>* return_value) {
Karl Wibergd6fbf2a2018-02-27 13:37:31 +0100308 auto real_decoder =
309 real_decoder_factory->MakeAudioDecoder(format, codec_pair_id);
kwiberg9e5b11e2017-04-19 03:47:57 -0700310 *return_value =
311 real_decoder
312 ? CreateForwardingMockDecoder(std::move(real_decoder))
313 : nullptr;
314 }));
315 return mock_decoder_factory;
316}
317
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200318struct AudioEncoderUnicornSparklesRainbow {
319 using Config = webrtc::AudioEncoderL16::Config;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200320 static absl::optional<Config> SdpToConfig(webrtc::SdpAudioFormat format) {
Niels Möller2edab4c2018-10-22 09:48:08 +0200321 if (absl::EqualsIgnoreCase(format.name, "UnicornSparklesRainbow")) {
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200322 const webrtc::SdpAudioFormat::Parameters expected_params = {
323 {"num_horns", "1"}};
324 EXPECT_EQ(expected_params, format.parameters);
325 format.parameters.clear();
326 format.name = "L16";
327 return webrtc::AudioEncoderL16::SdpToConfig(format);
328 } else {
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200329 return absl::nullopt;
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200330 }
331 }
332 static void AppendSupportedEncoders(
333 std::vector<webrtc::AudioCodecSpec>* specs) {
334 std::vector<webrtc::AudioCodecSpec> new_specs;
335 webrtc::AudioEncoderL16::AppendSupportedEncoders(&new_specs);
336 for (auto& spec : new_specs) {
337 spec.format.name = "UnicornSparklesRainbow";
338 EXPECT_TRUE(spec.format.parameters.empty());
339 spec.format.parameters.emplace("num_horns", "1");
340 specs->push_back(spec);
341 }
342 }
343 static webrtc::AudioCodecInfo QueryAudioEncoder(const Config& config) {
344 return webrtc::AudioEncoderL16::QueryAudioEncoder(config);
345 }
346 static std::unique_ptr<webrtc::AudioEncoder> MakeAudioEncoder(
347 const Config& config,
Karl Wiberg17668ec2018-03-01 15:13:27 +0100348 int payload_type,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200349 absl::optional<webrtc::AudioCodecPairId> codec_pair_id = absl::nullopt) {
Karl Wiberg17668ec2018-03-01 15:13:27 +0100350 return webrtc::AudioEncoderL16::MakeAudioEncoder(config, payload_type,
351 codec_pair_id);
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200352 }
353};
354
355struct AudioDecoderUnicornSparklesRainbow {
356 using Config = webrtc::AudioDecoderL16::Config;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200357 static absl::optional<Config> SdpToConfig(webrtc::SdpAudioFormat format) {
Niels Möller2edab4c2018-10-22 09:48:08 +0200358 if (absl::EqualsIgnoreCase(format.name, "UnicornSparklesRainbow")) {
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200359 const webrtc::SdpAudioFormat::Parameters expected_params = {
360 {"num_horns", "1"}};
361 EXPECT_EQ(expected_params, format.parameters);
362 format.parameters.clear();
363 format.name = "L16";
364 return webrtc::AudioDecoderL16::SdpToConfig(format);
365 } else {
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200366 return absl::nullopt;
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200367 }
368 }
369 static void AppendSupportedDecoders(
370 std::vector<webrtc::AudioCodecSpec>* specs) {
371 std::vector<webrtc::AudioCodecSpec> new_specs;
372 webrtc::AudioDecoderL16::AppendSupportedDecoders(&new_specs);
373 for (auto& spec : new_specs) {
374 spec.format.name = "UnicornSparklesRainbow";
375 EXPECT_TRUE(spec.format.parameters.empty());
376 spec.format.parameters.emplace("num_horns", "1");
377 specs->push_back(spec);
378 }
379 }
380 static std::unique_ptr<webrtc::AudioDecoder> MakeAudioDecoder(
Karl Wiberg17668ec2018-03-01 15:13:27 +0100381 const Config& config,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200382 absl::optional<webrtc::AudioCodecPairId> codec_pair_id = absl::nullopt) {
Karl Wiberg17668ec2018-03-01 15:13:27 +0100383 return webrtc::AudioDecoderL16::MakeAudioDecoder(config, codec_pair_id);
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200384 }
385};
386
387} // namespace
388
Steve Anton36da6ff2018-02-16 16:04:20 -0800389TEST_P(PeerConnectionEndToEndTest, Call) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700390 rtc::scoped_refptr<webrtc::AudioDecoderFactory> real_decoder_factory =
Karl Wiberg44d7ec02019-11-26 14:00:41 +0100391 webrtc::CreateOpusAudioDecoderFactory();
392 CreatePcs(webrtc::CreateOpusAudioEncoderFactory(),
kwiberg9e5b11e2017-04-19 03:47:57 -0700393 CreateForwardingMockDecoderFactory(real_decoder_factory.get()));
wu@webrtc.org364f2042013-11-20 21:49:41 +0000394 GetAndAddUserMedia();
395 Negotiate();
396 WaitForCallEstablished();
397}
398
Harald Alvestrandca327932022-04-04 15:37:31 +0000399#if defined(IS_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06 +0000400TEST_P(PeerConnectionEndToEndTest, CallWithSdesKeyNegotiation) {
401 config_.enable_dtls_srtp = false;
402 CreatePcs(webrtc::CreateOpusAudioEncoderFactory(),
403 webrtc::CreateOpusAudioDecoderFactory());
404 GetAndAddUserMedia();
405 Negotiate();
406 WaitForCallEstablished();
407}
Harald Alvestrandca327932022-04-04 15:37:31 +0000408#endif
Harald Alvestrand50b95522021-11-18 10:01:06 +0000409
Steve Anton191c39f2018-01-24 19:35:55 -0800410TEST_P(PeerConnectionEndToEndTest, CallWithCustomCodec) {
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100411 class IdLoggingAudioEncoderFactory : public webrtc::AudioEncoderFactory {
412 public:
413 IdLoggingAudioEncoderFactory(
414 rtc::scoped_refptr<AudioEncoderFactory> real_factory,
415 std::vector<webrtc::AudioCodecPairId>* const codec_ids)
416 : fact_(real_factory), codec_ids_(codec_ids) {}
417 std::vector<webrtc::AudioCodecSpec> GetSupportedEncoders() override {
418 return fact_->GetSupportedEncoders();
419 }
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200420 absl::optional<webrtc::AudioCodecInfo> QueryAudioEncoder(
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100421 const webrtc::SdpAudioFormat& format) override {
422 return fact_->QueryAudioEncoder(format);
423 }
424 std::unique_ptr<webrtc::AudioEncoder> MakeAudioEncoder(
425 int payload_type,
426 const webrtc::SdpAudioFormat& format,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200427 absl::optional<webrtc::AudioCodecPairId> codec_pair_id) override {
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100428 EXPECT_TRUE(codec_pair_id.has_value());
429 codec_ids_->push_back(*codec_pair_id);
430 return fact_->MakeAudioEncoder(payload_type, format, codec_pair_id);
431 }
432
433 private:
434 const rtc::scoped_refptr<webrtc::AudioEncoderFactory> fact_;
435 std::vector<webrtc::AudioCodecPairId>* const codec_ids_;
436 };
437
438 class IdLoggingAudioDecoderFactory : public webrtc::AudioDecoderFactory {
439 public:
440 IdLoggingAudioDecoderFactory(
441 rtc::scoped_refptr<AudioDecoderFactory> real_factory,
442 std::vector<webrtc::AudioCodecPairId>* const codec_ids)
443 : fact_(real_factory), codec_ids_(codec_ids) {}
444 std::vector<webrtc::AudioCodecSpec> GetSupportedDecoders() override {
445 return fact_->GetSupportedDecoders();
446 }
447 bool IsSupportedDecoder(const webrtc::SdpAudioFormat& format) override {
448 return fact_->IsSupportedDecoder(format);
449 }
450 std::unique_ptr<webrtc::AudioDecoder> MakeAudioDecoder(
451 const webrtc::SdpAudioFormat& format,
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200452 absl::optional<webrtc::AudioCodecPairId> codec_pair_id) override {
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100453 EXPECT_TRUE(codec_pair_id.has_value());
454 codec_ids_->push_back(*codec_pair_id);
455 return fact_->MakeAudioDecoder(format, codec_pair_id);
456 }
457
458 private:
459 const rtc::scoped_refptr<webrtc::AudioDecoderFactory> fact_;
460 std::vector<webrtc::AudioCodecPairId>* const codec_ids_;
461 };
462
463 std::vector<webrtc::AudioCodecPairId> encoder_id1, encoder_id2, decoder_id1,
464 decoder_id2;
Niels Möllere7cc8832022-01-04 15:20:03 +0100465 CreatePcs(rtc::make_ref_counted<IdLoggingAudioEncoderFactory>(
466 webrtc::CreateAudioEncoderFactory<
467 AudioEncoderUnicornSparklesRainbow>(),
468 &encoder_id1),
469 rtc::make_ref_counted<IdLoggingAudioDecoderFactory>(
470 webrtc::CreateAudioDecoderFactory<
471 AudioDecoderUnicornSparklesRainbow>(),
472 &decoder_id1),
473 rtc::make_ref_counted<IdLoggingAudioEncoderFactory>(
474 webrtc::CreateAudioEncoderFactory<
475 AudioEncoderUnicornSparklesRainbow>(),
476 &encoder_id2),
477 rtc::make_ref_counted<IdLoggingAudioDecoderFactory>(
478 webrtc::CreateAudioDecoderFactory<
479 AudioDecoderUnicornSparklesRainbow>(),
480 &decoder_id2));
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200481 GetAndAddUserMedia();
482 Negotiate();
483 WaitForCallEstablished();
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100484
485 // Each codec factory has been used to create one codec. The first pair got
486 // the same ID because they were passed to the same PeerConnectionFactory,
487 // and the second pair got the same ID---but these two IDs are not equal,
488 // because each PeerConnectionFactory has its own ID.
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200489 EXPECT_EQ(1U, encoder_id1.size());
490 EXPECT_EQ(1U, encoder_id2.size());
Karl Wiberg5bdc82a2018-03-22 00:07:39 +0100491 EXPECT_EQ(encoder_id1, decoder_id1);
492 EXPECT_EQ(encoder_id2, decoder_id2);
493 EXPECT_NE(encoder_id1, encoder_id2);
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200494}
495
Mirko Bonadei5eb43b42021-01-18 13:24:40 +0100496#ifdef WEBRTC_HAVE_SCTP
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000497// Verifies that a DataChannel created before the negotiation can transition to
498// "OPEN" and transfer data.
Steve Anton191c39f2018-01-24 19:35:55 -0800499TEST_P(PeerConnectionEndToEndTest, CreateDataChannelBeforeNegotiate) {
Karl Wibergbc4cf892018-11-13 13:20:51 +0100500 CreatePcs(webrtc::MockAudioEncoderFactory::CreateEmptyFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700501 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000502
503 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000504 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000505 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000506 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000507 callee_->CreateDataChannel("data", init));
508
509 Negotiate();
510 WaitForConnection();
511
Niels Möllerafb246b2022-04-20 14:26:50 +0200512 WaitForDataChannelsToOpen(caller_dc.get(), callee_signaled_data_channels_, 0);
513 WaitForDataChannelsToOpen(callee_dc.get(), caller_signaled_data_channels_, 0);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000514
Niels Möllerafb246b2022-04-20 14:26:50 +0200515 TestDataChannelSendAndReceive(caller_dc.get(),
516 callee_signaled_data_channels_[0].get());
517 TestDataChannelSendAndReceive(callee_dc.get(),
518 caller_signaled_data_channels_[0].get());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000519
Niels Möllerafb246b2022-04-20 14:26:50 +0200520 CloseDataChannels(caller_dc.get(), callee_signaled_data_channels_, 0);
521 CloseDataChannels(callee_dc.get(), caller_signaled_data_channels_, 0);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000522}
523
524// Verifies that a DataChannel created after the negotiation can transition to
525// "OPEN" and transfer data.
Steve Anton191c39f2018-01-24 19:35:55 -0800526TEST_P(PeerConnectionEndToEndTest, CreateDataChannelAfterNegotiate) {
Karl Wibergbc4cf892018-11-13 13:20:51 +0100527 CreatePcs(webrtc::MockAudioEncoderFactory::CreateEmptyFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700528 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000529
530 webrtc::DataChannelInit init;
531
532 // This DataChannel is for creating the data content in the negotiation.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000533 rtc::scoped_refptr<DataChannelInterface> dummy(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000534 caller_->CreateDataChannel("data", init));
535 Negotiate();
536 WaitForConnection();
537
Taylor Brandstetterbf2f5692016-06-29 11:22:47 -0700538 // Wait for the data channel created pre-negotiation to be opened.
Niels Möllerafb246b2022-04-20 14:26:50 +0200539 WaitForDataChannelsToOpen(dummy.get(), callee_signaled_data_channels_, 0);
Taylor Brandstetterbf2f5692016-06-29 11:22:47 -0700540
541 // Create new DataChannels after the negotiation and verify their states.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000542 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000543 caller_->CreateDataChannel("hello", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000544 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000545 callee_->CreateDataChannel("hello", init));
546
Niels Möllerafb246b2022-04-20 14:26:50 +0200547 WaitForDataChannelsToOpen(caller_dc.get(), callee_signaled_data_channels_, 1);
548 WaitForDataChannelsToOpen(callee_dc.get(), caller_signaled_data_channels_, 0);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000549
Niels Möllerafb246b2022-04-20 14:26:50 +0200550 TestDataChannelSendAndReceive(caller_dc.get(),
551 callee_signaled_data_channels_[1].get());
552 TestDataChannelSendAndReceive(callee_dc.get(),
553 caller_signaled_data_channels_[0].get());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000554
Niels Möllerafb246b2022-04-20 14:26:50 +0200555 CloseDataChannels(caller_dc.get(), callee_signaled_data_channels_, 1);
556 CloseDataChannels(callee_dc.get(), caller_signaled_data_channels_, 0);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000557}
558
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700559// Verifies that a DataChannel created can transfer large messages.
560TEST_P(PeerConnectionEndToEndTest, CreateDataChannelLargeTransfer) {
Karl Wibergbc4cf892018-11-13 13:20:51 +0100561 CreatePcs(webrtc::MockAudioEncoderFactory::CreateEmptyFactory(),
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700562 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
563
564 webrtc::DataChannelInit init;
565
566 // This DataChannel is for creating the data content in the negotiation.
567 rtc::scoped_refptr<DataChannelInterface> dummy(
568 caller_->CreateDataChannel("data", init));
569 Negotiate();
570 WaitForConnection();
571
572 // Wait for the data channel created pre-negotiation to be opened.
Niels Möllerafb246b2022-04-20 14:26:50 +0200573 WaitForDataChannelsToOpen(dummy.get(), callee_signaled_data_channels_, 0);
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700574
575 // Create new DataChannels after the negotiation and verify their states.
576 rtc::scoped_refptr<DataChannelInterface> caller_dc(
577 caller_->CreateDataChannel("hello", init));
578 rtc::scoped_refptr<DataChannelInterface> callee_dc(
579 callee_->CreateDataChannel("hello", init));
580
Niels Möllerafb246b2022-04-20 14:26:50 +0200581 WaitForDataChannelsToOpen(caller_dc.get(), callee_signaled_data_channels_, 1);
582 WaitForDataChannelsToOpen(callee_dc.get(), caller_signaled_data_channels_, 0);
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700583
Niels Möllerafb246b2022-04-20 14:26:50 +0200584 TestDataChannelSendAndReceive(
585 caller_dc.get(), callee_signaled_data_channels_[1].get(), 256 * 1024);
586 TestDataChannelSendAndReceive(
587 callee_dc.get(), caller_signaled_data_channels_[0].get(), 256 * 1024);
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700588
Niels Möllerafb246b2022-04-20 14:26:50 +0200589 CloseDataChannels(caller_dc.get(), callee_signaled_data_channels_, 1);
590 CloseDataChannels(callee_dc.get(), caller_signaled_data_channels_, 0);
Jeroen de Borst4f6d2332018-07-18 11:25:12 -0700591}
592
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000593// Verifies that DataChannel IDs are even/odd based on the DTLS roles.
Steve Anton191c39f2018-01-24 19:35:55 -0800594TEST_P(PeerConnectionEndToEndTest, DataChannelIdAssignment) {
Karl Wibergbc4cf892018-11-13 13:20:51 +0100595 CreatePcs(webrtc::MockAudioEncoderFactory::CreateEmptyFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700596 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000597
598 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000599 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000600 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000601 rtc::scoped_refptr<DataChannelInterface> callee_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000602 callee_->CreateDataChannel("data", init));
603
604 Negotiate();
605 WaitForConnection();
606
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200607 EXPECT_EQ(1, caller_dc_1->id() % 2);
608 EXPECT_EQ(0, callee_dc_1->id() % 2);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000609
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000610 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000611 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000612 rtc::scoped_refptr<DataChannelInterface> callee_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000613 callee_->CreateDataChannel("data", init));
614
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200615 EXPECT_EQ(1, caller_dc_2->id() % 2);
616 EXPECT_EQ(0, callee_dc_2->id() % 2);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000617}
618
619// Verifies that the message is received by the right remote DataChannel when
620// there are multiple DataChannels.
Steve Anton191c39f2018-01-24 19:35:55 -0800621TEST_P(PeerConnectionEndToEndTest,
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000622 MessageTransferBetweenTwoPairsOfDataChannels) {
Karl Wibergbc4cf892018-11-13 13:20:51 +0100623 CreatePcs(webrtc::MockAudioEncoderFactory::CreateEmptyFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700624 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000625
626 webrtc::DataChannelInit init;
627
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000628 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000629 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000630 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000631 caller_->CreateDataChannel("data", init));
632
633 Negotiate();
634 WaitForConnection();
Niels Möllerafb246b2022-04-20 14:26:50 +0200635 WaitForDataChannelsToOpen(caller_dc_1.get(), callee_signaled_data_channels_,
636 0);
637 WaitForDataChannelsToOpen(caller_dc_2.get(), callee_signaled_data_channels_,
638 1);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000639
kwibergd1fe2812016-04-27 06:47:29 -0700640 std::unique_ptr<webrtc::MockDataChannelObserver> dc_1_observer(
Niels Möllerafb246b2022-04-20 14:26:50 +0200641 new webrtc::MockDataChannelObserver(
642 callee_signaled_data_channels_[0].get()));
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000643
kwibergd1fe2812016-04-27 06:47:29 -0700644 std::unique_ptr<webrtc::MockDataChannelObserver> dc_2_observer(
Niels Möllerafb246b2022-04-20 14:26:50 +0200645 new webrtc::MockDataChannelObserver(
646 callee_signaled_data_channels_[1].get()));
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000647
648 const std::string message_1 = "hello 1";
649 const std::string message_2 = "hello 2";
650
651 caller_dc_1->Send(webrtc::DataBuffer(message_1));
652 EXPECT_EQ_WAIT(message_1, dc_1_observer->last_message(), kMaxWait);
653
654 caller_dc_2->Send(webrtc::DataBuffer(message_2));
655 EXPECT_EQ_WAIT(message_2, dc_2_observer->last_message(), kMaxWait);
656
657 EXPECT_EQ(1U, dc_1_observer->received_message_count());
658 EXPECT_EQ(1U, dc_2_observer->received_message_count());
659}
deadbeefab9b2d12015-10-14 11:33:11 -0700660
661// Verifies that a DataChannel added from an OPEN message functions after
662// a channel has been previously closed (webrtc issue 3778).
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700663// This previously failed because the new channel re-used the ID of the closed
664// channel, and the closed channel was incorrectly still assigned to the ID.
Steve Anton191c39f2018-01-24 19:35:55 -0800665TEST_P(PeerConnectionEndToEndTest,
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700666 DataChannelFromOpenWorksAfterPreviousChannelClosed) {
Karl Wibergbc4cf892018-11-13 13:20:51 +0100667 CreatePcs(webrtc::MockAudioEncoderFactory::CreateEmptyFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700668 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
deadbeefab9b2d12015-10-14 11:33:11 -0700669
670 webrtc::DataChannelInit init;
671 rtc::scoped_refptr<DataChannelInterface> caller_dc(
672 caller_->CreateDataChannel("data", init));
673
674 Negotiate();
675 WaitForConnection();
676
Niels Möllerafb246b2022-04-20 14:26:50 +0200677 WaitForDataChannelsToOpen(caller_dc.get(), callee_signaled_data_channels_, 0);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700678 int first_channel_id = caller_dc->id();
679 // Wait for the local side to say it's closed, but not the remote side.
680 // Previously, the channel on which Close is called reported being closed
681 // prematurely, and this caused issues; see bugs.webrtc.org/4453.
682 caller_dc->Close();
683 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, caller_dc->state(), kMaxWait);
deadbeefab9b2d12015-10-14 11:33:11 -0700684
685 // Create a new channel and ensure it works after closing the previous one.
686 caller_dc = caller_->CreateDataChannel("data2", init);
Niels Möllerafb246b2022-04-20 14:26:50 +0200687 WaitForDataChannelsToOpen(caller_dc.get(), callee_signaled_data_channels_, 1);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700688 // Since the second channel was created after the first finished closing, it
689 // should be able to re-use the first one's ID.
690 EXPECT_EQ(first_channel_id, caller_dc->id());
Niels Möllerafb246b2022-04-20 14:26:50 +0200691 TestDataChannelSendAndReceive(caller_dc.get(),
692 callee_signaled_data_channels_[1].get());
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700693
Niels Möllerafb246b2022-04-20 14:26:50 +0200694 CloseDataChannels(caller_dc.get(), callee_signaled_data_channels_, 1);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700695}
696
697// Similar to the above test, but don't wait for the first channel to finish
698// closing before creating the second one.
699TEST_P(PeerConnectionEndToEndTest,
700 DataChannelFromOpenWorksWhilePreviousChannelClosing) {
Karl Wibergbc4cf892018-11-13 13:20:51 +0100701 CreatePcs(webrtc::MockAudioEncoderFactory::CreateEmptyFactory(),
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700702 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
703
704 webrtc::DataChannelInit init;
705 rtc::scoped_refptr<DataChannelInterface> caller_dc(
706 caller_->CreateDataChannel("data", init));
707
708 Negotiate();
709 WaitForConnection();
710
Niels Möllerafb246b2022-04-20 14:26:50 +0200711 WaitForDataChannelsToOpen(caller_dc.get(), callee_signaled_data_channels_, 0);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700712 int first_channel_id = caller_dc->id();
713 caller_dc->Close();
714
715 // Immediately create a new channel, before waiting for the previous one to
716 // transition to "closed".
717 caller_dc = caller_->CreateDataChannel("data2", init);
Niels Möllerafb246b2022-04-20 14:26:50 +0200718 WaitForDataChannelsToOpen(caller_dc.get(), callee_signaled_data_channels_, 1);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700719 // Since the second channel was created while the first was still closing,
720 // it should have been assigned a different ID.
721 EXPECT_NE(first_channel_id, caller_dc->id());
Niels Möllerafb246b2022-04-20 14:26:50 +0200722 TestDataChannelSendAndReceive(caller_dc.get(),
723 callee_signaled_data_channels_[1].get());
deadbeefab9b2d12015-10-14 11:33:11 -0700724
Niels Möllerafb246b2022-04-20 14:26:50 +0200725 CloseDataChannels(caller_dc.get(), callee_signaled_data_channels_, 1);
deadbeefab9b2d12015-10-14 11:33:11 -0700726}
deadbeefbd292462015-12-14 18:15:29 -0800727
728// This tests that if a data channel is closed remotely while not referenced
729// by the application (meaning only the PeerConnection contributes to its
730// reference count), no memory access violation will occur.
731// See: https://code.google.com/p/chromium/issues/detail?id=565048
Steve Anton191c39f2018-01-24 19:35:55 -0800732TEST_P(PeerConnectionEndToEndTest, CloseDataChannelRemotelyWhileNotReferenced) {
Karl Wibergbc4cf892018-11-13 13:20:51 +0100733 CreatePcs(webrtc::MockAudioEncoderFactory::CreateEmptyFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700734 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
deadbeefbd292462015-12-14 18:15:29 -0800735
736 webrtc::DataChannelInit init;
737 rtc::scoped_refptr<DataChannelInterface> caller_dc(
738 caller_->CreateDataChannel("data", init));
739
740 Negotiate();
741 WaitForConnection();
742
Niels Möllerafb246b2022-04-20 14:26:50 +0200743 WaitForDataChannelsToOpen(caller_dc.get(), callee_signaled_data_channels_, 0);
deadbeefbd292462015-12-14 18:15:29 -0800744 // This removes the reference to the remote data channel that we hold.
745 callee_signaled_data_channels_.clear();
746 caller_dc->Close();
747 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, caller_dc->state(), kMaxWait);
748
749 // Wait for a bit longer so the remote data channel will receive the
750 // close message and be destroyed.
751 rtc::Thread::Current()->ProcessMessages(100);
752}
Harald Alvestrand1f928d32019-03-28 11:29:38 +0100753
754// Test behavior of creating too many datachannels.
755TEST_P(PeerConnectionEndToEndTest, TooManyDataChannelsOpenedBeforeConnecting) {
756 CreatePcs(webrtc::MockAudioEncoderFactory::CreateEmptyFactory(),
757 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
758
759 webrtc::DataChannelInit init;
760 std::vector<rtc::scoped_refptr<DataChannelInterface>> channels;
761 for (int i = 0; i <= cricket::kMaxSctpStreams / 2; i++) {
762 rtc::scoped_refptr<DataChannelInterface> caller_dc(
763 caller_->CreateDataChannel("data", init));
764 channels.push_back(std::move(caller_dc));
765 }
766 Negotiate();
767 WaitForConnection();
768 EXPECT_EQ_WAIT(callee_signaled_data_channels_.size(),
769 static_cast<size_t>(cricket::kMaxSctpStreams / 2), kMaxWait);
770 EXPECT_EQ(DataChannelInterface::kOpen,
771 channels[(cricket::kMaxSctpStreams / 2) - 1]->state());
772 EXPECT_EQ(DataChannelInterface::kClosed,
773 channels[cricket::kMaxSctpStreams / 2]->state());
774}
775
Mirko Bonadei5eb43b42021-01-18 13:24:40 +0100776#endif // WEBRTC_HAVE_SCTP
Steve Anton191c39f2018-01-24 19:35:55 -0800777
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200778TEST_P(PeerConnectionEndToEndTest, CanRestartIce) {
779 rtc::scoped_refptr<webrtc::AudioDecoderFactory> real_decoder_factory =
Karl Wiberg44d7ec02019-11-26 14:00:41 +0100780 webrtc::CreateOpusAudioDecoderFactory();
781 CreatePcs(webrtc::CreateOpusAudioEncoderFactory(),
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200782 CreateForwardingMockDecoderFactory(real_decoder_factory.get()));
783 GetAndAddUserMedia();
784 Negotiate();
785 WaitForCallEstablished();
786 // Cause ICE restart to be requested.
787 auto config = caller_->pc()->GetConfiguration();
788 ASSERT_NE(PeerConnectionInterface::kRelay, config.type);
789 config.type = PeerConnectionInterface::kRelay;
Niels Möller340e0c52019-08-26 11:03:47 +0200790 ASSERT_TRUE(caller_->pc()->SetConfiguration(config).ok());
Harald Alvestrand78a5e962019-04-03 10:42:39 +0200791 // When solving https://crbug.com/webrtc/10504, all we need to check
792 // is that we do not crash. We should also be testing that restart happens.
793}
794
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100795INSTANTIATE_TEST_SUITE_P(PeerConnectionEndToEndTest,
796 PeerConnectionEndToEndTest,
Florent Castelli15a38de2022-04-06 00:38:21 +0200797 Values(SdpSemantics::kPlanB_DEPRECATED,
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100798 SdpSemantics::kUnifiedPlan));