Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: content/browser/renderer_host/media/audio_renderer_host_unittest.cc

Issue 11413078: Tab Audio Capture: Browser-side connect/disconnect functionality. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Broke mirroring out of AudioRendererHost into separate AudioMirroringManager class. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_mirroring_manager.h"
12 #include "content/browser/renderer_host/media/audio_renderer_host.h" 13 #include "content/browser/renderer_host/media/audio_renderer_host.h"
13 #include "content/browser/renderer_host/media/mock_media_observer.h" 14 #include "content/browser/renderer_host/media/mock_media_observer.h"
14 #include "content/common/media/audio_messages.h" 15 #include "content/common/media/audio_messages.h"
15 #include "ipc/ipc_message_utils.h" 16 #include "ipc/ipc_message_utils.h"
16 #include "media/audio/audio_manager.h" 17 #include "media/audio/audio_manager.h"
17 #include "media/audio/fake_audio_output_stream.h" 18 #include "media/audio/fake_audio_output_stream.h"
18 #include "net/url_request/url_request_context.h" 19 #include "net/url_request/url_request_context.h"
19 #include "testing/gmock/include/gmock/gmock.h" 20 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
21 22
22 using ::testing::_; 23 using ::testing::_;
23 using ::testing::AtLeast; 24 using ::testing::AtLeast;
24 using ::testing::DoAll; 25 using ::testing::DoAll;
25 using ::testing::InSequence; 26 using ::testing::InSequence;
26 using ::testing::InvokeWithoutArgs; 27 using ::testing::NotNull;
27 using ::testing::Return; 28 using ::testing::Return;
28 using ::testing::SaveArg; 29 using ::testing::SaveArg;
29 using ::testing::SetArgumentPointee; 30 using ::testing::SetArgumentPointee;
30 31
31 namespace content { 32 namespace content {
32 33
34 static const int kRenderProcessId = 1;
35 static const int kRenderViewId = 4;
33 static const int kStreamId = 50; 36 static const int kStreamId = 50;
34 37
35 static bool IsRunningHeadless() { 38 static bool IsRunningHeadless() {
36 scoped_ptr<base::Environment> env(base::Environment::Create()); 39 scoped_ptr<base::Environment> env(base::Environment::Create());
37 if (env->HasVar("CHROME_HEADLESS")) 40 if (env->HasVar("CHROME_HEADLESS"))
38 return true; 41 return true;
39 return false; 42 return false;
40 } 43 }
41 44
45 class MockAudioMirroringManager : public AudioMirroringManager {
46 public:
47 MockAudioMirroringManager() {
48 AudioMirroringManager::SetInstanceForTesting(this);
tommi (sloooow) - chröme 2012/12/19 12:27:54 Sorry but I'm really not a fan of this approach, s
miu 2012/12/28 23:03:49 Done.
49 }
50
51 virtual ~MockAudioMirroringManager() {
52 AudioMirroringManager::SetInstanceForTesting(NULL);
53 }
54
55 MOCK_METHOD3(AddDiverter,
56 void(int render_process_id, int render_view_id,
57 Diverter* diverter));
58 MOCK_METHOD3(RemoveDiverter,
59 void(int render_process_id, int render_view_id,
60 Diverter* diverter));
61
62 private:
63 DISALLOW_COPY_AND_ASSIGN(MockAudioMirroringManager);
64 };
65
66
42 class MockAudioRendererHost : public AudioRendererHost { 67 class MockAudioRendererHost : public AudioRendererHost {
43 public: 68 public:
44 explicit MockAudioRendererHost( 69 explicit MockAudioRendererHost(
45 media::AudioManager* audio_manager, 70 media::AudioManager* audio_manager,
46 MediaObserver* media_observer) 71 MediaObserver* media_observer)
47 : AudioRendererHost(audio_manager, media_observer), 72 : AudioRendererHost(kRenderProcessId, audio_manager, media_observer),
48 shared_memory_length_(0) { 73 shared_memory_length_(0) {
49 } 74 }
50 75
51 // A list of mock methods. 76 // A list of mock methods.
52 MOCK_METHOD2(OnStreamCreated, 77 MOCK_METHOD2(OnStreamCreated,
53 void(int stream_id, int length)); 78 void(int stream_id, int length));
54 MOCK_METHOD1(OnStreamPlaying, void(int stream_id)); 79 MOCK_METHOD1(OnStreamPlaying, void(int stream_id));
55 MOCK_METHOD1(OnStreamPaused, void(int stream_id)); 80 MOCK_METHOD1(OnStreamPaused, void(int stream_id));
56 MOCK_METHOD1(OnStreamError, void(int stream_id)); 81 MOCK_METHOD1(OnStreamError, void(int stream_id));
57 MOCK_METHOD2(OnStreamVolume, void(int stream_id, double volume)); 82 MOCK_METHOD2(OnStreamVolume, void(int stream_id, double volume));
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 ACTION_P(QuitMessageLoop, message_loop) { 164 ACTION_P(QuitMessageLoop, message_loop) {
140 message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure()); 165 message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
141 } 166 }
142 167
143 class AudioRendererHostTest : public testing::Test { 168 class AudioRendererHostTest : public testing::Test {
144 public: 169 public:
145 AudioRendererHostTest() 170 AudioRendererHostTest()
146 : mock_stream_(true) { 171 : mock_stream_(true) {
147 } 172 }
148 173
174
tommi (sloooow) - chröme 2012/12/19 12:27:54 revert
miu 2012/12/28 23:03:49 Done.
149 protected: 175 protected:
150 virtual void SetUp() { 176 virtual void SetUp() {
177 if (!IsRunningHeadless())
178 EnableRealDevice();
179
151 // Create a message loop so AudioRendererHost can use it. 180 // Create a message loop so AudioRendererHost can use it.
152 message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO)); 181 message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
153 182
154 // Claim to be on both the UI and IO threads to pass all the DCHECKS. 183 // Claim to be on both the UI and IO threads to pass all the DCHECKS.
155 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO, 184 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
156 message_loop_.get())); 185 message_loop_.get()));
157 ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, 186 ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI,
158 message_loop_.get())); 187 message_loop_.get()));
159 audio_manager_.reset(media::AudioManager::Create()); 188 audio_manager_.reset(media::AudioManager::Create());
160 observer_.reset(new MockMediaObserver()); 189 observer_.reset(new MockMediaObserver());
161 host_ = new MockAudioRendererHost(audio_manager_.get(), observer_.get()); 190 host_ = new MockAudioRendererHost(audio_manager_.get(), observer_.get());
162 191
163 // Expect the audio stream will be deleted.
164 EXPECT_CALL(*observer_, OnDeleteAudioStream(_, kStreamId));
165
166 // Simulate IPC channel connected. 192 // Simulate IPC channel connected.
167 host_->OnChannelConnected(base::GetCurrentProcId()); 193 host_->OnChannelConnected(base::GetCurrentProcId());
168 } 194 }
169 195
170 virtual void TearDown() { 196 virtual void TearDown() {
171 // Simulate closing the IPC channel. 197 // Simulate closing the IPC channel.
172 host_->OnChannelClosing(); 198 host_->OnChannelClosing();
173 199
174 // Release the reference to the mock object. The object will be destructed 200 // Release the reference to the mock object. The object will be destructed
175 // on message_loop_. 201 // on message_loop_.
(...skipping 25 matching lines...) Expand all
201 227
202 media::AudioParameters params( 228 media::AudioParameters params(
203 format, media::CHANNEL_LAYOUT_STEREO, 229 format, media::CHANNEL_LAYOUT_STEREO,
204 media::AudioParameters::kAudioCDSampleRate, 16, 230 media::AudioParameters::kAudioCDSampleRate, 16,
205 media::AudioParameters::kAudioCDSampleRate / 10); 231 media::AudioParameters::kAudioCDSampleRate / 10);
206 232
207 // Send a create stream message to the audio output stream and wait until 233 // Send a create stream message to the audio output stream and wait until
208 // we receive the created message. 234 // we receive the created message.
209 host_->OnCreateStream(kStreamId, params, 0); 235 host_->OnCreateStream(kStreamId, params, 0);
210 message_loop_->Run(); 236 message_loop_->Run();
237
238 // Simulate the renderer process associating a stream with a render view.
239 EXPECT_CALL(mirroring_manager_,
240 RemoveDiverter(kRenderProcessId, MSG_ROUTING_NONE, _))
241 .RetiresOnSaturation();
242 EXPECT_CALL(mirroring_manager_,
243 AddDiverter(kRenderProcessId, kRenderViewId, NotNull()))
244 .RetiresOnSaturation();
245 host_->OnAssociateStreamWithProducer(kStreamId, kRenderViewId);
246 message_loop_->RunUntilIdle();
247 // At some point in the future, a corresponding RemoveDiverter() call must
248 // be made.
249 EXPECT_CALL(mirroring_manager_,
250 RemoveDiverter(kRenderProcessId, kRenderViewId, NotNull()))
251 .RetiresOnSaturation();
252
253 // Expect the audio stream will be deleted at some later point.
254 EXPECT_CALL(*observer_, OnDeleteAudioStream(_, kStreamId));
211 } 255 }
212 256
213 void Close() { 257 void Close() {
214 EXPECT_CALL(*observer_, 258 EXPECT_CALL(*observer_,
215 OnSetAudioStreamStatus(_, kStreamId, "closed")); 259 OnSetAudioStreamStatus(_, kStreamId, "closed"));
216 260
217 // Send a message to AudioRendererHost to tell it we want to close the 261 // Send a message to AudioRendererHost to tell it we want to close the
218 // stream. 262 // stream.
219 host_->OnCloseStream(kStreamId); 263 host_->OnCloseStream(kStreamId);
220 message_loop_->RunUntilIdle(); 264 message_loop_->RunUntilIdle();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 base::Unretained(audio_manager_.get()), 337 base::Unretained(audio_manager_.get()),
294 message_loop_.get())); 338 message_loop_.get()));
295 message_loop_->Run(); 339 message_loop_->Run();
296 } 340 }
297 341
298 void EnableRealDevice() { mock_stream_ = false; } 342 void EnableRealDevice() { mock_stream_ = false; }
299 343
300 private: 344 private:
301 bool mock_stream_; 345 bool mock_stream_;
302 scoped_ptr<MockMediaObserver> observer_; 346 scoped_ptr<MockMediaObserver> observer_;
347 MockAudioMirroringManager mirroring_manager_;
303 scoped_refptr<MockAudioRendererHost> host_; 348 scoped_refptr<MockAudioRendererHost> host_;
304 scoped_ptr<MessageLoop> message_loop_; 349 scoped_ptr<MessageLoop> message_loop_;
305 scoped_ptr<BrowserThreadImpl> io_thread_; 350 scoped_ptr<BrowserThreadImpl> io_thread_;
306 scoped_ptr<BrowserThreadImpl> ui_thread_; 351 scoped_ptr<BrowserThreadImpl> ui_thread_;
307 scoped_ptr<media::AudioManager> audio_manager_; 352 scoped_ptr<media::AudioManager> audio_manager_;
308 353
309 DISALLOW_COPY_AND_ASSIGN(AudioRendererHostTest); 354 DISALLOW_COPY_AND_ASSIGN(AudioRendererHostTest);
310 }; 355 };
311 356
312 TEST_F(AudioRendererHostTest, CreateAndClose) { 357 TEST_F(AudioRendererHostTest, CreateAndClose) {
313 if (!IsRunningHeadless())
314 EnableRealDevice();
315
316 Create(); 358 Create();
317 Close(); 359 Close();
318 } 360 }
319 361
320 // Simulate the case where a stream is not properly closed. 362 // Simulate the case where a stream is not properly closed.
321 TEST_F(AudioRendererHostTest, CreateAndShutdown) { 363 TEST_F(AudioRendererHostTest, CreateAndShutdown) {
322 if (!IsRunningHeadless())
323 EnableRealDevice();
324
325 Create(); 364 Create();
326 } 365 }
327 366
328 TEST_F(AudioRendererHostTest, CreatePlayAndClose) { 367 TEST_F(AudioRendererHostTest, CreatePlayAndClose) {
329 if (!IsRunningHeadless())
330 EnableRealDevice();
331
332 Create(); 368 Create();
333 Play(); 369 Play();
334 Close(); 370 Close();
335 } 371 }
336 372
337 TEST_F(AudioRendererHostTest, CreatePlayPauseAndClose) { 373 TEST_F(AudioRendererHostTest, CreatePlayPauseAndClose) {
338 if (!IsRunningHeadless())
339 EnableRealDevice();
340
341 Create(); 374 Create();
342 Play(); 375 Play();
343 Pause(); 376 Pause();
344 Close(); 377 Close();
345 } 378 }
346 379
347 TEST_F(AudioRendererHostTest, SetVolume) { 380 TEST_F(AudioRendererHostTest, SetVolume) {
348 if (!IsRunningHeadless())
349 EnableRealDevice();
350
351 Create(); 381 Create();
352 SetVolume(0.5); 382 SetVolume(0.5);
353 Play(); 383 Play();
354 Pause(); 384 Pause();
355 Close(); 385 Close();
356 } 386 }
357 387
358 // Simulate the case where a stream is not properly closed. 388 // Simulate the case where a stream is not properly closed.
359 TEST_F(AudioRendererHostTest, CreatePlayAndShutdown) { 389 TEST_F(AudioRendererHostTest, CreatePlayAndShutdown) {
360 if (!IsRunningHeadless())
361 EnableRealDevice();
362
363 Create(); 390 Create();
364 Play(); 391 Play();
365 } 392 }
366 393
367 // Simulate the case where a stream is not properly closed. 394 // Simulate the case where a stream is not properly closed.
368 TEST_F(AudioRendererHostTest, CreatePlayPauseAndShutdown) { 395 TEST_F(AudioRendererHostTest, CreatePlayPauseAndShutdown) {
369 if (!IsRunningHeadless())
370 EnableRealDevice();
371
372 Create(); 396 Create();
373 Play(); 397 Play();
374 Pause(); 398 Pause();
375 } 399 }
376 400
377 TEST_F(AudioRendererHostTest, SimulateError) { 401 TEST_F(AudioRendererHostTest, SimulateError) {
378 if (!IsRunningHeadless())
379 EnableRealDevice();
380
381 Create(); 402 Create();
382 Play(); 403 Play();
383 SimulateError(); 404 SimulateError();
384 } 405 }
385 406
386 // Simulate the case when an error is generated on the browser process, 407 // Simulate the case when an error is generated on the browser process,
387 // the audio device is closed but the render process try to close the 408 // the audio device is closed but the render process try to close the
388 // audio stream again. 409 // audio stream again.
389 TEST_F(AudioRendererHostTest, SimulateErrorAndClose) { 410 TEST_F(AudioRendererHostTest, SimulateErrorAndClose) {
390 if (!IsRunningHeadless())
391 EnableRealDevice();
392
393 Create(); 411 Create();
394 Play(); 412 Play();
395 SimulateError(); 413 SimulateError();
396 Close(); 414 Close();
397 } 415 }
398 416
399 // TODO(hclam): Add tests for data conversation in low latency mode. 417 // TODO(hclam): Add tests for data conversation in low latency mode.
400 418
401 } // namespace content 419 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698