| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * libjingle | |
| 3 * Copyright 2008 Google Inc. | |
| 4 * | |
| 5 * Redistribution and use in source and binary forms, with or without | |
| 6 * modification, are permitted provided that the following conditions are met: | |
| 7 * | |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | |
| 9 * this list of conditions and the following disclaimer. | |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | |
| 11 * this list of conditions and the following disclaimer in the documentation | |
| 12 * and/or other materials provided with the distribution. | |
| 13 * 3. The name of the author may not be used to endorse or promote products | |
| 14 * derived from this software without specific prior written permission. | |
| 15 * | |
| 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
| 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
| 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | |
| 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
| 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
| 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
| 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
| 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 26 */ | |
| 27 | |
| 28 #include "talk/session/media/channelmanager.h" | |
| 29 #include "webrtc/api/fakemediacontroller.h" | |
| 30 #include "webrtc/base/gunit.h" | |
| 31 #include "webrtc/base/logging.h" | |
| 32 #include "webrtc/base/thread.h" | |
| 33 #include "webrtc/media/base/fakecapturemanager.h" | |
| 34 #include "webrtc/media/base/fakemediaengine.h" | |
| 35 #include "webrtc/media/base/fakevideocapturer.h" | |
| 36 #include "webrtc/media/base/testutils.h" | |
| 37 #include "webrtc/media/engine/fakewebrtccall.h" | |
| 38 #include "webrtc/p2p/base/faketransportcontroller.h" | |
| 39 | |
| 40 namespace cricket { | |
| 41 | |
| 42 static const AudioCodec kAudioCodecs[] = { | |
| 43 AudioCodec(97, "voice", 1, 2, 3, 0), | |
| 44 AudioCodec(111, "OPUS", 48000, 32000, 2, 0), | |
| 45 }; | |
| 46 | |
| 47 static const VideoCodec kVideoCodecs[] = { | |
| 48 VideoCodec(99, "H264", 100, 200, 300, 0), | |
| 49 VideoCodec(100, "VP8", 100, 200, 300, 0), | |
| 50 VideoCodec(96, "rtx", 100, 200, 300, 0), | |
| 51 }; | |
| 52 | |
| 53 class ChannelManagerTest : public testing::Test { | |
| 54 protected: | |
| 55 ChannelManagerTest() | |
| 56 : fme_(new cricket::FakeMediaEngine()), | |
| 57 fdme_(new cricket::FakeDataEngine()), | |
| 58 fcm_(new cricket::FakeCaptureManager()), | |
| 59 cm_(new cricket::ChannelManager(fme_, | |
| 60 fdme_, | |
| 61 fcm_, | |
| 62 rtc::Thread::Current())), | |
| 63 fake_call_(webrtc::Call::Config()), | |
| 64 fake_mc_(cm_, &fake_call_), | |
| 65 transport_controller_( | |
| 66 new cricket::FakeTransportController(ICEROLE_CONTROLLING)) {} | |
| 67 | |
| 68 virtual void SetUp() { | |
| 69 fme_->SetAudioCodecs(MAKE_VECTOR(kAudioCodecs)); | |
| 70 fme_->SetVideoCodecs(MAKE_VECTOR(kVideoCodecs)); | |
| 71 } | |
| 72 | |
| 73 virtual void TearDown() { | |
| 74 delete transport_controller_; | |
| 75 delete cm_; | |
| 76 cm_ = NULL; | |
| 77 fcm_ = NULL; | |
| 78 fdme_ = NULL; | |
| 79 fme_ = NULL; | |
| 80 } | |
| 81 | |
| 82 rtc::Thread worker_; | |
| 83 cricket::FakeMediaEngine* fme_; | |
| 84 cricket::FakeDataEngine* fdme_; | |
| 85 cricket::FakeCaptureManager* fcm_; | |
| 86 cricket::ChannelManager* cm_; | |
| 87 cricket::FakeCall fake_call_; | |
| 88 cricket::FakeMediaController fake_mc_; | |
| 89 cricket::FakeTransportController* transport_controller_; | |
| 90 }; | |
| 91 | |
| 92 // Test that we startup/shutdown properly. | |
| 93 TEST_F(ChannelManagerTest, StartupShutdown) { | |
| 94 EXPECT_FALSE(cm_->initialized()); | |
| 95 EXPECT_EQ(rtc::Thread::Current(), cm_->worker_thread()); | |
| 96 EXPECT_TRUE(cm_->Init()); | |
| 97 EXPECT_TRUE(cm_->initialized()); | |
| 98 cm_->Terminate(); | |
| 99 EXPECT_FALSE(cm_->initialized()); | |
| 100 } | |
| 101 | |
| 102 // Test that we startup/shutdown properly with a worker thread. | |
| 103 TEST_F(ChannelManagerTest, StartupShutdownOnThread) { | |
| 104 worker_.Start(); | |
| 105 EXPECT_FALSE(cm_->initialized()); | |
| 106 EXPECT_EQ(rtc::Thread::Current(), cm_->worker_thread()); | |
| 107 EXPECT_TRUE(cm_->set_worker_thread(&worker_)); | |
| 108 EXPECT_EQ(&worker_, cm_->worker_thread()); | |
| 109 EXPECT_TRUE(cm_->Init()); | |
| 110 EXPECT_TRUE(cm_->initialized()); | |
| 111 // Setting the worker thread while initialized should fail. | |
| 112 EXPECT_FALSE(cm_->set_worker_thread(rtc::Thread::Current())); | |
| 113 cm_->Terminate(); | |
| 114 EXPECT_FALSE(cm_->initialized()); | |
| 115 } | |
| 116 | |
| 117 // Test that we can create and destroy a voice and video channel. | |
| 118 TEST_F(ChannelManagerTest, CreateDestroyChannels) { | |
| 119 EXPECT_TRUE(cm_->Init()); | |
| 120 cricket::VoiceChannel* voice_channel = | |
| 121 cm_->CreateVoiceChannel(&fake_mc_, transport_controller_, | |
| 122 cricket::CN_AUDIO, false, AudioOptions()); | |
| 123 EXPECT_TRUE(voice_channel != nullptr); | |
| 124 cricket::VideoChannel* video_channel = | |
| 125 cm_->CreateVideoChannel(&fake_mc_, transport_controller_, | |
| 126 cricket::CN_VIDEO, false, VideoOptions()); | |
| 127 EXPECT_TRUE(video_channel != nullptr); | |
| 128 cricket::DataChannel* data_channel = cm_->CreateDataChannel( | |
| 129 transport_controller_, cricket::CN_DATA, false, cricket::DCT_RTP); | |
| 130 EXPECT_TRUE(data_channel != nullptr); | |
| 131 cm_->DestroyVideoChannel(video_channel); | |
| 132 cm_->DestroyVoiceChannel(voice_channel); | |
| 133 cm_->DestroyDataChannel(data_channel); | |
| 134 cm_->Terminate(); | |
| 135 } | |
| 136 | |
| 137 // Test that we can create and destroy a voice and video channel with a worker. | |
| 138 TEST_F(ChannelManagerTest, CreateDestroyChannelsOnThread) { | |
| 139 worker_.Start(); | |
| 140 EXPECT_TRUE(cm_->set_worker_thread(&worker_)); | |
| 141 EXPECT_TRUE(cm_->Init()); | |
| 142 delete transport_controller_; | |
| 143 transport_controller_ = | |
| 144 new cricket::FakeTransportController(&worker_, ICEROLE_CONTROLLING); | |
| 145 cricket::VoiceChannel* voice_channel = | |
| 146 cm_->CreateVoiceChannel(&fake_mc_, transport_controller_, | |
| 147 cricket::CN_AUDIO, false, AudioOptions()); | |
| 148 EXPECT_TRUE(voice_channel != nullptr); | |
| 149 cricket::VideoChannel* video_channel = | |
| 150 cm_->CreateVideoChannel(&fake_mc_, transport_controller_, | |
| 151 cricket::CN_VIDEO, false, VideoOptions()); | |
| 152 EXPECT_TRUE(video_channel != nullptr); | |
| 153 cricket::DataChannel* data_channel = cm_->CreateDataChannel( | |
| 154 transport_controller_, cricket::CN_DATA, false, cricket::DCT_RTP); | |
| 155 EXPECT_TRUE(data_channel != nullptr); | |
| 156 cm_->DestroyVideoChannel(video_channel); | |
| 157 cm_->DestroyVoiceChannel(voice_channel); | |
| 158 cm_->DestroyDataChannel(data_channel); | |
| 159 cm_->Terminate(); | |
| 160 } | |
| 161 | |
| 162 // Test that we fail to create a voice/video channel if the session is unable | |
| 163 // to create a cricket::TransportChannel | |
| 164 TEST_F(ChannelManagerTest, NoTransportChannelTest) { | |
| 165 EXPECT_TRUE(cm_->Init()); | |
| 166 transport_controller_->set_fail_channel_creation(true); | |
| 167 // The test is useless unless the session does not fail creating | |
| 168 // cricket::TransportChannel. | |
| 169 ASSERT_TRUE(transport_controller_->CreateTransportChannel_w( | |
| 170 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP) == nullptr); | |
| 171 | |
| 172 cricket::VoiceChannel* voice_channel = | |
| 173 cm_->CreateVoiceChannel(&fake_mc_, transport_controller_, | |
| 174 cricket::CN_AUDIO, false, AudioOptions()); | |
| 175 EXPECT_TRUE(voice_channel == nullptr); | |
| 176 cricket::VideoChannel* video_channel = | |
| 177 cm_->CreateVideoChannel(&fake_mc_, transport_controller_, | |
| 178 cricket::CN_VIDEO, false, VideoOptions()); | |
| 179 EXPECT_TRUE(video_channel == nullptr); | |
| 180 cricket::DataChannel* data_channel = cm_->CreateDataChannel( | |
| 181 transport_controller_, cricket::CN_DATA, false, cricket::DCT_RTP); | |
| 182 EXPECT_TRUE(data_channel == nullptr); | |
| 183 cm_->Terminate(); | |
| 184 } | |
| 185 | |
| 186 TEST_F(ChannelManagerTest, GetSetOutputVolumeBeforeInit) { | |
| 187 int level; | |
| 188 // Before init, SetOutputVolume() remembers the volume but does not change the | |
| 189 // volume of the engine. GetOutputVolume() should fail. | |
| 190 EXPECT_EQ(-1, fme_->output_volume()); | |
| 191 EXPECT_FALSE(cm_->GetOutputVolume(&level)); | |
| 192 EXPECT_FALSE(cm_->SetOutputVolume(-1)); // Invalid volume. | |
| 193 EXPECT_TRUE(cm_->SetOutputVolume(99)); | |
| 194 EXPECT_EQ(-1, fme_->output_volume()); | |
| 195 | |
| 196 // Init() will apply the remembered volume. | |
| 197 EXPECT_TRUE(cm_->Init()); | |
| 198 EXPECT_TRUE(cm_->GetOutputVolume(&level)); | |
| 199 EXPECT_EQ(99, level); | |
| 200 EXPECT_EQ(level, fme_->output_volume()); | |
| 201 | |
| 202 EXPECT_TRUE(cm_->SetOutputVolume(60)); | |
| 203 EXPECT_TRUE(cm_->GetOutputVolume(&level)); | |
| 204 EXPECT_EQ(60, level); | |
| 205 EXPECT_EQ(level, fme_->output_volume()); | |
| 206 } | |
| 207 | |
| 208 TEST_F(ChannelManagerTest, GetSetOutputVolume) { | |
| 209 int level; | |
| 210 EXPECT_TRUE(cm_->Init()); | |
| 211 EXPECT_TRUE(cm_->GetOutputVolume(&level)); | |
| 212 EXPECT_EQ(level, fme_->output_volume()); | |
| 213 | |
| 214 EXPECT_FALSE(cm_->SetOutputVolume(-1)); // Invalid volume. | |
| 215 EXPECT_TRUE(cm_->SetOutputVolume(60)); | |
| 216 EXPECT_EQ(60, fme_->output_volume()); | |
| 217 EXPECT_TRUE(cm_->GetOutputVolume(&level)); | |
| 218 EXPECT_EQ(60, level); | |
| 219 } | |
| 220 | |
| 221 TEST_F(ChannelManagerTest, SetVideoRtxEnabled) { | |
| 222 std::vector<VideoCodec> codecs; | |
| 223 const VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0); | |
| 224 | |
| 225 // By default RTX is disabled. | |
| 226 cm_->GetSupportedVideoCodecs(&codecs); | |
| 227 EXPECT_FALSE(ContainsMatchingCodec(codecs, rtx_codec)); | |
| 228 | |
| 229 // Enable and check. | |
| 230 EXPECT_TRUE(cm_->SetVideoRtxEnabled(true)); | |
| 231 cm_->GetSupportedVideoCodecs(&codecs); | |
| 232 EXPECT_TRUE(ContainsMatchingCodec(codecs, rtx_codec)); | |
| 233 | |
| 234 // Disable and check. | |
| 235 EXPECT_TRUE(cm_->SetVideoRtxEnabled(false)); | |
| 236 cm_->GetSupportedVideoCodecs(&codecs); | |
| 237 EXPECT_FALSE(ContainsMatchingCodec(codecs, rtx_codec)); | |
| 238 | |
| 239 // Cannot toggle rtx after initialization. | |
| 240 EXPECT_TRUE(cm_->Init()); | |
| 241 EXPECT_FALSE(cm_->SetVideoRtxEnabled(true)); | |
| 242 EXPECT_FALSE(cm_->SetVideoRtxEnabled(false)); | |
| 243 | |
| 244 // Can set again after terminate. | |
| 245 cm_->Terminate(); | |
| 246 EXPECT_TRUE(cm_->SetVideoRtxEnabled(true)); | |
| 247 cm_->GetSupportedVideoCodecs(&codecs); | |
| 248 EXPECT_TRUE(ContainsMatchingCodec(codecs, rtx_codec)); | |
| 249 } | |
| 250 | |
| 251 } // namespace cricket | |
| OLD | NEW |