OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/environment.h" | 6 #include "base/environment.h" |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/process_util.h" | 9 #include "base/process_util.h" |
10 #include "base/sync_socket.h" | 10 #include "base/sync_socket.h" |
11 #include "content/browser/browser_thread_impl.h" | 11 #include "content/browser/browser_thread_impl.h" |
| 12 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
12 #include "content/browser/renderer_host/media/audio_mirroring_manager.h" | 13 #include "content/browser/renderer_host/media/audio_mirroring_manager.h" |
13 #include "content/browser/renderer_host/media/audio_renderer_host.h" | 14 #include "content/browser/renderer_host/media/audio_renderer_host.h" |
| 15 #include "content/browser/renderer_host/media/media_stream_manager.h" |
14 #include "content/browser/renderer_host/media/mock_media_observer.h" | 16 #include "content/browser/renderer_host/media/mock_media_observer.h" |
15 #include "content/common/media/audio_messages.h" | 17 #include "content/common/media/audio_messages.h" |
| 18 #include "content/common/media/media_stream_options.h" |
16 #include "ipc/ipc_message_utils.h" | 19 #include "ipc/ipc_message_utils.h" |
17 #include "media/audio/audio_manager.h" | 20 #include "media/audio/audio_manager.h" |
| 21 #include "media/audio/audio_manager_base.h" |
18 #include "media/audio/fake_audio_output_stream.h" | 22 #include "media/audio/fake_audio_output_stream.h" |
19 #include "net/url_request/url_request_context.h" | 23 #include "net/url_request/url_request_context.h" |
20 #include "testing/gmock/include/gmock/gmock.h" | 24 #include "testing/gmock/include/gmock/gmock.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
22 | 26 |
23 using ::testing::_; | 27 using ::testing::_; |
24 using ::testing::AtLeast; | 28 using ::testing::AtLeast; |
25 using ::testing::DoAll; | 29 using ::testing::DoAll; |
26 using ::testing::InSequence; | 30 using ::testing::InSequence; |
27 using ::testing::NotNull; | 31 using ::testing::NotNull; |
(...skipping 21 matching lines...) Expand all Loading... |
49 | 53 |
50 private: | 54 private: |
51 DISALLOW_COPY_AND_ASSIGN(MockAudioMirroringManager); | 55 DISALLOW_COPY_AND_ASSIGN(MockAudioMirroringManager); |
52 }; | 56 }; |
53 | 57 |
54 class MockAudioRendererHost : public AudioRendererHost { | 58 class MockAudioRendererHost : public AudioRendererHost { |
55 public: | 59 public: |
56 explicit MockAudioRendererHost( | 60 explicit MockAudioRendererHost( |
57 media::AudioManager* audio_manager, | 61 media::AudioManager* audio_manager, |
58 AudioMirroringManager* mirroring_manager, | 62 AudioMirroringManager* mirroring_manager, |
59 MediaInternals* media_internals) | 63 MediaInternals* media_internals, |
| 64 MediaStreamManager* media_stream_manager) |
60 : AudioRendererHost(kRenderProcessId, | 65 : AudioRendererHost(kRenderProcessId, |
61 audio_manager, | 66 audio_manager, |
62 mirroring_manager, | 67 mirroring_manager, |
63 media_internals), | 68 media_internals, |
| 69 media_stream_manager), |
64 shared_memory_length_(0) { | 70 shared_memory_length_(0) { |
65 } | 71 } |
66 | 72 |
67 // A list of mock methods. | 73 // A list of mock methods. |
68 MOCK_METHOD2(OnStreamCreated, | 74 MOCK_METHOD2(OnStreamCreated, |
69 void(int stream_id, int length)); | 75 void(int stream_id, int length)); |
70 MOCK_METHOD1(OnStreamPlaying, void(int stream_id)); | 76 MOCK_METHOD1(OnStreamPlaying, void(int stream_id)); |
71 MOCK_METHOD1(OnStreamPaused, void(int stream_id)); | 77 MOCK_METHOD1(OnStreamPaused, void(int stream_id)); |
72 MOCK_METHOD1(OnStreamError, void(int stream_id)); | 78 MOCK_METHOD1(OnStreamError, void(int stream_id)); |
73 | 79 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 virtual void SetUp() { | 169 virtual void SetUp() { |
164 // Create a message loop so AudioRendererHost can use it. | 170 // Create a message loop so AudioRendererHost can use it. |
165 message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO)); | 171 message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO)); |
166 | 172 |
167 // Claim to be on both the UI and IO threads to pass all the DCHECKS. | 173 // Claim to be on both the UI and IO threads to pass all the DCHECKS. |
168 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO, | 174 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO, |
169 message_loop_.get())); | 175 message_loop_.get())); |
170 ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, | 176 ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, |
171 message_loop_.get())); | 177 message_loop_.get())); |
172 audio_manager_.reset(media::AudioManager::Create()); | 178 audio_manager_.reset(media::AudioManager::Create()); |
| 179 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); |
| 180 media_stream_manager_->UseFakeDevice(); |
173 observer_.reset(new MockMediaInternals()); | 181 observer_.reset(new MockMediaInternals()); |
174 host_ = new MockAudioRendererHost( | 182 host_ = new MockAudioRendererHost( |
175 audio_manager_.get(), &mirroring_manager_, observer_.get()); | 183 audio_manager_.get(), &mirroring_manager_, observer_.get(), |
| 184 media_stream_manager_.get()); |
176 | 185 |
177 // Simulate IPC channel connected. | 186 // Simulate IPC channel connected. |
178 host_->OnChannelConnected(base::GetCurrentProcId()); | 187 host_->OnChannelConnected(base::GetCurrentProcId()); |
179 } | 188 } |
180 | 189 |
181 virtual void TearDown() { | 190 virtual void TearDown() { |
182 // Simulate closing the IPC channel. | 191 // Simulate closing the IPC channel. |
183 host_->OnChannelClosing(); | 192 host_->OnChannelClosing(); |
184 | 193 |
185 // Release the reference to the mock object. The object will be destructed | 194 // Release the reference to the mock object. The object will be destructed |
186 // on message_loop_. | 195 // on message_loop_. |
187 host_ = NULL; | 196 host_ = NULL; |
188 | 197 |
189 // We need to continue running message_loop_ to complete all destructions. | 198 // We need to continue running message_loop_ to complete all destructions. |
190 SyncWithAudioThread(); | 199 SyncWithAudioThread(); |
191 | |
192 audio_manager_.reset(); | 200 audio_manager_.reset(); |
193 | 201 |
194 io_thread_.reset(); | 202 io_thread_.reset(); |
195 ui_thread_.reset(); | 203 ui_thread_.reset(); |
| 204 |
| 205 // Delete the IO message loop. This will cause the MediaStreamManager to be |
| 206 // notified so it will stop its device thread and device managers. |
| 207 message_loop_.reset(); |
196 } | 208 } |
197 | 209 |
198 void Create() { | 210 void Create() { |
199 EXPECT_CALL(*observer_, | 211 EXPECT_CALL(*observer_, |
200 OnSetAudioStreamStatus(_, kStreamId, "created")); | 212 OnSetAudioStreamStatus(_, kStreamId, "created")); |
201 EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _)) | 213 EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _)) |
202 .WillOnce(QuitMessageLoop(message_loop_.get())); | 214 .WillOnce(QuitMessageLoop(message_loop_.get())); |
203 EXPECT_CALL(mirroring_manager_, | 215 EXPECT_CALL(mirroring_manager_, |
204 AddDiverter(kRenderProcessId, kRenderViewId, NotNull())) | 216 AddDiverter(kRenderProcessId, kRenderViewId, NotNull())) |
205 .RetiresOnSaturation(); | 217 .RetiresOnSaturation(); |
206 | 218 |
207 // Send a create stream message to the audio output stream and wait until | 219 // Send a create stream message to the audio output stream and wait until |
208 // we receive the created message. | 220 // we receive the created message. |
209 host_->OnCreateStream(kStreamId, | 221 host_->OnCreateStream(kStreamId, |
210 kRenderViewId, | 222 kRenderViewId, |
| 223 0, |
211 media::AudioParameters( | 224 media::AudioParameters( |
212 media::AudioParameters::AUDIO_FAKE, | 225 media::AudioParameters::AUDIO_FAKE, |
213 media::CHANNEL_LAYOUT_STEREO, | 226 media::CHANNEL_LAYOUT_STEREO, |
214 media::AudioParameters::kAudioCDSampleRate, 16, | 227 media::AudioParameters::kAudioCDSampleRate, 16, |
215 media::AudioParameters::kAudioCDSampleRate / 10)); | 228 media::AudioParameters::kAudioCDSampleRate / 10)); |
216 message_loop_->Run(); | 229 message_loop_->Run(); |
| 230 |
| 231 // At some point in the future, a corresponding RemoveDiverter() call must |
| 232 // be made. |
| 233 EXPECT_CALL(mirroring_manager_, |
| 234 RemoveDiverter(kRenderProcessId, kRenderViewId, NotNull())) |
| 235 .RetiresOnSaturation(); |
| 236 |
| 237 // All created streams should ultimately be closed. |
| 238 EXPECT_CALL(*observer_, |
| 239 OnSetAudioStreamStatus(_, kStreamId, "closed")); |
| 240 |
| 241 // Expect the audio stream will be deleted at some later point. |
| 242 EXPECT_CALL(*observer_, OnDeleteAudioStream(_, kStreamId)); |
| 243 } |
| 244 |
| 245 void CreateUnifiedStream() { |
| 246 EXPECT_CALL(*observer_, |
| 247 OnSetAudioStreamStatus(_, kStreamId, "created")); |
| 248 EXPECT_CALL(*host_, OnStreamCreated(kStreamId, _)) |
| 249 .WillOnce(QuitMessageLoop(message_loop_.get())); |
| 250 EXPECT_CALL(mirroring_manager_, |
| 251 AddDiverter(kRenderProcessId, kRenderViewId, NotNull())) |
| 252 .RetiresOnSaturation(); |
| 253 // Send a create stream message to the audio output stream and wait until |
| 254 // we receive the created message. |
| 255 // Use AudioInputDeviceManager::kFakeOpenSessionId as the session id to |
| 256 // pass the permission check. |
| 257 host_->OnCreateStream(kStreamId, |
| 258 kRenderViewId, |
| 259 AudioInputDeviceManager::kFakeOpenSessionId, |
| 260 media::AudioParameters( |
| 261 media::AudioParameters::AUDIO_FAKE, |
| 262 media::CHANNEL_LAYOUT_STEREO, |
| 263 2, |
| 264 media::AudioParameters::kAudioCDSampleRate, 16, |
| 265 media::AudioParameters::kAudioCDSampleRate / 10)); |
| 266 message_loop_->Run(); |
217 | 267 |
218 // At some point in the future, a corresponding RemoveDiverter() call must | 268 // At some point in the future, a corresponding RemoveDiverter() call must |
219 // be made. | 269 // be made. |
220 EXPECT_CALL(mirroring_manager_, | 270 EXPECT_CALL(mirroring_manager_, |
221 RemoveDiverter(kRenderProcessId, kRenderViewId, NotNull())) | 271 RemoveDiverter(kRenderProcessId, kRenderViewId, NotNull())) |
222 .RetiresOnSaturation(); | 272 .RetiresOnSaturation(); |
223 | 273 |
224 // All created streams should ultimately be closed. | 274 // All created streams should ultimately be closed. |
225 EXPECT_CALL(*observer_, | 275 EXPECT_CALL(*observer_, |
226 OnSetAudioStreamStatus(_, kStreamId, "closed")); | 276 OnSetAudioStreamStatus(_, kStreamId, "closed")); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 } | 358 } |
309 | 359 |
310 private: | 360 private: |
311 scoped_ptr<MockMediaInternals> observer_; | 361 scoped_ptr<MockMediaInternals> observer_; |
312 MockAudioMirroringManager mirroring_manager_; | 362 MockAudioMirroringManager mirroring_manager_; |
313 scoped_refptr<MockAudioRendererHost> host_; | 363 scoped_refptr<MockAudioRendererHost> host_; |
314 scoped_ptr<base::MessageLoop> message_loop_; | 364 scoped_ptr<base::MessageLoop> message_loop_; |
315 scoped_ptr<BrowserThreadImpl> io_thread_; | 365 scoped_ptr<BrowserThreadImpl> io_thread_; |
316 scoped_ptr<BrowserThreadImpl> ui_thread_; | 366 scoped_ptr<BrowserThreadImpl> ui_thread_; |
317 scoped_ptr<media::AudioManager> audio_manager_; | 367 scoped_ptr<media::AudioManager> audio_manager_; |
| 368 scoped_ptr<MediaStreamManager> media_stream_manager_; |
318 | 369 |
319 DISALLOW_COPY_AND_ASSIGN(AudioRendererHostTest); | 370 DISALLOW_COPY_AND_ASSIGN(AudioRendererHostTest); |
320 }; | 371 }; |
321 | 372 |
322 TEST_F(AudioRendererHostTest, CreateAndClose) { | 373 TEST_F(AudioRendererHostTest, CreateAndClose) { |
323 Create(); | 374 Create(); |
324 Close(); | 375 Close(); |
325 } | 376 } |
326 | 377 |
327 // Simulate the case where a stream is not properly closed. | 378 // Simulate the case where a stream is not properly closed. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 // Simulate the case when an error is generated on the browser process, | 423 // Simulate the case when an error is generated on the browser process, |
373 // the audio device is closed but the render process try to close the | 424 // the audio device is closed but the render process try to close the |
374 // audio stream again. | 425 // audio stream again. |
375 TEST_F(AudioRendererHostTest, SimulateErrorAndClose) { | 426 TEST_F(AudioRendererHostTest, SimulateErrorAndClose) { |
376 Create(); | 427 Create(); |
377 Play(); | 428 Play(); |
378 SimulateError(); | 429 SimulateError(); |
379 Close(); | 430 Close(); |
380 } | 431 } |
381 | 432 |
| 433 TEST_F(AudioRendererHostTest, CreateUnifiedStreamAndClose) { |
| 434 CreateUnifiedStream(); |
| 435 Close(); |
| 436 } |
| 437 |
382 // TODO(hclam): Add tests for data conversation in low latency mode. | 438 // TODO(hclam): Add tests for data conversation in low latency mode. |
383 | 439 |
384 } // namespace content | 440 } // namespace content |
OLD | NEW |