blob: 18f84752f784afc118e436a19a8717aabb12fefa [file] [log] [blame]
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00001/*
kjellander65c7f672016-02-12 00:05:01 -08002 * Copyright 2008 The WebRTC project authors. All Rights Reserved.
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 *
kjellander65c7f672016-02-12 00:05:01 -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.
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
deadbeef112b2e92017-02-10 20:13:37 -080011#include <memory>
Zhi Huang2dfc42d2017-12-04 13:38:48 -080012#include <utility>
deadbeef112b2e92017-02-10 20:13:37 -080013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "logging/rtc_event_log/rtc_event_log.h"
15#include "media/base/fakemediaengine.h"
16#include "media/base/fakevideocapturer.h"
17#include "media/base/testutils.h"
18#include "media/engine/fakewebrtccall.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "pc/channelmanager.h"
Zhi Huangb5261582017-09-29 10:51:43 -070020#include "pc/test/faketransportcontroller.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/gunit.h"
22#include "rtc_base/logging.h"
23#include "rtc_base/thread.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000024
deadbeef1a2183d2017-02-10 23:44:49 -080025namespace {
deadbeef7af91dd2016-12-13 11:29:11 -080026const bool kDefaultSrtpRequired = true;
27}
28
29namespace cricket {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000030
31static const AudioCodec kAudioCodecs[] = {
deadbeef67cf2c12016-04-13 10:07:16 -070032 AudioCodec(97, "voice", 1, 2, 3), AudioCodec(111, "OPUS", 48000, 32000, 2),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033};
34
35static const VideoCodec kVideoCodecs[] = {
perkj26752742016-10-24 01:21:16 -070036 VideoCodec(99, "H264"), VideoCodec(100, "VP8"), VideoCodec(96, "rtx"),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037};
38
39class ChannelManagerTest : public testing::Test {
40 protected:
deadbeefcbecd352015-09-23 11:50:27 -070041 ChannelManagerTest()
tommie7251592017-07-14 14:44:46 -070042 : network_(rtc::Thread::CreateWithSocketServer()),
43 worker_(rtc::Thread::Create()),
44 fme_(new cricket::FakeMediaEngine()),
stefanc1aeaf02015-10-15 07:26:07 -070045 fdme_(new cricket::FakeDataEngine()),
deadbeef112b2e92017-02-10 20:13:37 -080046 cm_(new cricket::ChannelManager(
47 std::unique_ptr<MediaEngineInterface>(fme_),
48 std::unique_ptr<DataEngineInterface>(fdme_),
Steve Antonc9e15602017-11-06 15:40:09 -080049 rtc::Thread::Current(),
deadbeef112b2e92017-02-10 20:13:37 -080050 rtc::Thread::Current())),
skvlad11a9cbf2016-10-07 11:53:05 -070051 fake_call_(webrtc::Call::Config(&event_log_)),
stefanc1aeaf02015-10-15 07:26:07 -070052 transport_controller_(
deadbeef112b2e92017-02-10 20:13:37 -080053 new cricket::FakeTransportController(ICEROLE_CONTROLLING)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054 fme_->SetAudioCodecs(MAKE_VECTOR(kAudioCodecs));
55 fme_->SetVideoCodecs(MAKE_VECTOR(kVideoCodecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056 }
57
skvlad11a9cbf2016-10-07 11:53:05 -070058 webrtc::RtcEventLogNullImpl event_log_;
tommie7251592017-07-14 14:44:46 -070059 std::unique_ptr<rtc::Thread> network_;
60 std::unique_ptr<rtc::Thread> worker_;
deadbeef112b2e92017-02-10 20:13:37 -080061 // |fme_| and |fdme_| are actually owned by |cm_|.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000062 cricket::FakeMediaEngine* fme_;
63 cricket::FakeDataEngine* fdme_;
deadbeef112b2e92017-02-10 20:13:37 -080064 std::unique_ptr<cricket::ChannelManager> cm_;
stefanc1aeaf02015-10-15 07:26:07 -070065 cricket::FakeCall fake_call_;
deadbeef112b2e92017-02-10 20:13:37 -080066 std::unique_ptr<cricket::FakeTransportController> transport_controller_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067};
68
69// Test that we startup/shutdown properly.
70TEST_F(ChannelManagerTest, StartupShutdown) {
71 EXPECT_FALSE(cm_->initialized());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000072 EXPECT_EQ(rtc::Thread::Current(), cm_->worker_thread());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000073 EXPECT_TRUE(cm_->Init());
74 EXPECT_TRUE(cm_->initialized());
75 cm_->Terminate();
76 EXPECT_FALSE(cm_->initialized());
77}
78
79// Test that we startup/shutdown properly with a worker thread.
80TEST_F(ChannelManagerTest, StartupShutdownOnThread) {
tommie7251592017-07-14 14:44:46 -070081 network_->Start();
82 worker_->Start();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000083 EXPECT_FALSE(cm_->initialized());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000084 EXPECT_EQ(rtc::Thread::Current(), cm_->worker_thread());
tommie7251592017-07-14 14:44:46 -070085 EXPECT_TRUE(cm_->set_network_thread(network_.get()));
86 EXPECT_EQ(network_.get(), cm_->network_thread());
87 EXPECT_TRUE(cm_->set_worker_thread(worker_.get()));
88 EXPECT_EQ(worker_.get(), cm_->worker_thread());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000089 EXPECT_TRUE(cm_->Init());
90 EXPECT_TRUE(cm_->initialized());
Danil Chapovalov33b01f22016-05-11 19:55:27 +020091 // Setting the network or worker thread while initialized should fail.
92 EXPECT_FALSE(cm_->set_network_thread(rtc::Thread::Current()));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000093 EXPECT_FALSE(cm_->set_worker_thread(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000094 cm_->Terminate();
95 EXPECT_FALSE(cm_->initialized());
96}
97
henrike@webrtc.org28e20752013-07-10 00:45:36 +000098// Test that we can create and destroy a voice and video channel.
99TEST_F(ChannelManagerTest, CreateDestroyChannels) {
100 EXPECT_TRUE(cm_->Init());
zhihuangb2cdd932017-01-19 16:54:25 -0800101 cricket::DtlsTransportInternal* rtp_transport =
102 transport_controller_->CreateDtlsTransport(
zhihuangf5b251b2017-01-12 19:37:48 -0800103 cricket::CN_AUDIO, cricket::ICE_CANDIDATE_COMPONENT_RTP);
skvlad6c87a672016-05-17 17:49:52 -0700104 cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
nisseeaabdf62017-05-05 02:23:02 -0700105 &fake_call_, cricket::MediaConfig(),
106 rtp_transport, nullptr /*rtcp_transport*/,
deadbeef1a2183d2017-02-10 23:44:49 -0800107 rtc::Thread::Current(), cricket::CN_AUDIO, kDefaultSrtpRequired,
108 AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200109 EXPECT_TRUE(voice_channel != nullptr);
skvlad6c87a672016-05-17 17:49:52 -0700110 cricket::VideoChannel* video_channel = cm_->CreateVideoChannel(
nisseeaabdf62017-05-05 02:23:02 -0700111 &fake_call_, cricket::MediaConfig(),
112 rtp_transport, nullptr /*rtcp_transport*/,
deadbeef1a2183d2017-02-10 23:44:49 -0800113 rtc::Thread::Current(), cricket::CN_VIDEO, kDefaultSrtpRequired,
114 VideoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200115 EXPECT_TRUE(video_channel != nullptr);
deadbeef953c2ce2017-01-09 14:53:41 -0800116 cricket::RtpDataChannel* rtp_data_channel = cm_->CreateRtpDataChannel(
nisseeaabdf62017-05-05 02:23:02 -0700117 cricket::MediaConfig(), rtp_transport, nullptr /*rtcp_transport*/,
deadbeef1a2183d2017-02-10 23:44:49 -0800118 rtc::Thread::Current(), cricket::CN_DATA, kDefaultSrtpRequired);
deadbeef953c2ce2017-01-09 14:53:41 -0800119 EXPECT_TRUE(rtp_data_channel != nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000120 cm_->DestroyVideoChannel(video_channel);
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200121 cm_->DestroyVoiceChannel(voice_channel);
deadbeef953c2ce2017-01-09 14:53:41 -0800122 cm_->DestroyRtpDataChannel(rtp_data_channel);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000123 cm_->Terminate();
124}
125
126// Test that we can create and destroy a voice and video channel with a worker.
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +0000127TEST_F(ChannelManagerTest, CreateDestroyChannelsOnThread) {
tommie7251592017-07-14 14:44:46 -0700128 network_->Start();
129 worker_->Start();
130 EXPECT_TRUE(cm_->set_worker_thread(worker_.get()));
131 EXPECT_TRUE(cm_->set_network_thread(network_.get()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000132 EXPECT_TRUE(cm_->Init());
tommie7251592017-07-14 14:44:46 -0700133 transport_controller_.reset(new cricket::FakeTransportController(
134 network_.get(), ICEROLE_CONTROLLING));
zhihuangb2cdd932017-01-19 16:54:25 -0800135 cricket::DtlsTransportInternal* rtp_transport =
136 transport_controller_->CreateDtlsTransport(
zhihuangf5b251b2017-01-12 19:37:48 -0800137 cricket::CN_AUDIO, cricket::ICE_CANDIDATE_COMPONENT_RTP);
skvlad6c87a672016-05-17 17:49:52 -0700138 cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
nisseeaabdf62017-05-05 02:23:02 -0700139 &fake_call_, cricket::MediaConfig(),
140 rtp_transport, nullptr /*rtcp_transport*/,
deadbeef1a2183d2017-02-10 23:44:49 -0800141 rtc::Thread::Current(), cricket::CN_AUDIO, kDefaultSrtpRequired,
142 AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200143 EXPECT_TRUE(voice_channel != nullptr);
skvlad6c87a672016-05-17 17:49:52 -0700144 cricket::VideoChannel* video_channel = cm_->CreateVideoChannel(
nisseeaabdf62017-05-05 02:23:02 -0700145 &fake_call_, cricket::MediaConfig(),
146 rtp_transport, nullptr /*rtcp_transport*/,
deadbeef1a2183d2017-02-10 23:44:49 -0800147 rtc::Thread::Current(), cricket::CN_VIDEO, kDefaultSrtpRequired,
148 VideoOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200149 EXPECT_TRUE(video_channel != nullptr);
deadbeef953c2ce2017-01-09 14:53:41 -0800150 cricket::RtpDataChannel* rtp_data_channel = cm_->CreateRtpDataChannel(
nisseeaabdf62017-05-05 02:23:02 -0700151 cricket::MediaConfig(), rtp_transport, nullptr /*rtcp_transport*/,
deadbeef1a2183d2017-02-10 23:44:49 -0800152 rtc::Thread::Current(), cricket::CN_DATA, kDefaultSrtpRequired);
deadbeef953c2ce2017-01-09 14:53:41 -0800153 EXPECT_TRUE(rtp_data_channel != nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000154 cm_->DestroyVideoChannel(video_channel);
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200155 cm_->DestroyVoiceChannel(voice_channel);
deadbeef953c2ce2017-01-09 14:53:41 -0800156 cm_->DestroyRtpDataChannel(rtp_data_channel);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157 cm_->Terminate();
158}
159
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000160TEST_F(ChannelManagerTest, SetVideoRtxEnabled) {
161 std::vector<VideoCodec> codecs;
perkj26752742016-10-24 01:21:16 -0700162 const VideoCodec rtx_codec(96, "rtx");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163
164 // By default RTX is disabled.
magjed3cf8ece2016-11-10 03:36:53 -0800165 cm_->GetSupportedVideoCodecs(&codecs);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 EXPECT_FALSE(ContainsMatchingCodec(codecs, rtx_codec));
167
168 // Enable and check.
169 EXPECT_TRUE(cm_->SetVideoRtxEnabled(true));
magjed3cf8ece2016-11-10 03:36:53 -0800170 cm_->GetSupportedVideoCodecs(&codecs);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 EXPECT_TRUE(ContainsMatchingCodec(codecs, rtx_codec));
172
173 // Disable and check.
174 EXPECT_TRUE(cm_->SetVideoRtxEnabled(false));
magjed3cf8ece2016-11-10 03:36:53 -0800175 cm_->GetSupportedVideoCodecs(&codecs);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176 EXPECT_FALSE(ContainsMatchingCodec(codecs, rtx_codec));
177
178 // Cannot toggle rtx after initialization.
179 EXPECT_TRUE(cm_->Init());
180 EXPECT_FALSE(cm_->SetVideoRtxEnabled(true));
181 EXPECT_FALSE(cm_->SetVideoRtxEnabled(false));
182
183 // Can set again after terminate.
184 cm_->Terminate();
185 EXPECT_TRUE(cm_->SetVideoRtxEnabled(true));
magjed3cf8ece2016-11-10 03:36:53 -0800186 cm_->GetSupportedVideoCodecs(&codecs);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000187 EXPECT_TRUE(ContainsMatchingCodec(codecs, rtx_codec));
188}
189
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800190enum class RTPTransportType { kRtp, kSrtp, kDtlsSrtp };
191
192class ChannelManagerTestWithRtpTransport
193 : public ChannelManagerTest,
194 public ::testing::WithParamInterface<RTPTransportType> {
195 public:
196 std::unique_ptr<webrtc::RtpTransportInternal> CreateRtpTransport() {
197 RTPTransportType type = GetParam();
198 switch (type) {
199 case RTPTransportType::kRtp:
200 return CreatePlainRtpTransport();
201 case RTPTransportType::kSrtp:
202 return CreateSrtpTransport();
203 case RTPTransportType::kDtlsSrtp:
204 return CreateDtlsSrtpTransport();
205 }
206 return nullptr;
207 }
208
209 void TestCreateDestroyChannels(webrtc::RtpTransportInternal* rtp_transport) {
210 cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
211 &fake_call_, cricket::MediaConfig(), rtp_transport,
212 rtc::Thread::Current(), cricket::CN_AUDIO, kDefaultSrtpRequired,
213 AudioOptions());
214 EXPECT_TRUE(voice_channel != nullptr);
215 cricket::VideoChannel* video_channel = cm_->CreateVideoChannel(
216 &fake_call_, cricket::MediaConfig(), rtp_transport,
217 rtc::Thread::Current(), cricket::CN_VIDEO, kDefaultSrtpRequired,
218 VideoOptions());
219 EXPECT_TRUE(video_channel != nullptr);
220 cricket::RtpDataChannel* rtp_data_channel = cm_->CreateRtpDataChannel(
221 cricket::MediaConfig(), rtp_transport, rtc::Thread::Current(),
222 cricket::CN_DATA, kDefaultSrtpRequired);
223 EXPECT_TRUE(rtp_data_channel != nullptr);
224 cm_->DestroyVideoChannel(video_channel);
225 cm_->DestroyVoiceChannel(voice_channel);
226 cm_->DestroyRtpDataChannel(rtp_data_channel);
227 cm_->Terminate();
228 }
229
230 private:
231 std::unique_ptr<webrtc::RtpTransportInternal> CreatePlainRtpTransport() {
232 return rtc::MakeUnique<webrtc::RtpTransport>(/*rtcp_mux_required=*/true);
233 }
234
235 std::unique_ptr<webrtc::RtpTransportInternal> CreateSrtpTransport() {
236 auto rtp_transport =
237 rtc::MakeUnique<webrtc::RtpTransport>(/*rtcp_mux_required=*/true);
238 auto srtp_transport =
239 rtc::MakeUnique<webrtc::SrtpTransport>(std::move(rtp_transport));
240 return srtp_transport;
241 }
242
243 std::unique_ptr<webrtc::RtpTransportInternal> CreateDtlsSrtpTransport() {
244 auto rtp_transport =
245 rtc::MakeUnique<webrtc::RtpTransport>(/*rtcp_mux_required=*/true);
246 auto srtp_transport =
247 rtc::MakeUnique<webrtc::SrtpTransport>(std::move(rtp_transport));
248 auto dtls_srtp_transport_ =
249 rtc::MakeUnique<webrtc::DtlsSrtpTransport>(std::move(srtp_transport));
250 return dtls_srtp_transport_;
251 }
252};
253
254TEST_P(ChannelManagerTestWithRtpTransport, CreateDestroyChannels) {
255 EXPECT_TRUE(cm_->Init());
256 auto rtp_transport = CreateRtpTransport();
257 TestCreateDestroyChannels(rtp_transport.get());
258}
259
260TEST_P(ChannelManagerTestWithRtpTransport, CreateDestroyChannelsOnThread) {
261 network_->Start();
262 worker_->Start();
263 EXPECT_TRUE(cm_->set_worker_thread(worker_.get()));
264 EXPECT_TRUE(cm_->set_network_thread(network_.get()));
265 EXPECT_TRUE(cm_->Init());
266 auto rtp_transport = CreateRtpTransport();
267 TestCreateDestroyChannels(rtp_transport.get());
268}
269
270INSTANTIATE_TEST_CASE_P(ChannelManagerTest,
271 ChannelManagerTestWithRtpTransport,
272 ::testing::Values(RTPTransportType::kRtp,
273 RTPTransportType::kSrtp,
274 RTPTransportType::kDtlsSrtp));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000275} // namespace cricket