1 /*
2  *  Copyright 2008 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "pc/channel_manager.h"
12 
13 #include <memory>
14 
15 #include "api/rtc_error.h"
16 #include "api/video/builtin_video_bitrate_allocator_factory.h"
17 #include "media/base/fake_media_engine.h"
18 #include "media/base/test_utils.h"
19 #include "media/engine/fake_webrtc_call.h"
20 #include "p2p/base/dtls_transport_internal.h"
21 #include "p2p/base/fake_dtls_transport.h"
22 #include "p2p/base/p2p_constants.h"
23 #include "p2p/base/packet_transport_internal.h"
24 #include "pc/dtls_srtp_transport.h"
25 #include "rtc_base/checks.h"
26 #include "rtc_base/thread.h"
27 #include "test/gtest.h"
28 
29 namespace cricket {
30 namespace {
31 const bool kDefaultSrtpRequired = true;
32 
33 static const AudioCodec kAudioCodecs[] = {
34     AudioCodec(97, "voice", 1, 2, 3),
35     AudioCodec(111, "OPUS", 48000, 32000, 2),
36 };
37 
38 static const VideoCodec kVideoCodecs[] = {
39     VideoCodec(99, "H264"),
40     VideoCodec(100, "VP8"),
41     VideoCodec(96, "rtx"),
42 };
43 
CreateFakeMediaEngine()44 std::unique_ptr<MediaEngineInterface> CreateFakeMediaEngine() {
45   auto fme = std::make_unique<FakeMediaEngine>();
46   fme->SetAudioCodecs(MAKE_VECTOR(kAudioCodecs));
47   fme->SetVideoCodecs(MAKE_VECTOR(kVideoCodecs));
48   return fme;
49 }
50 
51 }  // namespace
52 
53 class ChannelManagerTest : public ::testing::Test {
54  protected:
ChannelManagerTest()55   ChannelManagerTest()
56       : network_(rtc::Thread::CreateWithSocketServer()),
57         worker_(rtc::Thread::Current()),
58         video_bitrate_allocator_factory_(
59             webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
60         cm_(cricket::ChannelManager::Create(CreateFakeMediaEngine(),
61                                             std::make_unique<FakeDataEngine>(),
62                                             false,
63                                             worker_,
64                                             network_.get())),
65         fake_call_() {
66     network_->SetName("Network", this);
67     network_->Start();
68   }
69 
TestCreateDestroyChannels(webrtc::RtpTransportInternal * rtp_transport)70   void TestCreateDestroyChannels(webrtc::RtpTransportInternal* rtp_transport) {
71     RTC_DCHECK_RUN_ON(worker_);
72     cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
73         &fake_call_, cricket::MediaConfig(), rtp_transport,
74         rtc::Thread::Current(), cricket::CN_AUDIO, kDefaultSrtpRequired,
75         webrtc::CryptoOptions(), &ssrc_generator_, AudioOptions());
76     EXPECT_TRUE(voice_channel != nullptr);
77     cricket::VideoChannel* video_channel = cm_->CreateVideoChannel(
78         &fake_call_, cricket::MediaConfig(), rtp_transport,
79         rtc::Thread::Current(), cricket::CN_VIDEO, kDefaultSrtpRequired,
80         webrtc::CryptoOptions(), &ssrc_generator_, VideoOptions(),
81         video_bitrate_allocator_factory_.get());
82     EXPECT_TRUE(video_channel != nullptr);
83     cricket::RtpDataChannel* rtp_data_channel = cm_->CreateRtpDataChannel(
84         cricket::MediaConfig(), rtp_transport, rtc::Thread::Current(),
85         cricket::CN_DATA, kDefaultSrtpRequired, webrtc::CryptoOptions(),
86         &ssrc_generator_);
87     EXPECT_TRUE(rtp_data_channel != nullptr);
88     cm_->DestroyVideoChannel(video_channel);
89     cm_->DestroyVoiceChannel(voice_channel);
90     cm_->DestroyRtpDataChannel(rtp_data_channel);
91   }
92 
93   std::unique_ptr<rtc::Thread> network_;
94   rtc::Thread* const worker_;
95   std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
96       video_bitrate_allocator_factory_;
97   std::unique_ptr<cricket::ChannelManager> cm_;
98   cricket::FakeCall fake_call_;
99   rtc::UniqueRandomIdGenerator ssrc_generator_;
100 };
101 
TEST_F(ChannelManagerTest,SetVideoRtxEnabled)102 TEST_F(ChannelManagerTest, SetVideoRtxEnabled) {
103   std::vector<VideoCodec> send_codecs;
104   std::vector<VideoCodec> recv_codecs;
105   const VideoCodec rtx_codec(96, "rtx");
106 
107   // By default RTX is disabled.
108   cm_->GetSupportedVideoSendCodecs(&send_codecs);
109   EXPECT_FALSE(ContainsMatchingCodec(send_codecs, rtx_codec));
110   cm_->GetSupportedVideoSendCodecs(&recv_codecs);
111   EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec));
112 
113   // Enable and check.
114   cm_ = cricket::ChannelManager::Create(CreateFakeMediaEngine(),
115                                         std::make_unique<FakeDataEngine>(),
116                                         true, worker_, network_.get());
117   cm_->GetSupportedVideoSendCodecs(&send_codecs);
118   EXPECT_TRUE(ContainsMatchingCodec(send_codecs, rtx_codec));
119   cm_->GetSupportedVideoSendCodecs(&recv_codecs);
120   EXPECT_TRUE(ContainsMatchingCodec(recv_codecs, rtx_codec));
121 
122   // Disable and check.
123   cm_ = cricket::ChannelManager::Create(CreateFakeMediaEngine(),
124                                         std::make_unique<FakeDataEngine>(),
125                                         false, worker_, network_.get());
126   cm_->GetSupportedVideoSendCodecs(&send_codecs);
127   EXPECT_FALSE(ContainsMatchingCodec(send_codecs, rtx_codec));
128   cm_->GetSupportedVideoSendCodecs(&recv_codecs);
129   EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec));
130 }
131 
TEST_F(ChannelManagerTest,CreateDestroyChannels)132 TEST_F(ChannelManagerTest, CreateDestroyChannels) {
133   auto rtp_dtls_transport = std::make_unique<FakeDtlsTransport>(
134       "fake_dtls_transport", cricket::ICE_CANDIDATE_COMPONENT_RTP,
135       network_.get());
136   auto dtls_srtp_transport = std::make_unique<webrtc::DtlsSrtpTransport>(
137       /*rtcp_mux_required=*/true);
138   network_->Invoke<void>(
139       RTC_FROM_HERE, [&rtp_dtls_transport, &dtls_srtp_transport] {
140         dtls_srtp_transport->SetDtlsTransports(rtp_dtls_transport.get(),
141                                                /*rtcp_dtls_transport=*/nullptr);
142       });
143   TestCreateDestroyChannels(dtls_srtp_transport.get());
144 }
145 
146 }  // namespace cricket
147