Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/test/webrtc_audio_device_test.h" | 5 #include "content/test/webrtc_audio_device_test.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 DISALLOW_COPY_AND_ASSIGN(WebRTCMockResourceContext); | 89 DISALLOW_COPY_AND_ASSIGN(WebRTCMockResourceContext); |
| 90 }; | 90 }; |
| 91 | 91 |
| 92 ACTION_P(QuitMessageLoop, loop_or_proxy) { | 92 ACTION_P(QuitMessageLoop, loop_or_proxy) { |
| 93 loop_or_proxy->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 93 loop_or_proxy->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 94 } | 94 } |
| 95 | 95 |
| 96 } // end namespace | 96 } // end namespace |
| 97 | 97 |
| 98 WebRTCAudioDeviceTest::WebRTCAudioDeviceTest() | 98 WebRTCAudioDeviceTest::WebRTCAudioDeviceTest() |
| 99 : render_thread_(NULL), event_(false, false), audio_util_callback_(NULL) { | 99 : render_thread_(NULL), audio_util_callback_(NULL) { |
| 100 } | 100 } |
| 101 | 101 |
| 102 WebRTCAudioDeviceTest::~WebRTCAudioDeviceTest() {} | 102 WebRTCAudioDeviceTest::~WebRTCAudioDeviceTest() {} |
| 103 | 103 |
| 104 void WebRTCAudioDeviceTest::SetUp() { | 104 void WebRTCAudioDeviceTest::SetUp() { |
| 105 // This part sets up a RenderThread environment to ensure that | 105 // This part sets up a RenderThread environment to ensure that |
| 106 // RenderThread::current() (<=> TLS pointer) is valid. | 106 // RenderThread::current() (<=> TLS pointer) is valid. |
| 107 // Main parts are inspired by the RenderViewFakeResourcesTest. | 107 // Main parts are inspired by the RenderViewFakeResourcesTest. |
| 108 // Note that, the IPC part is not utilized in this test. | 108 // Note that, the IPC part is not utilized in this test. |
| 109 saved_content_renderer_.reset( | 109 saved_content_renderer_.reset( |
| 110 new ReplaceContentClientRenderer(&mock_content_renderer_client_)); | 110 new ReplaceContentClientRenderer(&mock_content_renderer_client_)); |
| 111 mock_process_.reset(new WebRTCMockRenderProcess()); | 111 mock_process_.reset(new WebRTCMockRenderProcess()); |
| 112 ui_thread_.reset(new content::TestBrowserThread(content::BrowserThread::UI, | 112 ui_thread_.reset(new content::TestBrowserThread(content::BrowserThread::UI, |
| 113 MessageLoop::current())); | 113 MessageLoop::current())); |
| 114 | 114 |
| 115 // Construct the resource context on the UI thread. | 115 // Construct the resource context on the UI thread. |
| 116 resource_context_.reset(new WebRTCMockResourceContext()); | 116 resource_context_.reset(new WebRTCMockResourceContext()); |
| 117 | 117 |
| 118 static const char kThreadName[] = "RenderThread"; | 118 static const char kThreadName[] = "RenderThread"; |
| 119 ChildProcess::current()->io_message_loop()->PostTask( | 119 ChildProcess::current()->io_message_loop()->PostTask(FROM_HERE, |
| 120 FROM_HERE, | 120 base::Bind(&WebRTCAudioDeviceTest::InitializeIOThread, |
| 121 base::Bind(&SetupTask::InitializeIOThread, new SetupTask(this), | 121 base::Unretained(this), kThreadName)); |
| 122 kThreadName)); | |
| 123 WaitForIOThreadCompletion(); | 122 WaitForIOThreadCompletion(); |
| 124 | 123 |
| 125 render_thread_ = new RenderThreadImpl(kThreadName); | 124 render_thread_ = new RenderThreadImpl(kThreadName); |
| 126 mock_process_->set_main_thread(render_thread_); | 125 mock_process_->set_main_thread(render_thread_); |
| 127 } | 126 } |
| 128 | 127 |
| 129 void WebRTCAudioDeviceTest::TearDown() { | 128 void WebRTCAudioDeviceTest::TearDown() { |
| 130 SetAudioUtilCallback(NULL); | 129 SetAudioUtilCallback(NULL); |
| 131 | 130 |
| 132 ChildProcess::current()->io_message_loop()->PostTask( | 131 // Kick of the cleanup process by closing channel. This queues up |
|
henrika (OOO until Aug 14)
2011/12/07 10:26:43
the
tommi (sloooow) - chröme
2011/12/07 12:26:44
Can you clarify?
henrika (OOO until Aug 14)
2011/12/07 12:48:01
"..by closing *the* channel."
tommi (sloooow) - chröme
2011/12/07 14:46:23
ah. sorry, refrigerator blindness. Done.
| |
| 133 FROM_HERE, | 132 // OnStreamClosed calls to be executed on the audio thread. |
| 134 base::Bind(&SetupTask::UninitializeIOThread, new SetupTask(this))); | 133 ChildProcess::current()->io_message_loop()->PostTask(FROM_HERE, |
| 135 EXPECT_TRUE(event_.TimedWait( | 134 base::Bind(&WebRTCAudioDeviceTest::DestroyChannel, |
| 136 base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms()))); | 135 base::Unretained(this))); |
| 136 WaitForIOThreadCompletion(); | |
| 137 | |
| 138 // When audio [input] render hosts are notified that the channel has | |
| 139 // been closed, they post tasks to the audio thread to close the | |
| 140 // AudioOutputController and once that's completed, a task is posted back to | |
| 141 // the IO thread to actually delete the AudioEntry for the audio stream. Only | |
| 142 // then is the reference to the audio manager released, so we wait for the | |
| 143 // whole thing to be torn down before we finally uninitialize the io thread. | |
| 144 WaitForAudioManagerCompletion(); | |
| 145 | |
| 146 ChildProcess::current()->io_message_loop()->PostTask(FROM_HERE, | |
| 147 base::Bind(&WebRTCAudioDeviceTest::UninitializeIOThread, | |
| 148 base::Unretained((this)))); | |
| 149 WaitForIOThreadCompletion(); | |
| 137 mock_process_.reset(); | 150 mock_process_.reset(); |
| 138 } | 151 } |
| 139 | 152 |
| 140 bool WebRTCAudioDeviceTest::Send(IPC::Message* message) { | 153 bool WebRTCAudioDeviceTest::Send(IPC::Message* message) { |
| 141 return channel_->Send(message); | 154 return channel_->Send(message); |
| 142 } | 155 } |
| 143 | 156 |
| 144 void WebRTCAudioDeviceTest::SetAudioUtilCallback(AudioUtilInterface* callback) { | 157 void WebRTCAudioDeviceTest::SetAudioUtilCallback(AudioUtilInterface* callback) { |
| 145 // Invalidate any potentially cached values since the new callback should | 158 // Invalidate any potentially cached values since the new callback should |
| 146 // be used for those queries. | 159 // be used for those queries. |
| 147 audio_hardware::ResetCache(); | 160 audio_hardware::ResetCache(); |
| 148 audio_util_callback_ = callback; | 161 audio_util_callback_ = callback; |
| 149 } | 162 } |
| 150 | 163 |
| 151 void WebRTCAudioDeviceTest::InitializeIOThread(const char* thread_name) { | 164 void WebRTCAudioDeviceTest::InitializeIOThread(const char* thread_name) { |
| 152 // We initialize COM (STA) on our IO thread as is done in Chrome. | 165 // We initialize COM (STA) on our IO thread as is done in Chrome. |
| 153 // See BrowserProcessSubThread::Init. | 166 // See BrowserProcessSubThread::Init. |
| 154 initialize_com_.reset(new ScopedCOMInitializer()); | 167 initialize_com_.reset(new ScopedCOMInitializer()); |
| 155 | 168 |
| 156 // Set the current thread as the IO thread. | 169 // Set the current thread as the IO thread. |
| 157 io_thread_.reset(new content::TestBrowserThread(content::BrowserThread::IO, | 170 io_thread_.reset(new content::TestBrowserThread(content::BrowserThread::IO, |
| 158 MessageLoop::current())); | 171 MessageLoop::current())); |
| 172 | |
| 173 audio_manager_ = AudioManager::Create(); | |
| 174 | |
| 175 // Populate our resource context. | |
| 159 test_request_context_ = new TestURLRequestContext(); | 176 test_request_context_ = new TestURLRequestContext(); |
| 160 resource_context_->set_request_context(test_request_context_.get()); | 177 resource_context_->set_request_context(test_request_context_.get()); |
| 161 media_observer_.reset(new MockMediaObserver()); | 178 media_observer_.reset(new MockMediaObserver()); |
| 162 resource_context_->set_media_observer(media_observer_.get()); | 179 resource_context_->set_media_observer(media_observer_.get()); |
| 163 media_stream_manager_.reset(new media_stream::MediaStreamManager()); | 180 media_stream_manager_.reset(new media_stream::MediaStreamManager( |
| 181 audio_manager_.get())); | |
| 164 resource_context_->set_media_stream_manager(media_stream_manager_.get()); | 182 resource_context_->set_media_stream_manager(media_stream_manager_.get()); |
| 183 resource_context_->set_audio_manager(audio_manager_.get()); | |
| 165 | 184 |
| 166 CreateChannel(thread_name, resource_context_.get()); | 185 // Create an IPC channel that handles incoming messages on the IO thread. |
| 186 CreateChannel(thread_name); | |
| 167 } | 187 } |
| 168 | 188 |
| 169 void WebRTCAudioDeviceTest::UninitializeIOThread() { | 189 void WebRTCAudioDeviceTest::UninitializeIOThread() { |
| 170 DestroyChannel(); | |
| 171 resource_context_.reset(); | 190 resource_context_.reset(); |
| 172 media_stream_manager_.reset(); | 191 media_stream_manager_.reset(); |
| 192 | |
| 193 EXPECT_TRUE(audio_manager_->HasOneRef()); | |
| 194 audio_manager_ = NULL; | |
| 173 test_request_context_ = NULL; | 195 test_request_context_ = NULL; |
| 174 initialize_com_.reset(); | 196 initialize_com_.reset(); |
| 175 event_.Signal(); | |
| 176 } | 197 } |
| 177 | 198 |
| 178 void WebRTCAudioDeviceTest::CreateChannel( | 199 void WebRTCAudioDeviceTest::CreateChannel(const char* name) { |
| 179 const char* name, | |
| 180 content::ResourceContext* resource_context) { | |
| 181 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 200 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 182 audio_render_host_ = new AudioRendererHost(resource_context); | 201 audio_render_host_ = new AudioRendererHost(resource_context_.get()); |
| 183 audio_render_host_->OnChannelConnected(base::GetCurrentProcId()); | 202 audio_render_host_->OnChannelConnected(base::GetCurrentProcId()); |
| 184 | 203 |
| 185 audio_input_renderer_host_ = new AudioInputRendererHost(resource_context); | 204 audio_input_renderer_host_ = new AudioInputRendererHost( |
| 205 resource_context_.get()); | |
| 186 audio_input_renderer_host_->OnChannelConnected(base::GetCurrentProcId()); | 206 audio_input_renderer_host_->OnChannelConnected(base::GetCurrentProcId()); |
| 187 | 207 |
| 188 channel_.reset(new IPC::Channel(name, IPC::Channel::MODE_SERVER, this)); | 208 channel_.reset(new IPC::Channel(name, IPC::Channel::MODE_SERVER, this)); |
| 189 ASSERT_TRUE(channel_->Connect()); | 209 ASSERT_TRUE(channel_->Connect()); |
| 190 | 210 |
| 191 audio_render_host_->OnFilterAdded(channel_.get()); | 211 audio_render_host_->OnFilterAdded(channel_.get()); |
| 192 audio_input_renderer_host_->OnFilterAdded(channel_.get()); | 212 audio_input_renderer_host_->OnFilterAdded(channel_.get()); |
| 193 } | 213 } |
| 194 | 214 |
| 195 void WebRTCAudioDeviceTest::DestroyChannel() { | 215 void WebRTCAudioDeviceTest::DestroyChannel() { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 250 IPC_MESSAGE_UNHANDLED(handled = false) | 270 IPC_MESSAGE_UNHANDLED(handled = false) |
| 251 IPC_END_MESSAGE_MAP_EX() | 271 IPC_END_MESSAGE_MAP_EX() |
| 252 | 272 |
| 253 EXPECT_TRUE(message_is_ok); | 273 EXPECT_TRUE(message_is_ok); |
| 254 | 274 |
| 255 return true; | 275 return true; |
| 256 } | 276 } |
| 257 | 277 |
| 258 // Posts a final task to the IO message loop and waits for completion. | 278 // Posts a final task to the IO message loop and waits for completion. |
| 259 void WebRTCAudioDeviceTest::WaitForIOThreadCompletion() { | 279 void WebRTCAudioDeviceTest::WaitForIOThreadCompletion() { |
| 260 ChildProcess::current()->io_message_loop()->PostTask( | 280 WaitForMessageLoopCompletion(ChildProcess::current()->io_message_loop()); |
| 261 FROM_HERE, base::Bind(&base::WaitableEvent::Signal, | 281 } |
| 262 base::Unretained(&event_))); | 282 |
| 263 EXPECT_TRUE(event_.TimedWait( | 283 void WebRTCAudioDeviceTest::WaitForAudioManagerCompletion() { |
| 264 base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms()))); | 284 if (audio_manager_.get()) |
| 285 WaitForMessageLoopCompletion(audio_manager_->GetMessageLoop()); | |
| 286 } | |
| 287 | |
| 288 void WebRTCAudioDeviceTest::WaitForMessageLoopCompletion(MessageLoop* loop) { | |
| 289 base::WaitableEvent* event = new base::WaitableEvent(false, false); | |
| 290 loop->PostTask(FROM_HERE, base::Bind(&base::WaitableEvent::Signal, | |
| 291 base::Unretained(event))); | |
| 292 if (event->TimedWait(base::TimeDelta::FromMilliseconds( | |
| 293 TestTimeouts::action_max_timeout_ms()))) { | |
| 294 delete event; | |
| 295 } else { | |
| 296 // Don't delete the event object in case the message ever gets processed. | |
| 297 // If we do, we will crash the test process. | |
| 298 ADD_FAILURE() << "Failed to wait for message loop"; | |
| 299 } | |
| 265 } | 300 } |
| 266 | 301 |
| 267 std::string WebRTCAudioDeviceTest::GetTestDataPath( | 302 std::string WebRTCAudioDeviceTest::GetTestDataPath( |
| 268 const FilePath::StringType& file_name) { | 303 const FilePath::StringType& file_name) { |
| 269 FilePath path; | 304 FilePath path; |
| 270 EXPECT_TRUE(PathService::Get(content::DIR_TEST_DATA, &path)); | 305 EXPECT_TRUE(PathService::Get(content::DIR_TEST_DATA, &path)); |
| 271 path = path.Append(file_name); | 306 path = path.Append(file_name); |
| 272 EXPECT_TRUE(file_util::PathExists(path)); | 307 EXPECT_TRUE(file_util::PathExists(path)); |
| 273 #ifdef OS_WIN | 308 #ifdef OS_WIN |
| 274 return WideToUTF8(path.value()); | 309 return WideToUTF8(path.value()); |
| 275 #else | 310 #else |
| 276 return path.value(); | 311 return path.value(); |
| 277 #endif | 312 #endif |
| 278 } | 313 } |
| 279 | 314 |
| 280 WebRTCTransportImpl::WebRTCTransportImpl(webrtc::VoENetwork* network) | 315 WebRTCTransportImpl::WebRTCTransportImpl(webrtc::VoENetwork* network) |
| 281 : network_(network) { | 316 : network_(network) { |
| 282 } | 317 } |
| 283 | 318 |
| 284 WebRTCTransportImpl::~WebRTCTransportImpl() {} | 319 WebRTCTransportImpl::~WebRTCTransportImpl() {} |
| 285 | 320 |
| 286 int WebRTCTransportImpl::SendPacket(int channel, const void* data, int len) { | 321 int WebRTCTransportImpl::SendPacket(int channel, const void* data, int len) { |
| 287 return network_->ReceivedRTPPacket(channel, data, len); | 322 return network_->ReceivedRTPPacket(channel, data, len); |
| 288 } | 323 } |
| 289 | 324 |
| 290 int WebRTCTransportImpl::SendRTCPPacket(int channel, const void* data, | 325 int WebRTCTransportImpl::SendRTCPPacket(int channel, const void* data, |
| 291 int len) { | 326 int len) { |
| 292 return network_->ReceivedRTCPPacket(channel, data, len); | 327 return network_->ReceivedRTCPPacket(channel, data, len); |
| 293 } | 328 } |
| OLD | NEW |