| /* | 
 |  *  Copyright 2008 The WebRTC project authors. All Rights Reserved. | 
 |  * | 
 |  *  Use of this source code is governed by a BSD-style license | 
 |  *  that can be found in the LICENSE file in the root of the source | 
 |  *  tree. An additional intellectual property rights grant can be found | 
 |  *  in the file PATENTS.  All contributing project authors may | 
 |  *  be found in the AUTHORS file in the root of the source tree. | 
 |  */ | 
 |  | 
 | #include "webrtc/api/fakemediacontroller.h" | 
 | #include "webrtc/base/gunit.h" | 
 | #include "webrtc/base/logging.h" | 
 | #include "webrtc/base/thread.h" | 
 | #include "webrtc/media/base/fakemediaengine.h" | 
 | #include "webrtc/media/base/fakevideocapturer.h" | 
 | #include "webrtc/media/base/testutils.h" | 
 | #include "webrtc/media/engine/fakewebrtccall.h" | 
 | #include "webrtc/p2p/base/faketransportcontroller.h" | 
 | #include "webrtc/pc/channelmanager.h" | 
 |  | 
 | namespace cricket { | 
 |  | 
 | static const AudioCodec kAudioCodecs[] = { | 
 |     AudioCodec(97, "voice", 1, 2, 3), AudioCodec(111, "OPUS", 48000, 32000, 2), | 
 | }; | 
 |  | 
 | static const VideoCodec kVideoCodecs[] = { | 
 |     VideoCodec(99, "H264", 100, 200, 300), | 
 |     VideoCodec(100, "VP8", 100, 200, 300), VideoCodec(96, "rtx", 100, 200, 300), | 
 | }; | 
 |  | 
 | class ChannelManagerTest : public testing::Test { | 
 |  protected: | 
 |   ChannelManagerTest() | 
 |       : fme_(new cricket::FakeMediaEngine()), | 
 |         fdme_(new cricket::FakeDataEngine()), | 
 |         cm_(new cricket::ChannelManager(fme_, | 
 |                                         fdme_, | 
 |                                         rtc::Thread::Current())), | 
 |         fake_call_(webrtc::Call::Config()), | 
 |         fake_mc_(cm_, &fake_call_), | 
 |         transport_controller_( | 
 |             new cricket::FakeTransportController(ICEROLE_CONTROLLING)) {} | 
 |  | 
 |   virtual void SetUp() { | 
 |     fme_->SetAudioCodecs(MAKE_VECTOR(kAudioCodecs)); | 
 |     fme_->SetVideoCodecs(MAKE_VECTOR(kVideoCodecs)); | 
 |   } | 
 |  | 
 |   virtual void TearDown() { | 
 |     delete transport_controller_; | 
 |     delete cm_; | 
 |     cm_ = NULL; | 
 |     fdme_ = NULL; | 
 |     fme_ = NULL; | 
 |   } | 
 |  | 
 |   rtc::Thread network_; | 
 |   rtc::Thread worker_; | 
 |   cricket::FakeMediaEngine* fme_; | 
 |   cricket::FakeDataEngine* fdme_; | 
 |   cricket::ChannelManager* cm_; | 
 |   cricket::FakeCall fake_call_; | 
 |   cricket::FakeMediaController fake_mc_; | 
 |   cricket::FakeTransportController* transport_controller_; | 
 | }; | 
 |  | 
 | // Test that we startup/shutdown properly. | 
 | TEST_F(ChannelManagerTest, StartupShutdown) { | 
 |   EXPECT_FALSE(cm_->initialized()); | 
 |   EXPECT_EQ(rtc::Thread::Current(), cm_->worker_thread()); | 
 |   EXPECT_TRUE(cm_->Init()); | 
 |   EXPECT_TRUE(cm_->initialized()); | 
 |   cm_->Terminate(); | 
 |   EXPECT_FALSE(cm_->initialized()); | 
 | } | 
 |  | 
 | // Test that we startup/shutdown properly with a worker thread. | 
 | TEST_F(ChannelManagerTest, StartupShutdownOnThread) { | 
 |   network_.Start(); | 
 |   worker_.Start(); | 
 |   EXPECT_FALSE(cm_->initialized()); | 
 |   EXPECT_EQ(rtc::Thread::Current(), cm_->worker_thread()); | 
 |   EXPECT_TRUE(cm_->set_network_thread(&network_)); | 
 |   EXPECT_EQ(&network_, cm_->network_thread()); | 
 |   EXPECT_TRUE(cm_->set_worker_thread(&worker_)); | 
 |   EXPECT_EQ(&worker_, cm_->worker_thread()); | 
 |   EXPECT_TRUE(cm_->Init()); | 
 |   EXPECT_TRUE(cm_->initialized()); | 
 |   // Setting the network or worker thread while initialized should fail. | 
 |   EXPECT_FALSE(cm_->set_network_thread(rtc::Thread::Current())); | 
 |   EXPECT_FALSE(cm_->set_worker_thread(rtc::Thread::Current())); | 
 |   cm_->Terminate(); | 
 |   EXPECT_FALSE(cm_->initialized()); | 
 | } | 
 |  | 
 | // Test that we can create and destroy a voice and video channel. | 
 | TEST_F(ChannelManagerTest, CreateDestroyChannels) { | 
 |   EXPECT_TRUE(cm_->Init()); | 
 |   cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel( | 
 |       &fake_mc_, transport_controller_, cricket::CN_AUDIO, nullptr, false, | 
 |       AudioOptions()); | 
 |   EXPECT_TRUE(voice_channel != nullptr); | 
 |   cricket::VideoChannel* video_channel = cm_->CreateVideoChannel( | 
 |       &fake_mc_, transport_controller_, cricket::CN_VIDEO, nullptr, false, | 
 |       VideoOptions()); | 
 |   EXPECT_TRUE(video_channel != nullptr); | 
 |   cricket::DataChannel* data_channel = | 
 |       cm_->CreateDataChannel(transport_controller_, cricket::CN_DATA, nullptr, | 
 |                              false, cricket::DCT_RTP); | 
 |   EXPECT_TRUE(data_channel != nullptr); | 
 |   cm_->DestroyVideoChannel(video_channel); | 
 |   cm_->DestroyVoiceChannel(voice_channel); | 
 |   cm_->DestroyDataChannel(data_channel); | 
 |   cm_->Terminate(); | 
 | } | 
 |  | 
 | // Test that we can create and destroy a voice and video channel with a worker. | 
 | TEST_F(ChannelManagerTest, CreateDestroyChannelsOnThread) { | 
 |   network_.Start(); | 
 |   worker_.Start(); | 
 |   EXPECT_TRUE(cm_->set_worker_thread(&worker_)); | 
 |   EXPECT_TRUE(cm_->set_network_thread(&network_)); | 
 |   EXPECT_TRUE(cm_->Init()); | 
 |   delete transport_controller_; | 
 |   transport_controller_ = | 
 |       new cricket::FakeTransportController(&network_, ICEROLE_CONTROLLING); | 
 |   cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel( | 
 |       &fake_mc_, transport_controller_, cricket::CN_AUDIO, nullptr, false, | 
 |       AudioOptions()); | 
 |   EXPECT_TRUE(voice_channel != nullptr); | 
 |   cricket::VideoChannel* video_channel = cm_->CreateVideoChannel( | 
 |       &fake_mc_, transport_controller_, cricket::CN_VIDEO, nullptr, false, | 
 |       VideoOptions()); | 
 |   EXPECT_TRUE(video_channel != nullptr); | 
 |   cricket::DataChannel* data_channel = | 
 |       cm_->CreateDataChannel(transport_controller_, cricket::CN_DATA, nullptr, | 
 |                              false, cricket::DCT_RTP); | 
 |   EXPECT_TRUE(data_channel != nullptr); | 
 |   cm_->DestroyVideoChannel(video_channel); | 
 |   cm_->DestroyVoiceChannel(voice_channel); | 
 |   cm_->DestroyDataChannel(data_channel); | 
 |   cm_->Terminate(); | 
 | } | 
 |  | 
 | // Test that we fail to create a voice/video channel if the session is unable | 
 | // to create a cricket::TransportChannel | 
 | TEST_F(ChannelManagerTest, NoTransportChannelTest) { | 
 |   EXPECT_TRUE(cm_->Init()); | 
 |   transport_controller_->set_fail_channel_creation(true); | 
 |   // The test is useless unless the session does not fail creating | 
 |   // cricket::TransportChannel. | 
 |   ASSERT_TRUE(transport_controller_->CreateTransportChannel_n( | 
 |                   "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP) == nullptr); | 
 |  | 
 |   cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel( | 
 |       &fake_mc_, transport_controller_, cricket::CN_AUDIO, nullptr, false, | 
 |       AudioOptions()); | 
 |   EXPECT_TRUE(voice_channel == nullptr); | 
 |   cricket::VideoChannel* video_channel = cm_->CreateVideoChannel( | 
 |       &fake_mc_, transport_controller_, cricket::CN_VIDEO, nullptr, false, | 
 |       VideoOptions()); | 
 |   EXPECT_TRUE(video_channel == nullptr); | 
 |   cricket::DataChannel* data_channel = | 
 |       cm_->CreateDataChannel(transport_controller_, cricket::CN_DATA, nullptr, | 
 |                              false, cricket::DCT_RTP); | 
 |   EXPECT_TRUE(data_channel == nullptr); | 
 |   cm_->Terminate(); | 
 | } | 
 |  | 
 | TEST_F(ChannelManagerTest, SetVideoRtxEnabled) { | 
 |   std::vector<VideoCodec> codecs; | 
 |   const VideoCodec rtx_codec(96, "rtx", 0, 0, 0); | 
 |  | 
 |   // By default RTX is disabled. | 
 |   cm_->GetSupportedVideoCodecs(&codecs); | 
 |   EXPECT_FALSE(ContainsMatchingCodec(codecs, rtx_codec)); | 
 |  | 
 |   // Enable and check. | 
 |   EXPECT_TRUE(cm_->SetVideoRtxEnabled(true)); | 
 |   cm_->GetSupportedVideoCodecs(&codecs); | 
 |   EXPECT_TRUE(ContainsMatchingCodec(codecs, rtx_codec)); | 
 |  | 
 |   // Disable and check. | 
 |   EXPECT_TRUE(cm_->SetVideoRtxEnabled(false)); | 
 |   cm_->GetSupportedVideoCodecs(&codecs); | 
 |   EXPECT_FALSE(ContainsMatchingCodec(codecs, rtx_codec)); | 
 |  | 
 |   // Cannot toggle rtx after initialization. | 
 |   EXPECT_TRUE(cm_->Init()); | 
 |   EXPECT_FALSE(cm_->SetVideoRtxEnabled(true)); | 
 |   EXPECT_FALSE(cm_->SetVideoRtxEnabled(false)); | 
 |  | 
 |   // Can set again after terminate. | 
 |   cm_->Terminate(); | 
 |   EXPECT_TRUE(cm_->SetVideoRtxEnabled(true)); | 
 |   cm_->GetSupportedVideoCodecs(&codecs); | 
 |   EXPECT_TRUE(ContainsMatchingCodec(codecs, rtx_codec)); | 
 | } | 
 |  | 
 | }  // namespace cricket |