1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <string> 6 7#include "base/bind.h" 8#include "base/command_line.h" 9#include "base/message_loop/message_loop.h" 10#include "base/run_loop.h" 11#include "content/browser/browser_thread_impl.h" 12#include "content/browser/renderer_host/media/media_stream_manager.h" 13#include "content/browser/renderer_host/media/media_stream_ui_proxy.h" 14#include "content/common/media/media_stream_options.h" 15#include "content/public/common/content_switches.h" 16#include "content/public/test/test_browser_thread_bundle.h" 17#include "media/audio/audio_manager_base.h" 18#include "media/audio/fake_audio_log_factory.h" 19#include "media/base/media_switches.h" 20#include "testing/gmock/include/gmock/gmock.h" 21#include "testing/gtest/include/gtest/gtest.h" 22 23#if defined(USE_ALSA) 24#include "media/audio/alsa/audio_manager_alsa.h" 25#elif defined(OS_ANDROID) 26#include "media/audio/android/audio_manager_android.h" 27#elif defined(OS_MACOSX) 28#include "media/audio/mac/audio_manager_mac.h" 29#elif defined(OS_WIN) 30#include "media/audio/win/audio_manager_win.h" 31#else 32#include "media/audio/fake_audio_manager.h" 33#endif 34 35using testing::_; 36 37namespace content { 38 39#if defined(USE_ALSA) 40typedef media::AudioManagerAlsa AudioManagerPlatform; 41#elif defined(OS_MACOSX) 42typedef media::AudioManagerMac AudioManagerPlatform; 43#elif defined(OS_WIN) 44typedef media::AudioManagerWin AudioManagerPlatform; 45#elif defined(OS_ANDROID) 46typedef media::AudioManagerAndroid AudioManagerPlatform; 47#else 48typedef media::FakeAudioManager AudioManagerPlatform; 49#endif 50 51 52// This class mocks the audio manager and overrides the 53// GetAudioInputDeviceNames() method to ensure that we can run our tests on 54// the buildbots. media::AudioManagerBase 55class MockAudioManager : public AudioManagerPlatform { 56 public: 57 MockAudioManager() : AudioManagerPlatform(&fake_audio_log_factory_) {} 58 virtual ~MockAudioManager() {} 59 60 virtual void GetAudioInputDeviceNames( 61 media::AudioDeviceNames* device_names) OVERRIDE { 62 DCHECK(device_names->empty()); 63 if (HasAudioInputDevices()) { 64 AudioManagerBase::GetAudioInputDeviceNames(device_names); 65 } else { 66 device_names->push_back(media::AudioDeviceName("fake_device_name", 67 "fake_device_id")); 68 } 69 } 70 71 private: 72 media::FakeAudioLogFactory fake_audio_log_factory_; 73 DISALLOW_COPY_AND_ASSIGN(MockAudioManager); 74}; 75 76class MediaStreamManagerTest : public ::testing::Test { 77 public: 78 MediaStreamManagerTest() 79 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 80 message_loop_(base::MessageLoopProxy::current()) { 81 // Create our own MediaStreamManager. Use fake devices to run on the bots. 82 base::CommandLine::ForCurrentProcess()->AppendSwitch( 83 switches::kUseFakeDeviceForMediaStream); 84 audio_manager_.reset(new MockAudioManager()); 85 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); 86} 87 88 virtual ~MediaStreamManagerTest() { 89 } 90 91 MOCK_METHOD1(Response, void(int index)); 92 void ResponseCallback(int index, 93 const MediaStreamDevices& devices, 94 scoped_ptr<MediaStreamUIProxy> ui_proxy) { 95 Response(index); 96 message_loop_->PostTask(FROM_HERE, run_loop_.QuitClosure()); 97 } 98 99 protected: 100 std::string MakeMediaAccessRequest(int index) { 101 const int render_process_id = 1; 102 const int render_frame_id = 1; 103 const int page_request_id = 1; 104 const GURL security_origin; 105 MediaStreamManager::MediaRequestResponseCallback callback = 106 base::Bind(&MediaStreamManagerTest::ResponseCallback, 107 base::Unretained(this), index); 108 StreamOptions options(true, true); 109 return media_stream_manager_->MakeMediaAccessRequest(render_process_id, 110 render_frame_id, 111 page_request_id, 112 options, 113 security_origin, 114 callback); 115 } 116 117 scoped_ptr<media::AudioManager> audio_manager_; 118 scoped_ptr<MediaStreamManager> media_stream_manager_; 119 content::TestBrowserThreadBundle thread_bundle_; 120 scoped_refptr<base::MessageLoopProxy> message_loop_; 121 base::RunLoop run_loop_; 122 123 private: 124 DISALLOW_COPY_AND_ASSIGN(MediaStreamManagerTest); 125}; 126 127TEST_F(MediaStreamManagerTest, MakeMediaAccessRequest) { 128 MakeMediaAccessRequest(0); 129 130 // Expecting the callback will be triggered and quit the test. 131 EXPECT_CALL(*this, Response(0)); 132 run_loop_.Run(); 133} 134 135TEST_F(MediaStreamManagerTest, MakeAndCancelMediaAccessRequest) { 136 std::string label = MakeMediaAccessRequest(0); 137 // No callback is expected. 138 media_stream_manager_->CancelRequest(label); 139 run_loop_.RunUntilIdle(); 140 media_stream_manager_->WillDestroyCurrentMessageLoop(); 141} 142 143TEST_F(MediaStreamManagerTest, MakeMultipleRequests) { 144 // First request. 145 std::string label1 = MakeMediaAccessRequest(0); 146 147 // Second request. 148 int render_process_id = 2; 149 int render_frame_id = 2; 150 int page_request_id = 2; 151 GURL security_origin; 152 StreamOptions options(true, true); 153 MediaStreamManager::MediaRequestResponseCallback callback = 154 base::Bind(&MediaStreamManagerTest::ResponseCallback, 155 base::Unretained(this), 1); 156 std::string label2 = media_stream_manager_->MakeMediaAccessRequest( 157 render_process_id, 158 render_frame_id, 159 page_request_id, 160 options, 161 security_origin, 162 callback); 163 164 // Expecting the callbackS from requests will be triggered and quit the test. 165 // Note, the callbacks might come in a different order depending on the 166 // value of labels. 167 EXPECT_CALL(*this, Response(0)); 168 EXPECT_CALL(*this, Response(1)); 169 run_loop_.Run(); 170} 171 172TEST_F(MediaStreamManagerTest, MakeAndCancelMultipleRequests) { 173 std::string label1 = MakeMediaAccessRequest(0); 174 std::string label2 = MakeMediaAccessRequest(1); 175 media_stream_manager_->CancelRequest(label1); 176 177 // Expecting the callback from the second request will be triggered and 178 // quit the test. 179 EXPECT_CALL(*this, Response(1)); 180 run_loop_.Run(); 181} 182 183} // namespace content 184