Home | History | Annotate | Download | only in media
      1 // libjingle
      2 // Copyright 2008 Google Inc.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //  1. Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //  2. Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //  3. The name of the author may not be used to endorse or promote products
     13 //     derived from this software without specific prior written permission.
     14 //
     15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25 
     26 #include "talk/base/gunit.h"
     27 #include "talk/base/logging.h"
     28 #include "talk/base/thread.h"
     29 #include "talk/media/base/fakecapturemanager.h"
     30 #include "talk/media/base/fakemediaengine.h"
     31 #include "talk/media/base/fakemediaprocessor.h"
     32 #include "talk/media/base/nullvideorenderer.h"
     33 #include "talk/media/devices/fakedevicemanager.h"
     34 #include "talk/media/base/testutils.h"
     35 #include "talk/p2p/base/fakesession.h"
     36 #include "talk/session/media/channelmanager.h"
     37 
     38 namespace cricket {
     39 
     40 static const AudioCodec kAudioCodecs[] = {
     41   AudioCodec(97, "voice", 1, 2, 3, 0),
     42   AudioCodec(110, "CELT", 32000, 48000, 2, 0),
     43   AudioCodec(111, "OPUS", 48000, 32000, 2, 0),
     44 };
     45 
     46 static const VideoCodec kVideoCodecs[] = {
     47   VideoCodec(99, "H264", 100, 200, 300, 0),
     48   VideoCodec(100, "VP8", 100, 200, 300, 0),
     49   VideoCodec(96, "rtx", 100, 200, 300, 0),
     50 };
     51 
     52 class ChannelManagerTest : public testing::Test {
     53  protected:
     54   ChannelManagerTest() : fme_(NULL), fdm_(NULL), fcm_(NULL), cm_(NULL) {
     55   }
     56 
     57   virtual void SetUp() {
     58     fme_ = new cricket::FakeMediaEngine();
     59     fme_->SetAudioCodecs(MAKE_VECTOR(kAudioCodecs));
     60     fme_->SetVideoCodecs(MAKE_VECTOR(kVideoCodecs));
     61     fdme_ = new cricket::FakeDataEngine();
     62     fdm_ = new cricket::FakeDeviceManager();
     63     fcm_ = new cricket::FakeCaptureManager();
     64     cm_ = new cricket::ChannelManager(
     65         fme_, fdme_, fdm_, fcm_, talk_base::Thread::Current());
     66     session_ = new cricket::FakeSession(true);
     67 
     68     std::vector<std::string> in_device_list, out_device_list, vid_device_list;
     69     in_device_list.push_back("audio-in1");
     70     in_device_list.push_back("audio-in2");
     71     out_device_list.push_back("audio-out1");
     72     out_device_list.push_back("audio-out2");
     73     vid_device_list.push_back("video-in1");
     74     vid_device_list.push_back("video-in2");
     75     fdm_->SetAudioInputDevices(in_device_list);
     76     fdm_->SetAudioOutputDevices(out_device_list);
     77     fdm_->SetVideoCaptureDevices(vid_device_list);
     78   }
     79 
     80   virtual void TearDown() {
     81     delete session_;
     82     delete cm_;
     83     cm_ = NULL;
     84     fdm_ = NULL;
     85     fcm_ = NULL;
     86     fdme_ = NULL;
     87     fme_ = NULL;
     88   }
     89 
     90   talk_base::Thread worker_;
     91   cricket::FakeMediaEngine* fme_;
     92   cricket::FakeDataEngine* fdme_;
     93   cricket::FakeDeviceManager* fdm_;
     94   cricket::FakeCaptureManager* fcm_;
     95   cricket::ChannelManager* cm_;
     96   cricket::FakeSession* session_;
     97 };
     98 
     99 // Test that we startup/shutdown properly.
    100 TEST_F(ChannelManagerTest, StartupShutdown) {
    101   EXPECT_FALSE(cm_->initialized());
    102   EXPECT_EQ(talk_base::Thread::Current(), cm_->worker_thread());
    103   EXPECT_TRUE(cm_->Init());
    104   EXPECT_TRUE(cm_->initialized());
    105   cm_->Terminate();
    106   EXPECT_FALSE(cm_->initialized());
    107 }
    108 
    109 // Test that we startup/shutdown properly with a worker thread.
    110 TEST_F(ChannelManagerTest, StartupShutdownOnThread) {
    111   worker_.Start();
    112   EXPECT_FALSE(cm_->initialized());
    113   EXPECT_EQ(talk_base::Thread::Current(), cm_->worker_thread());
    114   EXPECT_TRUE(cm_->set_worker_thread(&worker_));
    115   EXPECT_EQ(&worker_, cm_->worker_thread());
    116   EXPECT_TRUE(cm_->Init());
    117   EXPECT_TRUE(cm_->initialized());
    118   // Setting the worker thread while initialized should fail.
    119   EXPECT_FALSE(cm_->set_worker_thread(talk_base::Thread::Current()));
    120   cm_->Terminate();
    121   EXPECT_FALSE(cm_->initialized());
    122 }
    123 
    124 // Test that we fail to startup if we're given an unstarted thread.
    125 TEST_F(ChannelManagerTest, StartupShutdownOnUnstartedThread) {
    126   EXPECT_TRUE(cm_->set_worker_thread(&worker_));
    127   EXPECT_FALSE(cm_->Init());
    128   EXPECT_FALSE(cm_->initialized());
    129 }
    130 
    131 // Test that we can create and destroy a voice and video channel.
    132 TEST_F(ChannelManagerTest, CreateDestroyChannels) {
    133   EXPECT_TRUE(cm_->Init());
    134   cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
    135       session_, cricket::CN_AUDIO, false);
    136   EXPECT_TRUE(voice_channel != NULL);
    137   cricket::VideoChannel* video_channel =
    138       cm_->CreateVideoChannel(session_, cricket::CN_VIDEO,
    139                               false, voice_channel);
    140   EXPECT_TRUE(video_channel != NULL);
    141   cricket::DataChannel* data_channel =
    142       cm_->CreateDataChannel(session_, cricket::CN_DATA,
    143                              false, cricket::DCT_RTP);
    144   EXPECT_TRUE(data_channel != NULL);
    145   cm_->DestroyVideoChannel(video_channel);
    146   cm_->DestroyVoiceChannel(voice_channel);
    147   cm_->DestroyDataChannel(data_channel);
    148   cm_->Terminate();
    149 }
    150 
    151 // Test that we can create and destroy a voice and video channel with a worker.
    152 TEST_F(ChannelManagerTest, CreateDestroyChannelsOnThread) {
    153   worker_.Start();
    154   EXPECT_TRUE(cm_->set_worker_thread(&worker_));
    155   EXPECT_TRUE(cm_->Init());
    156   cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
    157       session_, cricket::CN_AUDIO, false);
    158   EXPECT_TRUE(voice_channel != NULL);
    159   cricket::VideoChannel* video_channel =
    160       cm_->CreateVideoChannel(session_, cricket::CN_VIDEO,
    161                               false, voice_channel);
    162   EXPECT_TRUE(video_channel != NULL);
    163   cricket::DataChannel* data_channel =
    164       cm_->CreateDataChannel(session_, cricket::CN_DATA,
    165                              false, cricket::DCT_RTP);
    166   EXPECT_TRUE(data_channel != NULL);
    167   cm_->DestroyVideoChannel(video_channel);
    168   cm_->DestroyVoiceChannel(voice_channel);
    169   cm_->DestroyDataChannel(data_channel);
    170   cm_->Terminate();
    171 }
    172 
    173 // Test that we fail to create a voice/video channel if the session is unable
    174 // to create a cricket::TransportChannel
    175 TEST_F(ChannelManagerTest, NoTransportChannelTest) {
    176   EXPECT_TRUE(cm_->Init());
    177   session_->set_fail_channel_creation(true);
    178   // The test is useless unless the session does not fail creating
    179   // cricket::TransportChannel.
    180   ASSERT_TRUE(session_->CreateChannel(
    181       "audio", "rtp", cricket::ICE_CANDIDATE_COMPONENT_RTP) == NULL);
    182 
    183   cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
    184       session_, cricket::CN_AUDIO, false);
    185   EXPECT_TRUE(voice_channel == NULL);
    186   cricket::VideoChannel* video_channel =
    187       cm_->CreateVideoChannel(session_, cricket::CN_VIDEO,
    188                               false, voice_channel);
    189   EXPECT_TRUE(video_channel == NULL);
    190   cricket::DataChannel* data_channel =
    191       cm_->CreateDataChannel(session_, cricket::CN_DATA,
    192                              false, cricket::DCT_RTP);
    193   EXPECT_TRUE(data_channel == NULL);
    194   cm_->Terminate();
    195 }
    196 
    197 // Test that SetDefaultVideoCodec passes through the right values.
    198 TEST_F(ChannelManagerTest, SetDefaultVideoEncoderConfig) {
    199   cricket::VideoCodec codec(96, "G264", 1280, 720, 60, 0);
    200   cricket::VideoEncoderConfig config(codec, 1, 2);
    201   EXPECT_TRUE(cm_->Init());
    202   EXPECT_TRUE(cm_->SetDefaultVideoEncoderConfig(config));
    203   EXPECT_EQ(config, fme_->default_video_encoder_config());
    204 }
    205 
    206 // Test that SetDefaultVideoCodec passes through the right values.
    207 TEST_F(ChannelManagerTest, SetDefaultVideoCodecBeforeInit) {
    208   cricket::VideoCodec codec(96, "G264", 1280, 720, 60, 0);
    209   cricket::VideoEncoderConfig config(codec, 1, 2);
    210   EXPECT_TRUE(cm_->SetDefaultVideoEncoderConfig(config));
    211   EXPECT_TRUE(cm_->Init());
    212   EXPECT_EQ(config, fme_->default_video_encoder_config());
    213 }
    214 
    215 TEST_F(ChannelManagerTest, SetAudioOptionsBeforeInit) {
    216   // Test that values that we set before Init are applied.
    217   EXPECT_TRUE(cm_->SetAudioOptions("audio-in1", "audio-out1", 0x2));
    218   EXPECT_TRUE(cm_->Init());
    219   EXPECT_EQ("audio-in1", fme_->audio_in_device());
    220   EXPECT_EQ("audio-out1", fme_->audio_out_device());
    221   EXPECT_EQ(0x2, fme_->audio_options());
    222   EXPECT_EQ(0, fme_->audio_delay_offset());
    223   EXPECT_EQ(cricket::MediaEngineInterface::kDefaultAudioDelayOffset,
    224             fme_->audio_delay_offset());
    225 }
    226 
    227 TEST_F(ChannelManagerTest, GetAudioOptionsBeforeInit) {
    228   std::string audio_in, audio_out;
    229   int opts;
    230   // Test that GetAudioOptions works before Init.
    231   EXPECT_TRUE(cm_->SetAudioOptions("audio-in2", "audio-out2", 0x1));
    232   EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, &opts));
    233   EXPECT_EQ("audio-in2", audio_in);
    234   EXPECT_EQ("audio-out2", audio_out);
    235   EXPECT_EQ(0x1, opts);
    236   // Test that options set before Init can be gotten after Init.
    237   EXPECT_TRUE(cm_->SetAudioOptions("audio-in1", "audio-out1", 0x2));
    238   EXPECT_TRUE(cm_->Init());
    239   EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, &opts));
    240   EXPECT_EQ("audio-in1", audio_in);
    241   EXPECT_EQ("audio-out1", audio_out);
    242   EXPECT_EQ(0x2, opts);
    243 }
    244 
    245 TEST_F(ChannelManagerTest, GetAudioOptionsWithNullParameters) {
    246   std::string audio_in, audio_out;
    247   int opts;
    248   EXPECT_TRUE(cm_->SetAudioOptions("audio-in2", "audio-out2", 0x1));
    249   EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, NULL, NULL));
    250   EXPECT_EQ("audio-in2", audio_in);
    251   EXPECT_TRUE(cm_->GetAudioOptions(NULL, &audio_out, NULL));
    252   EXPECT_EQ("audio-out2", audio_out);
    253   EXPECT_TRUE(cm_->GetAudioOptions(NULL, NULL, &opts));
    254   EXPECT_EQ(0x1, opts);
    255 }
    256 
    257 TEST_F(ChannelManagerTest, SetAudioOptions) {
    258   // Test initial state.
    259   EXPECT_TRUE(cm_->Init());
    260   EXPECT_EQ(std::string(cricket::DeviceManagerInterface::kDefaultDeviceName),
    261             fme_->audio_in_device());
    262   EXPECT_EQ(std::string(cricket::DeviceManagerInterface::kDefaultDeviceName),
    263             fme_->audio_out_device());
    264   EXPECT_EQ(cricket::MediaEngineInterface::DEFAULT_AUDIO_OPTIONS,
    265             fme_->audio_options());
    266   EXPECT_EQ(cricket::MediaEngineInterface::kDefaultAudioDelayOffset,
    267             fme_->audio_delay_offset());
    268   // Test setting defaults.
    269   EXPECT_TRUE(cm_->SetAudioOptions("", "",
    270       cricket::MediaEngineInterface::DEFAULT_AUDIO_OPTIONS));
    271   EXPECT_EQ("", fme_->audio_in_device());
    272   EXPECT_EQ("", fme_->audio_out_device());
    273   EXPECT_EQ(cricket::MediaEngineInterface::DEFAULT_AUDIO_OPTIONS,
    274             fme_->audio_options());
    275   EXPECT_EQ(cricket::MediaEngineInterface::kDefaultAudioDelayOffset,
    276             fme_->audio_delay_offset());
    277   // Test setting specific values.
    278   EXPECT_TRUE(cm_->SetAudioOptions("audio-in1", "audio-out1", 0x2));
    279   EXPECT_EQ("audio-in1", fme_->audio_in_device());
    280   EXPECT_EQ("audio-out1", fme_->audio_out_device());
    281   EXPECT_EQ(0x2, fme_->audio_options());
    282   EXPECT_EQ(cricket::MediaEngineInterface::kDefaultAudioDelayOffset,
    283             fme_->audio_delay_offset());
    284   // Test setting bad values.
    285   EXPECT_FALSE(cm_->SetAudioOptions("audio-in9", "audio-out2", 0x1));
    286 }
    287 
    288 TEST_F(ChannelManagerTest, GetAudioOptions) {
    289   std::string audio_in, audio_out;
    290   int opts;
    291   // Test initial state.
    292   EXPECT_TRUE(cm_->Init());
    293   EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, &opts));
    294   EXPECT_EQ(std::string(cricket::DeviceManagerInterface::kDefaultDeviceName),
    295             audio_in);
    296   EXPECT_EQ(std::string(cricket::DeviceManagerInterface::kDefaultDeviceName),
    297             audio_out);
    298   EXPECT_EQ(cricket::MediaEngineInterface::DEFAULT_AUDIO_OPTIONS, opts);
    299   // Test that we get back specific values that we set.
    300   EXPECT_TRUE(cm_->SetAudioOptions("audio-in1", "audio-out1", 0x2));
    301   EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, &opts));
    302   EXPECT_EQ("audio-in1", audio_in);
    303   EXPECT_EQ("audio-out1", audio_out);
    304   EXPECT_EQ(0x2, opts);
    305 }
    306 
    307 TEST_F(ChannelManagerTest, SetCaptureDeviceBeforeInit) {
    308   // Test that values that we set before Init are applied.
    309   EXPECT_TRUE(cm_->SetCaptureDevice("video-in2"));
    310   EXPECT_TRUE(cm_->Init());
    311   EXPECT_EQ("video-in2", cm_->video_device_name());
    312 }
    313 
    314 TEST_F(ChannelManagerTest, GetCaptureDeviceBeforeInit) {
    315   std::string video_in;
    316   // Test that GetCaptureDevice works before Init.
    317   EXPECT_TRUE(cm_->SetCaptureDevice("video-in1"));
    318   EXPECT_TRUE(cm_->GetCaptureDevice(&video_in));
    319   EXPECT_EQ("video-in1", video_in);
    320   // Test that options set before Init can be gotten after Init.
    321   EXPECT_TRUE(cm_->SetCaptureDevice("video-in2"));
    322   EXPECT_TRUE(cm_->Init());
    323   EXPECT_TRUE(cm_->GetCaptureDevice(&video_in));
    324   EXPECT_EQ("video-in2", video_in);
    325 }
    326 
    327 TEST_F(ChannelManagerTest, SetCaptureDevice) {
    328   // Test setting defaults.
    329   EXPECT_TRUE(cm_->Init());
    330   EXPECT_TRUE(cm_->SetCaptureDevice(""));  // will use DeviceManager default
    331   EXPECT_EQ("video-in1", cm_->video_device_name());
    332   // Test setting specific values.
    333   EXPECT_TRUE(cm_->SetCaptureDevice("video-in2"));
    334   EXPECT_EQ("video-in2", cm_->video_device_name());
    335   // TODO(juberti): Add test for invalid value here.
    336 }
    337 
    338 // Test unplugging and plugging back the preferred devices. When the preferred
    339 // device is unplugged, we fall back to the default device. When the preferred
    340 // device is plugged back, we use it.
    341 TEST_F(ChannelManagerTest, SetAudioOptionsUnplugPlug) {
    342   // Set preferences "audio-in1" and "audio-out1" before init.
    343   EXPECT_TRUE(cm_->SetAudioOptions("audio-in1", "audio-out1", 0x2));
    344   // Unplug device "audio-in1" and "audio-out1".
    345   std::vector<std::string> in_device_list, out_device_list;
    346   in_device_list.push_back("audio-in2");
    347   out_device_list.push_back("audio-out2");
    348   fdm_->SetAudioInputDevices(in_device_list);
    349   fdm_->SetAudioOutputDevices(out_device_list);
    350   // Init should fall back to default devices.
    351   EXPECT_TRUE(cm_->Init());
    352   // The media engine should use the default.
    353   EXPECT_EQ("", fme_->audio_in_device());
    354   EXPECT_EQ("", fme_->audio_out_device());
    355   // The channel manager keeps the preferences "audio-in1" and "audio-out1".
    356   std::string audio_in, audio_out;
    357   EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, NULL));
    358   EXPECT_EQ("audio-in1", audio_in);
    359   EXPECT_EQ("audio-out1", audio_out);
    360   cm_->Terminate();
    361 
    362   // Plug devices "audio-in2" and "audio-out2" back.
    363   in_device_list.push_back("audio-in1");
    364   out_device_list.push_back("audio-out1");
    365   fdm_->SetAudioInputDevices(in_device_list);
    366   fdm_->SetAudioOutputDevices(out_device_list);
    367   // Init again. The preferences, "audio-in2" and "audio-out2", are used.
    368   EXPECT_TRUE(cm_->Init());
    369   EXPECT_EQ("audio-in1", fme_->audio_in_device());
    370   EXPECT_EQ("audio-out1", fme_->audio_out_device());
    371   EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, NULL));
    372   EXPECT_EQ("audio-in1", audio_in);
    373   EXPECT_EQ("audio-out1", audio_out);
    374 }
    375 
    376 // We have one camera. Unplug it, fall back to no camera.
    377 TEST_F(ChannelManagerTest, SetCaptureDeviceUnplugPlugOneCamera) {
    378   // Set preferences "video-in1" before init.
    379   std::vector<std::string> vid_device_list;
    380   vid_device_list.push_back("video-in1");
    381   fdm_->SetVideoCaptureDevices(vid_device_list);
    382   EXPECT_TRUE(cm_->SetCaptureDevice("video-in1"));
    383 
    384   // Unplug "video-in1".
    385   vid_device_list.clear();
    386   fdm_->SetVideoCaptureDevices(vid_device_list);
    387 
    388   // Init should fall back to avatar.
    389   EXPECT_TRUE(cm_->Init());
    390   // The media engine should use no camera.
    391   EXPECT_EQ("", cm_->video_device_name());
    392   // The channel manager keeps the user preference "video-in".
    393   std::string video_in;
    394   EXPECT_TRUE(cm_->GetCaptureDevice(&video_in));
    395   EXPECT_EQ("video-in1", video_in);
    396   cm_->Terminate();
    397 
    398   // Plug device "video-in1" back.
    399   vid_device_list.push_back("video-in1");
    400   fdm_->SetVideoCaptureDevices(vid_device_list);
    401   // Init again. The user preferred device, "video-in1", is used.
    402   EXPECT_TRUE(cm_->Init());
    403   EXPECT_EQ("video-in1", cm_->video_device_name());
    404   EXPECT_TRUE(cm_->GetCaptureDevice(&video_in));
    405   EXPECT_EQ("video-in1", video_in);
    406 }
    407 
    408 // We have multiple cameras. Unplug the preferred, fall back to another camera.
    409 TEST_F(ChannelManagerTest, SetCaptureDeviceUnplugPlugTwoDevices) {
    410   // Set video device to "video-in1" before init.
    411   EXPECT_TRUE(cm_->SetCaptureDevice("video-in1"));
    412   // Unplug device "video-in1".
    413   std::vector<std::string> vid_device_list;
    414   vid_device_list.push_back("video-in2");
    415   fdm_->SetVideoCaptureDevices(vid_device_list);
    416   // Init should fall back to default device "video-in2".
    417   EXPECT_TRUE(cm_->Init());
    418   // The media engine should use the default device "video-in2".
    419   EXPECT_EQ("video-in2", cm_->video_device_name());
    420   // The channel manager keeps the user preference "video-in".
    421   std::string video_in;
    422   EXPECT_TRUE(cm_->GetCaptureDevice(&video_in));
    423   EXPECT_EQ("video-in1", video_in);
    424   cm_->Terminate();
    425 
    426   // Plug device "video-in1" back.
    427   vid_device_list.push_back("video-in1");
    428   fdm_->SetVideoCaptureDevices(vid_device_list);
    429   // Init again. The user preferred device, "video-in1", is used.
    430   EXPECT_TRUE(cm_->Init());
    431   EXPECT_EQ("video-in1", cm_->video_device_name());
    432   EXPECT_TRUE(cm_->GetCaptureDevice(&video_in));
    433   EXPECT_EQ("video-in1", video_in);
    434 }
    435 
    436 TEST_F(ChannelManagerTest, GetCaptureDevice) {
    437   std::string video_in;
    438   // Test setting/getting defaults.
    439   EXPECT_TRUE(cm_->Init());
    440   EXPECT_TRUE(cm_->SetCaptureDevice(""));
    441   EXPECT_TRUE(cm_->GetCaptureDevice(&video_in));
    442   EXPECT_EQ("video-in1", video_in);
    443   // Test setting/getting specific values.
    444   EXPECT_TRUE(cm_->SetCaptureDevice("video-in2"));
    445   EXPECT_TRUE(cm_->GetCaptureDevice(&video_in));
    446   EXPECT_EQ("video-in2", video_in);
    447 }
    448 
    449 TEST_F(ChannelManagerTest, GetSetOutputVolumeBeforeInit) {
    450   int level;
    451   // Before init, SetOutputVolume() remembers the volume but does not change the
    452   // volume of the engine. GetOutputVolume() should fail.
    453   EXPECT_EQ(-1, fme_->output_volume());
    454   EXPECT_FALSE(cm_->GetOutputVolume(&level));
    455   EXPECT_FALSE(cm_->SetOutputVolume(-1));  // Invalid volume.
    456   EXPECT_TRUE(cm_->SetOutputVolume(99));
    457   EXPECT_EQ(-1, fme_->output_volume());
    458 
    459   // Init() will apply the remembered volume.
    460   EXPECT_TRUE(cm_->Init());
    461   EXPECT_TRUE(cm_->GetOutputVolume(&level));
    462   EXPECT_EQ(99, level);
    463   EXPECT_EQ(level, fme_->output_volume());
    464 
    465   EXPECT_TRUE(cm_->SetOutputVolume(60));
    466   EXPECT_TRUE(cm_->GetOutputVolume(&level));
    467   EXPECT_EQ(60, level);
    468   EXPECT_EQ(level, fme_->output_volume());
    469 }
    470 
    471 TEST_F(ChannelManagerTest, GetSetOutputVolume) {
    472   int level;
    473   EXPECT_TRUE(cm_->Init());
    474   EXPECT_TRUE(cm_->GetOutputVolume(&level));
    475   EXPECT_EQ(level, fme_->output_volume());
    476 
    477   EXPECT_FALSE(cm_->SetOutputVolume(-1));  // Invalid volume.
    478   EXPECT_TRUE(cm_->SetOutputVolume(60));
    479   EXPECT_EQ(60, fme_->output_volume());
    480   EXPECT_TRUE(cm_->GetOutputVolume(&level));
    481   EXPECT_EQ(60, level);
    482 }
    483 
    484 // Test that a value set before Init is applied properly.
    485 TEST_F(ChannelManagerTest, SetLocalRendererBeforeInit) {
    486   cricket::NullVideoRenderer renderer;
    487   EXPECT_TRUE(cm_->SetLocalRenderer(&renderer));
    488   EXPECT_TRUE(cm_->Init());
    489   EXPECT_EQ(&renderer, fme_->local_renderer());
    490 }
    491 
    492 // Test that a value set after init is passed through properly.
    493 TEST_F(ChannelManagerTest, SetLocalRenderer) {
    494   cricket::NullVideoRenderer renderer;
    495   EXPECT_TRUE(cm_->Init());
    496   EXPECT_TRUE(cm_->SetLocalRenderer(&renderer));
    497   EXPECT_EQ(&renderer, fme_->local_renderer());
    498 }
    499 
    500 // Test that logging options set before Init are applied properly,
    501 // and retained even after Init.
    502 TEST_F(ChannelManagerTest, SetLoggingBeforeInit) {
    503   cm_->SetVoiceLogging(talk_base::LS_INFO, "test-voice");
    504   cm_->SetVideoLogging(talk_base::LS_VERBOSE, "test-video");
    505   EXPECT_EQ(talk_base::LS_INFO, fme_->voice_loglevel());
    506   EXPECT_STREQ("test-voice", fme_->voice_logfilter().c_str());
    507   EXPECT_EQ(talk_base::LS_VERBOSE, fme_->video_loglevel());
    508   EXPECT_STREQ("test-video", fme_->video_logfilter().c_str());
    509   EXPECT_TRUE(cm_->Init());
    510   EXPECT_EQ(talk_base::LS_INFO, fme_->voice_loglevel());
    511   EXPECT_STREQ("test-voice", fme_->voice_logfilter().c_str());
    512   EXPECT_EQ(talk_base::LS_VERBOSE, fme_->video_loglevel());
    513   EXPECT_STREQ("test-video", fme_->video_logfilter().c_str());
    514 }
    515 
    516 // Test that logging options set after Init are applied properly.
    517 TEST_F(ChannelManagerTest, SetLogging) {
    518   EXPECT_TRUE(cm_->Init());
    519   cm_->SetVoiceLogging(talk_base::LS_INFO, "test-voice");
    520   cm_->SetVideoLogging(talk_base::LS_VERBOSE, "test-video");
    521   EXPECT_EQ(talk_base::LS_INFO, fme_->voice_loglevel());
    522   EXPECT_STREQ("test-voice", fme_->voice_logfilter().c_str());
    523   EXPECT_EQ(talk_base::LS_VERBOSE, fme_->video_loglevel());
    524   EXPECT_STREQ("test-video", fme_->video_logfilter().c_str());
    525 }
    526 
    527 // Test that the Video/Voice Processors register and unregister
    528 TEST_F(ChannelManagerTest, RegisterProcessors) {
    529   cricket::FakeMediaProcessor fmp;
    530   EXPECT_TRUE(cm_->Init());
    531   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
    532   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
    533 
    534   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
    535   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
    536 
    537   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
    538   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
    539 
    540   EXPECT_TRUE(cm_->RegisterVoiceProcessor(1,
    541                                           &fmp,
    542                                           cricket::MPD_RX));
    543   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
    544   EXPECT_TRUE(fme_->voice_processor_registered(cricket::MPD_RX));
    545 
    546 
    547   EXPECT_TRUE(cm_->UnregisterVoiceProcessor(1,
    548                                             &fmp,
    549                                             cricket::MPD_RX));
    550   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
    551   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
    552 
    553   EXPECT_TRUE(cm_->RegisterVoiceProcessor(1,
    554                                           &fmp,
    555                                           cricket::MPD_TX));
    556   EXPECT_TRUE(fme_->voice_processor_registered(cricket::MPD_TX));
    557   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
    558 
    559   EXPECT_TRUE(cm_->UnregisterVoiceProcessor(1,
    560                                             &fmp,
    561                                             cricket::MPD_TX));
    562   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
    563   EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
    564 }
    565 
    566 TEST_F(ChannelManagerTest, SetVideoRtxEnabled) {
    567   std::vector<VideoCodec> codecs;
    568   const VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
    569 
    570   // By default RTX is disabled.
    571   cm_->GetSupportedVideoCodecs(&codecs);
    572   EXPECT_FALSE(ContainsMatchingCodec(codecs, rtx_codec));
    573 
    574   // Enable and check.
    575   EXPECT_TRUE(cm_->SetVideoRtxEnabled(true));
    576   cm_->GetSupportedVideoCodecs(&codecs);
    577   EXPECT_TRUE(ContainsMatchingCodec(codecs, rtx_codec));
    578 
    579   // Disable and check.
    580   EXPECT_TRUE(cm_->SetVideoRtxEnabled(false));
    581   cm_->GetSupportedVideoCodecs(&codecs);
    582   EXPECT_FALSE(ContainsMatchingCodec(codecs, rtx_codec));
    583 
    584   // Cannot toggle rtx after initialization.
    585   EXPECT_TRUE(cm_->Init());
    586   EXPECT_FALSE(cm_->SetVideoRtxEnabled(true));
    587   EXPECT_FALSE(cm_->SetVideoRtxEnabled(false));
    588 
    589   // Can set again after terminate.
    590   cm_->Terminate();
    591   EXPECT_TRUE(cm_->SetVideoRtxEnabled(true));
    592   cm_->GetSupportedVideoCodecs(&codecs);
    593   EXPECT_TRUE(ContainsMatchingCodec(codecs, rtx_codec));
    594 }
    595 
    596 }  // namespace cricket
    597