blob: 4eefd0b1dcd05d4610a83b75e1e0cba06cc9eec1 [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
kwibergd1fe2812016-04-27 06:47:29 -070011#include <memory>
12
Karl Wibergc5bb00b2017-10-10 23:17:17 +020013#include "api/audio_codecs/L16/audio_decoder_L16.h"
14#include "api/audio_codecs/L16/audio_encoder_L16.h"
15#include "api/audio_codecs/audio_decoder_factory_template.h"
16#include "api/audio_codecs/audio_encoder_factory_template.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/audio_codecs/builtin_audio_decoder_factory.h"
18#include "api/audio_codecs/builtin_audio_encoder_factory.h"
19#include "rtc_base/gunit.h"
20#include "rtc_base/logging.h"
21#include "rtc_base/ptr_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/stringencode.h"
23#include "rtc_base/stringutils.h"
Patrik Höglund563934e2017-09-15 09:04:28 +020024
ossu7bb87ee2017-01-23 04:56:25 -080025#ifdef WEBRTC_ANDROID
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "pc/test/androidtestinitializer.h"
ossu7bb87ee2017-01-23 04:56:25 -080027#endif
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "pc/test/peerconnectiontestwrapper.h"
ossu7bb87ee2017-01-23 04:56:25 -080029// Notice that mockpeerconnectionobservers.h must be included after the above!
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "pc/test/mockpeerconnectionobservers.h"
31#include "test/mock_audio_decoder.h"
32#include "test/mock_audio_decoder_factory.h"
kwiberg9e5b11e2017-04-19 03:47:57 -070033
34using testing::AtLeast;
35using testing::Invoke;
36using testing::StrictMock;
Steve Anton191c39f2018-01-24 19:35:55 -080037using testing::Values;
kwiberg9e5b11e2017-04-19 03:47:57 -070038using testing::_;
wu@webrtc.org364f2042013-11-20 21:49:41 +000039
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000040using webrtc::DataChannelInterface;
wu@webrtc.org364f2042013-11-20 21:49:41 +000041using webrtc::FakeConstraints;
42using webrtc::MediaConstraintsInterface;
43using webrtc::MediaStreamInterface;
44using webrtc::PeerConnectionInterface;
Steve Anton191c39f2018-01-24 19:35:55 -080045using webrtc::SdpSemantics;
wu@webrtc.org364f2042013-11-20 21:49:41 +000046
47namespace {
48
Honghai Zhang82d78622016-05-06 11:29:15 -070049const int kMaxWait = 10000;
wu@webrtc.org364f2042013-11-20 21:49:41 +000050
wu@webrtc.org364f2042013-11-20 21:49:41 +000051} // namespace
52
Steve Anton191c39f2018-01-24 19:35:55 -080053class PeerConnectionEndToEndBaseTest : public sigslot::has_slots<>,
54 public testing::Test {
wu@webrtc.org364f2042013-11-20 21:49:41 +000055 public:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000056 typedef std::vector<rtc::scoped_refptr<DataChannelInterface> >
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000057 DataChannelList;
58
Steve Anton191c39f2018-01-24 19:35:55 -080059 explicit PeerConnectionEndToEndBaseTest(SdpSemantics sdp_semantics) {
tommie7251592017-07-14 14:44:46 -070060 network_thread_ = rtc::Thread::CreateWithSocketServer();
61 worker_thread_ = rtc::Thread::Create();
62 RTC_CHECK(network_thread_->Start());
63 RTC_CHECK(worker_thread_->Start());
perkj57db6522016-04-08 08:16:33 -070064 caller_ = new rtc::RefCountedObject<PeerConnectionTestWrapper>(
tommie7251592017-07-14 14:44:46 -070065 "caller", network_thread_.get(), worker_thread_.get());
perkj57db6522016-04-08 08:16:33 -070066 callee_ = new rtc::RefCountedObject<PeerConnectionTestWrapper>(
tommie7251592017-07-14 14:44:46 -070067 "callee", network_thread_.get(), worker_thread_.get());
zhihuang9763d562016-08-05 11:14:50 -070068 webrtc::PeerConnectionInterface::IceServer ice_server;
69 ice_server.uri = "stun:stun.l.google.com:19302";
70 config_.servers.push_back(ice_server);
Steve Anton191c39f2018-01-24 19:35:55 -080071 config_.sdp_semantics = sdp_semantics;
zhihuang9763d562016-08-05 11:14:50 -070072
phoglund37ebcf02016-01-08 05:04:57 -080073#ifdef WEBRTC_ANDROID
74 webrtc::InitializeAndroidObjects();
75#endif
wu@webrtc.org364f2042013-11-20 21:49:41 +000076 }
77
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010078 void CreatePcs(const MediaConstraintsInterface* pc_constraints,
79 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
80 audio_encoder_factory,
81 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
82 audio_decoder_factory) {
kwiberg9e5b11e2017-04-19 03:47:57 -070083 EXPECT_TRUE(caller_->CreatePc(
84 pc_constraints, config_, audio_encoder_factory, audio_decoder_factory));
85 EXPECT_TRUE(callee_->CreatePc(
86 pc_constraints, config_, audio_encoder_factory, audio_decoder_factory));
wu@webrtc.org364f2042013-11-20 21:49:41 +000087 PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000088
89 caller_->SignalOnDataChannel.connect(
Steve Anton191c39f2018-01-24 19:35:55 -080090 this, &PeerConnectionEndToEndBaseTest::OnCallerAddedDataChanel);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000091 callee_->SignalOnDataChannel.connect(
Steve Anton191c39f2018-01-24 19:35:55 -080092 this, &PeerConnectionEndToEndBaseTest::OnCalleeAddedDataChannel);
wu@webrtc.org364f2042013-11-20 21:49:41 +000093 }
94
95 void GetAndAddUserMedia() {
96 FakeConstraints audio_constraints;
97 FakeConstraints video_constraints;
98 GetAndAddUserMedia(true, audio_constraints, true, video_constraints);
99 }
100
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +0100101 void GetAndAddUserMedia(bool audio,
102 const FakeConstraints& audio_constraints,
103 bool video,
104 const FakeConstraints& video_constraints) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000105 caller_->GetAndAddUserMedia(audio, audio_constraints,
106 video, video_constraints);
107 callee_->GetAndAddUserMedia(audio, audio_constraints,
108 video, video_constraints);
109 }
110
111 void Negotiate() {
112 caller_->CreateOffer(NULL);
113 }
114
115 void WaitForCallEstablished() {
116 caller_->WaitForCallEstablished();
117 callee_->WaitForCallEstablished();
118 }
119
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000120 void WaitForConnection() {
121 caller_->WaitForConnection();
122 callee_->WaitForConnection();
123 }
124
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000125 void OnCallerAddedDataChanel(DataChannelInterface* dc) {
126 caller_signaled_data_channels_.push_back(dc);
127 }
128
129 void OnCalleeAddedDataChannel(DataChannelInterface* dc) {
130 callee_signaled_data_channels_.push_back(dc);
131 }
132
133 // Tests that |dc1| and |dc2| can send to and receive from each other.
134 void TestDataChannelSendAndReceive(
135 DataChannelInterface* dc1, DataChannelInterface* dc2) {
kwibergd1fe2812016-04-27 06:47:29 -0700136 std::unique_ptr<webrtc::MockDataChannelObserver> dc1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000137 new webrtc::MockDataChannelObserver(dc1));
138
kwibergd1fe2812016-04-27 06:47:29 -0700139 std::unique_ptr<webrtc::MockDataChannelObserver> dc2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000140 new webrtc::MockDataChannelObserver(dc2));
141
142 static const std::string kDummyData = "abcdefg";
143 webrtc::DataBuffer buffer(kDummyData);
144 EXPECT_TRUE(dc1->Send(buffer));
145 EXPECT_EQ_WAIT(kDummyData, dc2_observer->last_message(), kMaxWait);
146
147 EXPECT_TRUE(dc2->Send(buffer));
148 EXPECT_EQ_WAIT(kDummyData, dc1_observer->last_message(), kMaxWait);
149
150 EXPECT_EQ(1U, dc1_observer->received_message_count());
151 EXPECT_EQ(1U, dc2_observer->received_message_count());
152 }
153
154 void WaitForDataChannelsToOpen(DataChannelInterface* local_dc,
155 const DataChannelList& remote_dc_list,
156 size_t remote_dc_index) {
157 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, local_dc->state(), kMaxWait);
158
159 EXPECT_TRUE_WAIT(remote_dc_list.size() > remote_dc_index, kMaxWait);
160 EXPECT_EQ_WAIT(DataChannelInterface::kOpen,
161 remote_dc_list[remote_dc_index]->state(),
162 kMaxWait);
163 EXPECT_EQ(local_dc->id(), remote_dc_list[remote_dc_index]->id());
164 }
165
166 void CloseDataChannels(DataChannelInterface* local_dc,
167 const DataChannelList& remote_dc_list,
168 size_t remote_dc_index) {
169 local_dc->Close();
170 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, local_dc->state(), kMaxWait);
171 EXPECT_EQ_WAIT(DataChannelInterface::kClosed,
172 remote_dc_list[remote_dc_index]->state(),
173 kMaxWait);
174 }
175
wu@webrtc.org364f2042013-11-20 21:49:41 +0000176 protected:
tommie7251592017-07-14 14:44:46 -0700177 std::unique_ptr<rtc::Thread> network_thread_;
178 std::unique_ptr<rtc::Thread> worker_thread_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000179 rtc::scoped_refptr<PeerConnectionTestWrapper> caller_;
180 rtc::scoped_refptr<PeerConnectionTestWrapper> callee_;
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000181 DataChannelList caller_signaled_data_channels_;
182 DataChannelList callee_signaled_data_channels_;
zhihuang9763d562016-08-05 11:14:50 -0700183 webrtc::PeerConnectionInterface::RTCConfiguration config_;
wu@webrtc.org364f2042013-11-20 21:49:41 +0000184};
185
Steve Anton191c39f2018-01-24 19:35:55 -0800186class PeerConnectionEndToEndTest
187 : public PeerConnectionEndToEndBaseTest,
188 public ::testing::WithParamInterface<SdpSemantics> {
189 protected:
190 PeerConnectionEndToEndTest() : PeerConnectionEndToEndBaseTest(GetParam()) {}
191};
192
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200193namespace {
194
kwiberg9e5b11e2017-04-19 03:47:57 -0700195std::unique_ptr<webrtc::AudioDecoder> CreateForwardingMockDecoder(
196 std::unique_ptr<webrtc::AudioDecoder> real_decoder) {
197 class ForwardingMockDecoder : public StrictMock<webrtc::MockAudioDecoder> {
198 public:
Steve Anton36b29d12017-10-30 09:57:42 -0700199 explicit ForwardingMockDecoder(std::unique_ptr<AudioDecoder> decoder)
kwiberg9e5b11e2017-04-19 03:47:57 -0700200 : decoder_(std::move(decoder)) {}
201
202 private:
203 std::unique_ptr<AudioDecoder> decoder_;
204 };
205
206 const auto dec = real_decoder.get(); // For lambda capturing.
207 auto mock_decoder =
208 rtc::MakeUnique<ForwardingMockDecoder>(std::move(real_decoder));
209 EXPECT_CALL(*mock_decoder, Channels())
210 .Times(AtLeast(1))
211 .WillRepeatedly(Invoke([dec] { return dec->Channels(); }));
212 EXPECT_CALL(*mock_decoder, DecodeInternal(_, _, _, _, _))
213 .Times(AtLeast(1))
214 .WillRepeatedly(
215 Invoke([dec](const uint8_t* encoded, size_t encoded_len,
216 int sample_rate_hz, int16_t* decoded,
217 webrtc::AudioDecoder::SpeechType* speech_type) {
218 return dec->Decode(encoded, encoded_len, sample_rate_hz,
219 std::numeric_limits<size_t>::max(), decoded,
220 speech_type);
221 }));
222 EXPECT_CALL(*mock_decoder, Die());
223 EXPECT_CALL(*mock_decoder, HasDecodePlc()).WillRepeatedly(Invoke([dec] {
224 return dec->HasDecodePlc();
225 }));
226 EXPECT_CALL(*mock_decoder, IncomingPacket(_, _, _, _, _))
227 .Times(AtLeast(1))
228 .WillRepeatedly(Invoke([dec](const uint8_t* payload, size_t payload_len,
229 uint16_t rtp_sequence_number,
230 uint32_t rtp_timestamp,
231 uint32_t arrival_timestamp) {
232 return dec->IncomingPacket(payload, payload_len, rtp_sequence_number,
233 rtp_timestamp, arrival_timestamp);
234 }));
235 EXPECT_CALL(*mock_decoder, PacketDuration(_, _))
236 .Times(AtLeast(1))
237 .WillRepeatedly(Invoke([dec](const uint8_t* encoded, size_t encoded_len) {
238 return dec->PacketDuration(encoded, encoded_len);
239 }));
240 EXPECT_CALL(*mock_decoder, SampleRateHz())
241 .Times(AtLeast(1))
242 .WillRepeatedly(Invoke([dec] { return dec->SampleRateHz(); }));
243
244 return std::move(mock_decoder);
245}
246
247rtc::scoped_refptr<webrtc::AudioDecoderFactory>
248CreateForwardingMockDecoderFactory(
249 webrtc::AudioDecoderFactory* real_decoder_factory) {
250 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
251 new rtc::RefCountedObject<StrictMock<webrtc::MockAudioDecoderFactory>>;
252 EXPECT_CALL(*mock_decoder_factory, GetSupportedDecoders())
253 .Times(AtLeast(1))
254 .WillRepeatedly(Invoke([real_decoder_factory] {
255 return real_decoder_factory->GetSupportedDecoders();
256 }));
257 EXPECT_CALL(*mock_decoder_factory, IsSupportedDecoder(_))
258 .Times(AtLeast(1))
259 .WillRepeatedly(
260 Invoke([real_decoder_factory](const webrtc::SdpAudioFormat& format) {
261 return real_decoder_factory->IsSupportedDecoder(format);
262 }));
263 EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _))
264 .Times(AtLeast(2))
265 .WillRepeatedly(
266 Invoke([real_decoder_factory](
267 const webrtc::SdpAudioFormat& format,
268 std::unique_ptr<webrtc::AudioDecoder>* return_value) {
269 auto real_decoder = real_decoder_factory->MakeAudioDecoder(format);
270 *return_value =
271 real_decoder
272 ? CreateForwardingMockDecoder(std::move(real_decoder))
273 : nullptr;
274 }));
275 return mock_decoder_factory;
276}
277
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200278struct AudioEncoderUnicornSparklesRainbow {
279 using Config = webrtc::AudioEncoderL16::Config;
280 static rtc::Optional<Config> SdpToConfig(webrtc::SdpAudioFormat format) {
281 if (STR_CASE_CMP(format.name.c_str(), "UnicornSparklesRainbow") == 0) {
282 const webrtc::SdpAudioFormat::Parameters expected_params = {
283 {"num_horns", "1"}};
284 EXPECT_EQ(expected_params, format.parameters);
285 format.parameters.clear();
286 format.name = "L16";
287 return webrtc::AudioEncoderL16::SdpToConfig(format);
288 } else {
Oskar Sundbom63e232a2017-11-16 10:57:03 +0100289 return rtc::nullopt;
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200290 }
291 }
292 static void AppendSupportedEncoders(
293 std::vector<webrtc::AudioCodecSpec>* specs) {
294 std::vector<webrtc::AudioCodecSpec> new_specs;
295 webrtc::AudioEncoderL16::AppendSupportedEncoders(&new_specs);
296 for (auto& spec : new_specs) {
297 spec.format.name = "UnicornSparklesRainbow";
298 EXPECT_TRUE(spec.format.parameters.empty());
299 spec.format.parameters.emplace("num_horns", "1");
300 specs->push_back(spec);
301 }
302 }
303 static webrtc::AudioCodecInfo QueryAudioEncoder(const Config& config) {
304 return webrtc::AudioEncoderL16::QueryAudioEncoder(config);
305 }
306 static std::unique_ptr<webrtc::AudioEncoder> MakeAudioEncoder(
307 const Config& config,
308 int payload_type) {
309 return webrtc::AudioEncoderL16::MakeAudioEncoder(config, payload_type);
310 }
311};
312
313struct AudioDecoderUnicornSparklesRainbow {
314 using Config = webrtc::AudioDecoderL16::Config;
315 static rtc::Optional<Config> SdpToConfig(webrtc::SdpAudioFormat format) {
316 if (STR_CASE_CMP(format.name.c_str(), "UnicornSparklesRainbow") == 0) {
317 const webrtc::SdpAudioFormat::Parameters expected_params = {
318 {"num_horns", "1"}};
319 EXPECT_EQ(expected_params, format.parameters);
320 format.parameters.clear();
321 format.name = "L16";
322 return webrtc::AudioDecoderL16::SdpToConfig(format);
323 } else {
Oskar Sundbom63e232a2017-11-16 10:57:03 +0100324 return rtc::nullopt;
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200325 }
326 }
327 static void AppendSupportedDecoders(
328 std::vector<webrtc::AudioCodecSpec>* specs) {
329 std::vector<webrtc::AudioCodecSpec> new_specs;
330 webrtc::AudioDecoderL16::AppendSupportedDecoders(&new_specs);
331 for (auto& spec : new_specs) {
332 spec.format.name = "UnicornSparklesRainbow";
333 EXPECT_TRUE(spec.format.parameters.empty());
334 spec.format.parameters.emplace("num_horns", "1");
335 specs->push_back(spec);
336 }
337 }
338 static std::unique_ptr<webrtc::AudioDecoder> MakeAudioDecoder(
339 const Config& config) {
340 return webrtc::AudioDecoderL16::MakeAudioDecoder(config);
341 }
342};
343
344} // namespace
345
kjellander@webrtc.org70c0e292015-11-30 21:45:35 +0100346// Disabled for TSan v2, see
347// https://bugs.chromium.org/p/webrtc/issues/detail?id=4719 for details.
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100348// Disabled for Mac, see
349// https://bugs.chromium.org/p/webrtc/issues/detail?id=5231 for details.
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200350#if defined(THREAD_SANITIZER) || defined(WEBRTC_MAC)
Steve Anton36da6ff2018-02-16 16:04:20 -0800351TEST_P(PeerConnectionEndToEndTest, DISABLED_Call) {
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200352#else
Steve Anton36da6ff2018-02-16 16:04:20 -0800353TEST_P(PeerConnectionEndToEndTest, Call) {
354#endif // defined(THREAD_SANITIZER) || defined(WEBRTC_MAC)
kwiberg9e5b11e2017-04-19 03:47:57 -0700355 rtc::scoped_refptr<webrtc::AudioDecoderFactory> real_decoder_factory =
356 webrtc::CreateBuiltinAudioDecoderFactory();
357 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
358 CreateForwardingMockDecoderFactory(real_decoder_factory.get()));
wu@webrtc.org364f2042013-11-20 21:49:41 +0000359 GetAndAddUserMedia();
360 Negotiate();
361 WaitForCallEstablished();
362}
363
philipel7703b272016-11-28 16:23:12 +0100364#if !defined(ADDRESS_SANITIZER)
Steve Anton191c39f2018-01-24 19:35:55 -0800365TEST_P(PeerConnectionEndToEndTest, CallWithLegacySdp) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000366 FakeConstraints pc_constraints;
367 pc_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
368 false);
kwiberg9e5b11e2017-04-19 03:47:57 -0700369 CreatePcs(&pc_constraints, webrtc::CreateBuiltinAudioEncoderFactory(),
370 webrtc::CreateBuiltinAudioDecoderFactory());
wu@webrtc.org364f2042013-11-20 21:49:41 +0000371 GetAndAddUserMedia();
372 Negotiate();
373 WaitForCallEstablished();
374}
philipel7703b272016-11-28 16:23:12 +0100375#endif // !defined(ADDRESS_SANITIZER)
wu@webrtc.orgb43202d2013-11-22 19:14:25 +0000376
Steve Anton191c39f2018-01-24 19:35:55 -0800377TEST_P(PeerConnectionEndToEndTest, CallWithCustomCodec) {
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200378 CreatePcs(
379 nullptr,
380 webrtc::CreateAudioEncoderFactory<AudioEncoderUnicornSparklesRainbow>(),
381 webrtc::CreateAudioDecoderFactory<AudioDecoderUnicornSparklesRainbow>());
382 GetAndAddUserMedia();
383 Negotiate();
384 WaitForCallEstablished();
385}
386
deadbeef40610e22016-12-22 10:53:38 -0800387#ifdef HAVE_SCTP
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000388// Verifies that a DataChannel created before the negotiation can transition to
389// "OPEN" and transfer data.
Steve Anton191c39f2018-01-24 19:35:55 -0800390TEST_P(PeerConnectionEndToEndTest, CreateDataChannelBeforeNegotiate) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700391 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700392 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000393
394 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000395 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000396 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000397 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000398 callee_->CreateDataChannel("data", init));
399
400 Negotiate();
401 WaitForConnection();
402
403 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
404 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
405
406 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[0]);
407 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
408
409 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
410 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
411}
412
413// Verifies that a DataChannel created after the negotiation can transition to
414// "OPEN" and transfer data.
Steve Anton191c39f2018-01-24 19:35:55 -0800415TEST_P(PeerConnectionEndToEndTest, CreateDataChannelAfterNegotiate) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700416 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700417 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000418
419 webrtc::DataChannelInit init;
420
421 // This DataChannel is for creating the data content in the negotiation.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000422 rtc::scoped_refptr<DataChannelInterface> dummy(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000423 caller_->CreateDataChannel("data", init));
424 Negotiate();
425 WaitForConnection();
426
Taylor Brandstetterbf2f5692016-06-29 11:22:47 -0700427 // Wait for the data channel created pre-negotiation to be opened.
428 WaitForDataChannelsToOpen(dummy, callee_signaled_data_channels_, 0);
429
430 // Create new DataChannels after the negotiation and verify their states.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000431 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000432 caller_->CreateDataChannel("hello", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000433 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000434 callee_->CreateDataChannel("hello", init));
435
436 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
437 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
438
439 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
440 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
441
442 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
443 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
444}
445
446// Verifies that DataChannel IDs are even/odd based on the DTLS roles.
Steve Anton191c39f2018-01-24 19:35:55 -0800447TEST_P(PeerConnectionEndToEndTest, DataChannelIdAssignment) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700448 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700449 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000450
451 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000452 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000453 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000454 rtc::scoped_refptr<DataChannelInterface> callee_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000455 callee_->CreateDataChannel("data", init));
456
457 Negotiate();
458 WaitForConnection();
459
460 EXPECT_EQ(1U, caller_dc_1->id() % 2);
461 EXPECT_EQ(0U, callee_dc_1->id() % 2);
462
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000463 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000464 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000465 rtc::scoped_refptr<DataChannelInterface> callee_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000466 callee_->CreateDataChannel("data", init));
467
468 EXPECT_EQ(1U, caller_dc_2->id() % 2);
469 EXPECT_EQ(0U, callee_dc_2->id() % 2);
470}
471
472// Verifies that the message is received by the right remote DataChannel when
473// there are multiple DataChannels.
Steve Anton191c39f2018-01-24 19:35:55 -0800474TEST_P(PeerConnectionEndToEndTest,
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000475 MessageTransferBetweenTwoPairsOfDataChannels) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700476 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700477 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000478
479 webrtc::DataChannelInit init;
480
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000481 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000482 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000483 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000484 caller_->CreateDataChannel("data", init));
485
486 Negotiate();
487 WaitForConnection();
488 WaitForDataChannelsToOpen(caller_dc_1, callee_signaled_data_channels_, 0);
489 WaitForDataChannelsToOpen(caller_dc_2, callee_signaled_data_channels_, 1);
490
kwibergd1fe2812016-04-27 06:47:29 -0700491 std::unique_ptr<webrtc::MockDataChannelObserver> dc_1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000492 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[0]));
493
kwibergd1fe2812016-04-27 06:47:29 -0700494 std::unique_ptr<webrtc::MockDataChannelObserver> dc_2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000495 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[1]));
496
497 const std::string message_1 = "hello 1";
498 const std::string message_2 = "hello 2";
499
500 caller_dc_1->Send(webrtc::DataBuffer(message_1));
501 EXPECT_EQ_WAIT(message_1, dc_1_observer->last_message(), kMaxWait);
502
503 caller_dc_2->Send(webrtc::DataBuffer(message_2));
504 EXPECT_EQ_WAIT(message_2, dc_2_observer->last_message(), kMaxWait);
505
506 EXPECT_EQ(1U, dc_1_observer->received_message_count());
507 EXPECT_EQ(1U, dc_2_observer->received_message_count());
508}
deadbeefab9b2d12015-10-14 11:33:11 -0700509
510// Verifies that a DataChannel added from an OPEN message functions after
511// a channel has been previously closed (webrtc issue 3778).
512// This previously failed because the new channel re-uses the ID of the closed
513// channel, and the closed channel was incorrectly still assigned to the id.
514// TODO(deadbeef): This is disabled because there's currently a race condition
515// caused by the fact that a data channel signals that it's closed before it
516// really is. Re-enable this test once that's fixed.
deadbeefe2213ce2016-11-03 16:01:57 -0700517// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=4453
Steve Anton191c39f2018-01-24 19:35:55 -0800518TEST_P(PeerConnectionEndToEndTest,
deadbeefab9b2d12015-10-14 11:33:11 -0700519 DISABLED_DataChannelFromOpenWorksAfterClose) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700520 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700521 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
deadbeefab9b2d12015-10-14 11:33:11 -0700522
523 webrtc::DataChannelInit init;
524 rtc::scoped_refptr<DataChannelInterface> caller_dc(
525 caller_->CreateDataChannel("data", init));
526
527 Negotiate();
528 WaitForConnection();
529
530 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
531 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
532
533 // Create a new channel and ensure it works after closing the previous one.
534 caller_dc = caller_->CreateDataChannel("data2", init);
535
536 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
537 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
538
539 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
540}
deadbeefbd292462015-12-14 18:15:29 -0800541
542// This tests that if a data channel is closed remotely while not referenced
543// by the application (meaning only the PeerConnection contributes to its
544// reference count), no memory access violation will occur.
545// See: https://code.google.com/p/chromium/issues/detail?id=565048
Steve Anton191c39f2018-01-24 19:35:55 -0800546TEST_P(PeerConnectionEndToEndTest, CloseDataChannelRemotelyWhileNotReferenced) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700547 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700548 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
deadbeefbd292462015-12-14 18:15:29 -0800549
550 webrtc::DataChannelInit init;
551 rtc::scoped_refptr<DataChannelInterface> caller_dc(
552 caller_->CreateDataChannel("data", init));
553
554 Negotiate();
555 WaitForConnection();
556
557 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
558 // This removes the reference to the remote data channel that we hold.
559 callee_signaled_data_channels_.clear();
560 caller_dc->Close();
561 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, caller_dc->state(), kMaxWait);
562
563 // Wait for a bit longer so the remote data channel will receive the
564 // close message and be destroyed.
565 rtc::Thread::Current()->ProcessMessages(100);
566}
deadbeef40610e22016-12-22 10:53:38 -0800567#endif // HAVE_SCTP
Steve Anton191c39f2018-01-24 19:35:55 -0800568
569INSTANTIATE_TEST_CASE_P(PeerConnectionEndToEndTest,
570 PeerConnectionEndToEndTest,
571 Values(SdpSemantics::kPlanB,
572 SdpSemantics::kUnifiedPlan));