blob: 17f48bf326ed9f8e5a45f026c0bd45f9548e24fc [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;
37using testing::_;
wu@webrtc.org364f2042013-11-20 21:49:41 +000038
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000039using webrtc::DataChannelInterface;
wu@webrtc.org364f2042013-11-20 21:49:41 +000040using webrtc::FakeConstraints;
41using webrtc::MediaConstraintsInterface;
42using webrtc::MediaStreamInterface;
43using webrtc::PeerConnectionInterface;
44
45namespace {
46
Honghai Zhang82d78622016-05-06 11:29:15 -070047const int kMaxWait = 10000;
wu@webrtc.org364f2042013-11-20 21:49:41 +000048
wu@webrtc.org364f2042013-11-20 21:49:41 +000049} // namespace
50
51class PeerConnectionEndToEndTest
52 : public sigslot::has_slots<>,
53 public testing::Test {
54 public:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000055 typedef std::vector<rtc::scoped_refptr<DataChannelInterface> >
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000056 DataChannelList;
57
perkj57db6522016-04-08 08:16:33 -070058 PeerConnectionEndToEndTest() {
tommie7251592017-07-14 14:44:46 -070059 network_thread_ = rtc::Thread::CreateWithSocketServer();
60 worker_thread_ = rtc::Thread::Create();
61 RTC_CHECK(network_thread_->Start());
62 RTC_CHECK(worker_thread_->Start());
perkj57db6522016-04-08 08:16:33 -070063 caller_ = new rtc::RefCountedObject<PeerConnectionTestWrapper>(
tommie7251592017-07-14 14:44:46 -070064 "caller", network_thread_.get(), worker_thread_.get());
perkj57db6522016-04-08 08:16:33 -070065 callee_ = new rtc::RefCountedObject<PeerConnectionTestWrapper>(
tommie7251592017-07-14 14:44:46 -070066 "callee", network_thread_.get(), worker_thread_.get());
zhihuang9763d562016-08-05 11:14:50 -070067 webrtc::PeerConnectionInterface::IceServer ice_server;
68 ice_server.uri = "stun:stun.l.google.com:19302";
69 config_.servers.push_back(ice_server);
70
phoglund37ebcf02016-01-08 05:04:57 -080071#ifdef WEBRTC_ANDROID
72 webrtc::InitializeAndroidObjects();
73#endif
wu@webrtc.org364f2042013-11-20 21:49:41 +000074 }
75
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010076 void CreatePcs(const MediaConstraintsInterface* pc_constraints,
77 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
78 audio_encoder_factory,
79 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
80 audio_decoder_factory) {
kwiberg9e5b11e2017-04-19 03:47:57 -070081 EXPECT_TRUE(caller_->CreatePc(
82 pc_constraints, config_, audio_encoder_factory, audio_decoder_factory));
83 EXPECT_TRUE(callee_->CreatePc(
84 pc_constraints, config_, audio_encoder_factory, audio_decoder_factory));
wu@webrtc.org364f2042013-11-20 21:49:41 +000085 PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000086
87 caller_->SignalOnDataChannel.connect(
88 this, &PeerConnectionEndToEndTest::OnCallerAddedDataChanel);
89 callee_->SignalOnDataChannel.connect(
90 this, &PeerConnectionEndToEndTest::OnCalleeAddedDataChannel);
wu@webrtc.org364f2042013-11-20 21:49:41 +000091 }
92
93 void GetAndAddUserMedia() {
94 FakeConstraints audio_constraints;
95 FakeConstraints video_constraints;
96 GetAndAddUserMedia(true, audio_constraints, true, video_constraints);
97 }
98
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010099 void GetAndAddUserMedia(bool audio,
100 const FakeConstraints& audio_constraints,
101 bool video,
102 const FakeConstraints& video_constraints) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000103 caller_->GetAndAddUserMedia(audio, audio_constraints,
104 video, video_constraints);
105 callee_->GetAndAddUserMedia(audio, audio_constraints,
106 video, video_constraints);
107 }
108
109 void Negotiate() {
110 caller_->CreateOffer(NULL);
111 }
112
113 void WaitForCallEstablished() {
114 caller_->WaitForCallEstablished();
115 callee_->WaitForCallEstablished();
116 }
117
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000118 void WaitForConnection() {
119 caller_->WaitForConnection();
120 callee_->WaitForConnection();
121 }
122
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000123 void OnCallerAddedDataChanel(DataChannelInterface* dc) {
124 caller_signaled_data_channels_.push_back(dc);
125 }
126
127 void OnCalleeAddedDataChannel(DataChannelInterface* dc) {
128 callee_signaled_data_channels_.push_back(dc);
129 }
130
131 // Tests that |dc1| and |dc2| can send to and receive from each other.
132 void TestDataChannelSendAndReceive(
133 DataChannelInterface* dc1, DataChannelInterface* dc2) {
kwibergd1fe2812016-04-27 06:47:29 -0700134 std::unique_ptr<webrtc::MockDataChannelObserver> dc1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000135 new webrtc::MockDataChannelObserver(dc1));
136
kwibergd1fe2812016-04-27 06:47:29 -0700137 std::unique_ptr<webrtc::MockDataChannelObserver> dc2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000138 new webrtc::MockDataChannelObserver(dc2));
139
140 static const std::string kDummyData = "abcdefg";
141 webrtc::DataBuffer buffer(kDummyData);
142 EXPECT_TRUE(dc1->Send(buffer));
143 EXPECT_EQ_WAIT(kDummyData, dc2_observer->last_message(), kMaxWait);
144
145 EXPECT_TRUE(dc2->Send(buffer));
146 EXPECT_EQ_WAIT(kDummyData, dc1_observer->last_message(), kMaxWait);
147
148 EXPECT_EQ(1U, dc1_observer->received_message_count());
149 EXPECT_EQ(1U, dc2_observer->received_message_count());
150 }
151
152 void WaitForDataChannelsToOpen(DataChannelInterface* local_dc,
153 const DataChannelList& remote_dc_list,
154 size_t remote_dc_index) {
155 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, local_dc->state(), kMaxWait);
156
157 EXPECT_TRUE_WAIT(remote_dc_list.size() > remote_dc_index, kMaxWait);
158 EXPECT_EQ_WAIT(DataChannelInterface::kOpen,
159 remote_dc_list[remote_dc_index]->state(),
160 kMaxWait);
161 EXPECT_EQ(local_dc->id(), remote_dc_list[remote_dc_index]->id());
162 }
163
164 void CloseDataChannels(DataChannelInterface* local_dc,
165 const DataChannelList& remote_dc_list,
166 size_t remote_dc_index) {
167 local_dc->Close();
168 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, local_dc->state(), kMaxWait);
169 EXPECT_EQ_WAIT(DataChannelInterface::kClosed,
170 remote_dc_list[remote_dc_index]->state(),
171 kMaxWait);
172 }
173
wu@webrtc.org364f2042013-11-20 21:49:41 +0000174 protected:
tommie7251592017-07-14 14:44:46 -0700175 std::unique_ptr<rtc::Thread> network_thread_;
176 std::unique_ptr<rtc::Thread> worker_thread_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000177 rtc::scoped_refptr<PeerConnectionTestWrapper> caller_;
178 rtc::scoped_refptr<PeerConnectionTestWrapper> callee_;
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000179 DataChannelList caller_signaled_data_channels_;
180 DataChannelList callee_signaled_data_channels_;
zhihuang9763d562016-08-05 11:14:50 -0700181 webrtc::PeerConnectionInterface::RTCConfiguration config_;
wu@webrtc.org364f2042013-11-20 21:49:41 +0000182};
183
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200184namespace {
185
kwiberg9e5b11e2017-04-19 03:47:57 -0700186std::unique_ptr<webrtc::AudioDecoder> CreateForwardingMockDecoder(
187 std::unique_ptr<webrtc::AudioDecoder> real_decoder) {
188 class ForwardingMockDecoder : public StrictMock<webrtc::MockAudioDecoder> {
189 public:
Steve Anton36b29d12017-10-30 09:57:42 -0700190 explicit ForwardingMockDecoder(std::unique_ptr<AudioDecoder> decoder)
kwiberg9e5b11e2017-04-19 03:47:57 -0700191 : decoder_(std::move(decoder)) {}
192
193 private:
194 std::unique_ptr<AudioDecoder> decoder_;
195 };
196
197 const auto dec = real_decoder.get(); // For lambda capturing.
198 auto mock_decoder =
199 rtc::MakeUnique<ForwardingMockDecoder>(std::move(real_decoder));
200 EXPECT_CALL(*mock_decoder, Channels())
201 .Times(AtLeast(1))
202 .WillRepeatedly(Invoke([dec] { return dec->Channels(); }));
203 EXPECT_CALL(*mock_decoder, DecodeInternal(_, _, _, _, _))
204 .Times(AtLeast(1))
205 .WillRepeatedly(
206 Invoke([dec](const uint8_t* encoded, size_t encoded_len,
207 int sample_rate_hz, int16_t* decoded,
208 webrtc::AudioDecoder::SpeechType* speech_type) {
209 return dec->Decode(encoded, encoded_len, sample_rate_hz,
210 std::numeric_limits<size_t>::max(), decoded,
211 speech_type);
212 }));
213 EXPECT_CALL(*mock_decoder, Die());
214 EXPECT_CALL(*mock_decoder, HasDecodePlc()).WillRepeatedly(Invoke([dec] {
215 return dec->HasDecodePlc();
216 }));
217 EXPECT_CALL(*mock_decoder, IncomingPacket(_, _, _, _, _))
218 .Times(AtLeast(1))
219 .WillRepeatedly(Invoke([dec](const uint8_t* payload, size_t payload_len,
220 uint16_t rtp_sequence_number,
221 uint32_t rtp_timestamp,
222 uint32_t arrival_timestamp) {
223 return dec->IncomingPacket(payload, payload_len, rtp_sequence_number,
224 rtp_timestamp, arrival_timestamp);
225 }));
226 EXPECT_CALL(*mock_decoder, PacketDuration(_, _))
227 .Times(AtLeast(1))
228 .WillRepeatedly(Invoke([dec](const uint8_t* encoded, size_t encoded_len) {
229 return dec->PacketDuration(encoded, encoded_len);
230 }));
231 EXPECT_CALL(*mock_decoder, SampleRateHz())
232 .Times(AtLeast(1))
233 .WillRepeatedly(Invoke([dec] { return dec->SampleRateHz(); }));
234
235 return std::move(mock_decoder);
236}
237
238rtc::scoped_refptr<webrtc::AudioDecoderFactory>
239CreateForwardingMockDecoderFactory(
240 webrtc::AudioDecoderFactory* real_decoder_factory) {
241 rtc::scoped_refptr<webrtc::MockAudioDecoderFactory> mock_decoder_factory =
242 new rtc::RefCountedObject<StrictMock<webrtc::MockAudioDecoderFactory>>;
243 EXPECT_CALL(*mock_decoder_factory, GetSupportedDecoders())
244 .Times(AtLeast(1))
245 .WillRepeatedly(Invoke([real_decoder_factory] {
246 return real_decoder_factory->GetSupportedDecoders();
247 }));
248 EXPECT_CALL(*mock_decoder_factory, IsSupportedDecoder(_))
249 .Times(AtLeast(1))
250 .WillRepeatedly(
251 Invoke([real_decoder_factory](const webrtc::SdpAudioFormat& format) {
252 return real_decoder_factory->IsSupportedDecoder(format);
253 }));
254 EXPECT_CALL(*mock_decoder_factory, MakeAudioDecoderMock(_, _))
255 .Times(AtLeast(2))
256 .WillRepeatedly(
257 Invoke([real_decoder_factory](
258 const webrtc::SdpAudioFormat& format,
259 std::unique_ptr<webrtc::AudioDecoder>* return_value) {
260 auto real_decoder = real_decoder_factory->MakeAudioDecoder(format);
261 *return_value =
262 real_decoder
263 ? CreateForwardingMockDecoder(std::move(real_decoder))
264 : nullptr;
265 }));
266 return mock_decoder_factory;
267}
268
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200269struct AudioEncoderUnicornSparklesRainbow {
270 using Config = webrtc::AudioEncoderL16::Config;
271 static rtc::Optional<Config> SdpToConfig(webrtc::SdpAudioFormat format) {
272 if (STR_CASE_CMP(format.name.c_str(), "UnicornSparklesRainbow") == 0) {
273 const webrtc::SdpAudioFormat::Parameters expected_params = {
274 {"num_horns", "1"}};
275 EXPECT_EQ(expected_params, format.parameters);
276 format.parameters.clear();
277 format.name = "L16";
278 return webrtc::AudioEncoderL16::SdpToConfig(format);
279 } else {
Oskar Sundbom63e232a2017-11-16 10:57:03 +0100280 return rtc::nullopt;
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200281 }
282 }
283 static void AppendSupportedEncoders(
284 std::vector<webrtc::AudioCodecSpec>* specs) {
285 std::vector<webrtc::AudioCodecSpec> new_specs;
286 webrtc::AudioEncoderL16::AppendSupportedEncoders(&new_specs);
287 for (auto& spec : new_specs) {
288 spec.format.name = "UnicornSparklesRainbow";
289 EXPECT_TRUE(spec.format.parameters.empty());
290 spec.format.parameters.emplace("num_horns", "1");
291 specs->push_back(spec);
292 }
293 }
294 static webrtc::AudioCodecInfo QueryAudioEncoder(const Config& config) {
295 return webrtc::AudioEncoderL16::QueryAudioEncoder(config);
296 }
297 static std::unique_ptr<webrtc::AudioEncoder> MakeAudioEncoder(
298 const Config& config,
299 int payload_type) {
300 return webrtc::AudioEncoderL16::MakeAudioEncoder(config, payload_type);
301 }
302};
303
304struct AudioDecoderUnicornSparklesRainbow {
305 using Config = webrtc::AudioDecoderL16::Config;
306 static rtc::Optional<Config> SdpToConfig(webrtc::SdpAudioFormat format) {
307 if (STR_CASE_CMP(format.name.c_str(), "UnicornSparklesRainbow") == 0) {
308 const webrtc::SdpAudioFormat::Parameters expected_params = {
309 {"num_horns", "1"}};
310 EXPECT_EQ(expected_params, format.parameters);
311 format.parameters.clear();
312 format.name = "L16";
313 return webrtc::AudioDecoderL16::SdpToConfig(format);
314 } else {
Oskar Sundbom63e232a2017-11-16 10:57:03 +0100315 return rtc::nullopt;
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200316 }
317 }
318 static void AppendSupportedDecoders(
319 std::vector<webrtc::AudioCodecSpec>* specs) {
320 std::vector<webrtc::AudioCodecSpec> new_specs;
321 webrtc::AudioDecoderL16::AppendSupportedDecoders(&new_specs);
322 for (auto& spec : new_specs) {
323 spec.format.name = "UnicornSparklesRainbow";
324 EXPECT_TRUE(spec.format.parameters.empty());
325 spec.format.parameters.emplace("num_horns", "1");
326 specs->push_back(spec);
327 }
328 }
329 static std::unique_ptr<webrtc::AudioDecoder> MakeAudioDecoder(
330 const Config& config) {
331 return webrtc::AudioDecoderL16::MakeAudioDecoder(config);
332 }
333};
334
335} // namespace
336
kjellander@webrtc.org70c0e292015-11-30 21:45:35 +0100337// Disabled for TSan v2, see
338// https://bugs.chromium.org/p/webrtc/issues/detail?id=4719 for details.
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100339// Disabled for Mac, see
340// https://bugs.chromium.org/p/webrtc/issues/detail?id=5231 for details.
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200341#if defined(THREAD_SANITIZER) || defined(WEBRTC_MAC)
342#define MAYBE_Call DISABLED_Call
343#else
344#define MAYBE_Call Call
345#endif
346TEST_F(PeerConnectionEndToEndTest, MAYBE_Call) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700347 rtc::scoped_refptr<webrtc::AudioDecoderFactory> real_decoder_factory =
348 webrtc::CreateBuiltinAudioDecoderFactory();
349 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
350 CreateForwardingMockDecoderFactory(real_decoder_factory.get()));
wu@webrtc.org364f2042013-11-20 21:49:41 +0000351 GetAndAddUserMedia();
352 Negotiate();
353 WaitForCallEstablished();
354}
355
philipel7703b272016-11-28 16:23:12 +0100356#if !defined(ADDRESS_SANITIZER)
deadbeefc9be0072015-12-14 18:27:57 -0800357TEST_F(PeerConnectionEndToEndTest, CallWithLegacySdp) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000358 FakeConstraints pc_constraints;
359 pc_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
360 false);
kwiberg9e5b11e2017-04-19 03:47:57 -0700361 CreatePcs(&pc_constraints, webrtc::CreateBuiltinAudioEncoderFactory(),
362 webrtc::CreateBuiltinAudioDecoderFactory());
wu@webrtc.org364f2042013-11-20 21:49:41 +0000363 GetAndAddUserMedia();
364 Negotiate();
365 WaitForCallEstablished();
366}
philipel7703b272016-11-28 16:23:12 +0100367#endif // !defined(ADDRESS_SANITIZER)
wu@webrtc.orgb43202d2013-11-22 19:14:25 +0000368
Karl Wibergc5bb00b2017-10-10 23:17:17 +0200369TEST_F(PeerConnectionEndToEndTest, CallWithCustomCodec) {
370 CreatePcs(
371 nullptr,
372 webrtc::CreateAudioEncoderFactory<AudioEncoderUnicornSparklesRainbow>(),
373 webrtc::CreateAudioDecoderFactory<AudioDecoderUnicornSparklesRainbow>());
374 GetAndAddUserMedia();
375 Negotiate();
376 WaitForCallEstablished();
377}
378
deadbeef40610e22016-12-22 10:53:38 -0800379#ifdef HAVE_SCTP
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000380// Verifies that a DataChannel created before the negotiation can transition to
381// "OPEN" and transfer data.
382TEST_F(PeerConnectionEndToEndTest, CreateDataChannelBeforeNegotiate) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700383 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700384 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000385
386 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000387 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000388 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000389 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000390 callee_->CreateDataChannel("data", init));
391
392 Negotiate();
393 WaitForConnection();
394
395 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
396 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
397
398 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[0]);
399 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
400
401 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
402 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
403}
404
405// Verifies that a DataChannel created after the negotiation can transition to
406// "OPEN" and transfer data.
Taylor Brandstetterbf2f5692016-06-29 11:22:47 -0700407TEST_F(PeerConnectionEndToEndTest, CreateDataChannelAfterNegotiate) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700408 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700409 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000410
411 webrtc::DataChannelInit init;
412
413 // This DataChannel is for creating the data content in the negotiation.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000414 rtc::scoped_refptr<DataChannelInterface> dummy(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000415 caller_->CreateDataChannel("data", init));
416 Negotiate();
417 WaitForConnection();
418
Taylor Brandstetterbf2f5692016-06-29 11:22:47 -0700419 // Wait for the data channel created pre-negotiation to be opened.
420 WaitForDataChannelsToOpen(dummy, callee_signaled_data_channels_, 0);
421
422 // Create new DataChannels after the negotiation and verify their states.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000423 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000424 caller_->CreateDataChannel("hello", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000425 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000426 callee_->CreateDataChannel("hello", init));
427
428 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
429 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
430
431 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
432 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
433
434 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
435 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
436}
437
438// Verifies that DataChannel IDs are even/odd based on the DTLS roles.
439TEST_F(PeerConnectionEndToEndTest, DataChannelIdAssignment) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700440 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700441 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000442
443 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000444 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000445 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000446 rtc::scoped_refptr<DataChannelInterface> callee_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000447 callee_->CreateDataChannel("data", init));
448
449 Negotiate();
450 WaitForConnection();
451
452 EXPECT_EQ(1U, caller_dc_1->id() % 2);
453 EXPECT_EQ(0U, callee_dc_1->id() % 2);
454
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000455 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000456 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000457 rtc::scoped_refptr<DataChannelInterface> callee_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000458 callee_->CreateDataChannel("data", init));
459
460 EXPECT_EQ(1U, caller_dc_2->id() % 2);
461 EXPECT_EQ(0U, callee_dc_2->id() % 2);
462}
463
464// Verifies that the message is received by the right remote DataChannel when
465// there are multiple DataChannels.
466TEST_F(PeerConnectionEndToEndTest,
467 MessageTransferBetweenTwoPairsOfDataChannels) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700468 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700469 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000470
471 webrtc::DataChannelInit init;
472
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000473 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000474 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000475 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000476 caller_->CreateDataChannel("data", init));
477
478 Negotiate();
479 WaitForConnection();
480 WaitForDataChannelsToOpen(caller_dc_1, callee_signaled_data_channels_, 0);
481 WaitForDataChannelsToOpen(caller_dc_2, callee_signaled_data_channels_, 1);
482
kwibergd1fe2812016-04-27 06:47:29 -0700483 std::unique_ptr<webrtc::MockDataChannelObserver> dc_1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000484 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[0]));
485
kwibergd1fe2812016-04-27 06:47:29 -0700486 std::unique_ptr<webrtc::MockDataChannelObserver> dc_2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000487 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[1]));
488
489 const std::string message_1 = "hello 1";
490 const std::string message_2 = "hello 2";
491
492 caller_dc_1->Send(webrtc::DataBuffer(message_1));
493 EXPECT_EQ_WAIT(message_1, dc_1_observer->last_message(), kMaxWait);
494
495 caller_dc_2->Send(webrtc::DataBuffer(message_2));
496 EXPECT_EQ_WAIT(message_2, dc_2_observer->last_message(), kMaxWait);
497
498 EXPECT_EQ(1U, dc_1_observer->received_message_count());
499 EXPECT_EQ(1U, dc_2_observer->received_message_count());
500}
deadbeefab9b2d12015-10-14 11:33:11 -0700501
502// Verifies that a DataChannel added from an OPEN message functions after
503// a channel has been previously closed (webrtc issue 3778).
504// This previously failed because the new channel re-uses the ID of the closed
505// channel, and the closed channel was incorrectly still assigned to the id.
506// TODO(deadbeef): This is disabled because there's currently a race condition
507// caused by the fact that a data channel signals that it's closed before it
508// really is. Re-enable this test once that's fixed.
deadbeefe2213ce2016-11-03 16:01:57 -0700509// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=4453
deadbeefab9b2d12015-10-14 11:33:11 -0700510TEST_F(PeerConnectionEndToEndTest,
511 DISABLED_DataChannelFromOpenWorksAfterClose) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700512 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700513 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
deadbeefab9b2d12015-10-14 11:33:11 -0700514
515 webrtc::DataChannelInit init;
516 rtc::scoped_refptr<DataChannelInterface> caller_dc(
517 caller_->CreateDataChannel("data", init));
518
519 Negotiate();
520 WaitForConnection();
521
522 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
523 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
524
525 // Create a new channel and ensure it works after closing the previous one.
526 caller_dc = caller_->CreateDataChannel("data2", init);
527
528 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
529 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
530
531 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
532}
deadbeefbd292462015-12-14 18:15:29 -0800533
534// This tests that if a data channel is closed remotely while not referenced
535// by the application (meaning only the PeerConnection contributes to its
536// reference count), no memory access violation will occur.
537// See: https://code.google.com/p/chromium/issues/detail?id=565048
538TEST_F(PeerConnectionEndToEndTest, CloseDataChannelRemotelyWhileNotReferenced) {
kwiberg9e5b11e2017-04-19 03:47:57 -0700539 CreatePcs(nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
kwiberg7a12b5a2017-04-27 03:55:57 -0700540 webrtc::MockAudioDecoderFactory::CreateEmptyFactory());
deadbeefbd292462015-12-14 18:15:29 -0800541
542 webrtc::DataChannelInit init;
543 rtc::scoped_refptr<DataChannelInterface> caller_dc(
544 caller_->CreateDataChannel("data", init));
545
546 Negotiate();
547 WaitForConnection();
548
549 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
550 // This removes the reference to the remote data channel that we hold.
551 callee_signaled_data_channels_.clear();
552 caller_dc->Close();
553 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, caller_dc->state(), kMaxWait);
554
555 // Wait for a bit longer so the remote data channel will receive the
556 // close message and be destroyed.
557 rtc::Thread::Current()->ProcessMessages(100);
558}
deadbeef40610e22016-12-22 10:53:38 -0800559#endif // HAVE_SCTP