Remove repaint callbacks from Viewport.
[chromium-blink-merge.git] / media / audio / audio_output_proxy_unittest.cc
blobb8f23acaa9274421fa27bdea085b054bcda34948
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.
5 #include <string>
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "media/audio/audio_manager.h"
10 #include "media/audio/audio_manager_base.h"
11 #include "media/audio/audio_output_dispatcher_impl.h"
12 #include "media/audio/audio_output_proxy.h"
13 #include "media/audio/audio_output_resampler.h"
14 #include "media/audio/fake_audio_log_factory.h"
15 #include "media/audio/fake_audio_output_stream.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 using ::testing::_;
20 using ::testing::AllOf;
21 using ::testing::DoAll;
22 using ::testing::Field;
23 using ::testing::Mock;
24 using ::testing::NotNull;
25 using ::testing::Return;
26 using ::testing::SetArrayArgument;
27 using media::AudioBus;
28 using media::AudioBuffersState;
29 using media::AudioInputStream;
30 using media::AudioManager;
31 using media::AudioManagerBase;
32 using media::AudioOutputDispatcher;
33 using media::AudioOutputProxy;
34 using media::AudioOutputStream;
35 using media::AudioParameters;
36 using media::FakeAudioOutputStream;
38 namespace {
40 static const int kTestCloseDelayMs = 10;
42 // Delay between callbacks to AudioSourceCallback::OnMoreData.
43 static const int kOnMoreDataCallbackDelayMs = 10;
45 // Let start run long enough for many OnMoreData callbacks to occur.
46 static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10;
48 class MockAudioOutputStream : public AudioOutputStream {
49 public:
50 MockAudioOutputStream(AudioManagerBase* manager,
51 const AudioParameters& params)
52 : start_called_(false),
53 stop_called_(false),
54 params_(params),
55 fake_output_stream_(
56 FakeAudioOutputStream::MakeFakeStream(manager, params_)) {
59 void Start(AudioSourceCallback* callback) {
60 start_called_ = true;
61 fake_output_stream_->Start(callback);
64 void Stop() {
65 stop_called_ = true;
66 fake_output_stream_->Stop();
69 ~MockAudioOutputStream() {}
71 bool start_called() { return start_called_; }
72 bool stop_called() { return stop_called_; }
74 MOCK_METHOD0(Open, bool());
75 MOCK_METHOD1(SetVolume, void(double volume));
76 MOCK_METHOD1(GetVolume, void(double* volume));
77 MOCK_METHOD0(Close, void());
79 private:
80 bool start_called_;
81 bool stop_called_;
82 AudioParameters params_;
83 scoped_ptr<AudioOutputStream> fake_output_stream_;
86 class MockAudioManager : public AudioManagerBase {
87 public:
88 MockAudioManager() : AudioManagerBase(&fake_audio_log_factory_) {}
89 virtual ~MockAudioManager() {
90 Shutdown();
93 MOCK_METHOD0(HasAudioOutputDevices, bool());
94 MOCK_METHOD0(HasAudioInputDevices, bool());
95 MOCK_METHOD0(GetAudioInputDeviceModel, base::string16());
96 MOCK_METHOD2(MakeAudioOutputStream, AudioOutputStream*(
97 const AudioParameters& params,
98 const std::string& device_id));
99 MOCK_METHOD2(MakeAudioOutputStreamProxy, AudioOutputStream*(
100 const AudioParameters& params,
101 const std::string& device_id));
102 MOCK_METHOD2(MakeAudioInputStream, AudioInputStream*(
103 const AudioParameters& params, const std::string& device_id));
104 MOCK_METHOD0(ShowAudioInputSettings, void());
105 MOCK_METHOD0(GetTaskRunner, scoped_refptr<base::SingleThreadTaskRunner>());
106 MOCK_METHOD0(GetWorkerTaskRunner,
107 scoped_refptr<base::SingleThreadTaskRunner>());
108 MOCK_METHOD1(GetAudioInputDeviceNames, void(
109 media::AudioDeviceNames* device_name));
111 MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*(
112 const AudioParameters& params));
113 MOCK_METHOD2(MakeLowLatencyOutputStream, AudioOutputStream*(
114 const AudioParameters& params, const std::string& device_id));
115 MOCK_METHOD2(MakeLinearInputStream, AudioInputStream*(
116 const AudioParameters& params, const std::string& device_id));
117 MOCK_METHOD2(MakeLowLatencyInputStream, AudioInputStream*(
118 const AudioParameters& params, const std::string& device_id));
119 MOCK_METHOD2(GetPreferredOutputStreamParameters, AudioParameters(
120 const std::string& device_id, const AudioParameters& params));
122 private:
123 media::FakeAudioLogFactory fake_audio_log_factory_;
126 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
127 public:
128 int OnMoreData(AudioBus* audio_bus, AudioBuffersState buffers_state) {
129 audio_bus->Zero();
130 return audio_bus->frames();
132 MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
135 } // namespace
137 namespace media {
139 class AudioOutputProxyTest : public testing::Test {
140 protected:
141 virtual void SetUp() {
142 EXPECT_CALL(manager_, GetTaskRunner())
143 .WillRepeatedly(Return(message_loop_.message_loop_proxy()));
144 EXPECT_CALL(manager_, GetWorkerTaskRunner())
145 .WillRepeatedly(Return(message_loop_.message_loop_proxy()));
146 // Use a low sample rate and large buffer size when testing otherwise the
147 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
148 // RunUntilIdle() will never terminate.
149 params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
150 CHANNEL_LAYOUT_STEREO, 8000, 16, 2048);
151 InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs));
154 virtual void TearDown() {
155 // This is necessary to free all proxy objects that have been
156 // closed by the test.
157 message_loop_.RunUntilIdle();
160 virtual void InitDispatcher(base::TimeDelta close_delay) {
161 dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(),
162 params_,
163 std::string(),
164 close_delay);
167 virtual void OnStart() {}
169 MockAudioManager& manager() {
170 return manager_;
173 void WaitForCloseTimer(MockAudioOutputStream* stream) {
174 base::RunLoop run_loop;
175 EXPECT_CALL(*stream, Close())
176 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
177 run_loop.Run();
180 void CloseAndWaitForCloseTimer(AudioOutputProxy* proxy,
181 MockAudioOutputStream* stream) {
182 // Close the stream and verify it doesn't happen immediately.
183 proxy->Close();
184 Mock::VerifyAndClear(stream);
186 // Wait for the actual close event to come from the close timer.
187 WaitForCloseTimer(stream);
190 // Basic Open() and Close() test.
191 void OpenAndClose(AudioOutputDispatcher* dispatcher) {
192 MockAudioOutputStream stream(&manager_, params_);
194 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
195 .WillOnce(Return(&stream));
196 EXPECT_CALL(stream, Open())
197 .WillOnce(Return(true));
199 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
200 EXPECT_TRUE(proxy->Open());
201 CloseAndWaitForCloseTimer(proxy, &stream);
204 // Creates a stream, and then calls Start() and Stop().
205 void StartAndStop(AudioOutputDispatcher* dispatcher) {
206 MockAudioOutputStream stream(&manager_, params_);
208 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
209 .WillOnce(Return(&stream));
210 EXPECT_CALL(stream, Open())
211 .WillOnce(Return(true));
212 EXPECT_CALL(stream, SetVolume(_))
213 .Times(1);
215 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
216 EXPECT_TRUE(proxy->Open());
218 proxy->Start(&callback_);
219 OnStart();
220 proxy->Stop();
222 CloseAndWaitForCloseTimer(proxy, &stream);
223 EXPECT_TRUE(stream.stop_called());
224 EXPECT_TRUE(stream.start_called());
227 // Verify that the stream is closed after Stop() is called.
228 void CloseAfterStop(AudioOutputDispatcher* dispatcher) {
229 MockAudioOutputStream stream(&manager_, params_);
231 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
232 .WillOnce(Return(&stream));
233 EXPECT_CALL(stream, Open())
234 .WillOnce(Return(true));
235 EXPECT_CALL(stream, SetVolume(_))
236 .Times(1);
238 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
239 EXPECT_TRUE(proxy->Open());
241 proxy->Start(&callback_);
242 OnStart();
243 proxy->Stop();
245 // Wait for the close timer to fire after StopStream().
246 WaitForCloseTimer(&stream);
247 proxy->Close();
248 EXPECT_TRUE(stream.stop_called());
249 EXPECT_TRUE(stream.start_called());
252 // Create two streams, but don't start them. Only one device must be opened.
253 void TwoStreams(AudioOutputDispatcher* dispatcher) {
254 MockAudioOutputStream stream(&manager_, params_);
256 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
257 .WillOnce(Return(&stream));
258 EXPECT_CALL(stream, Open())
259 .WillOnce(Return(true));
261 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
262 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
263 EXPECT_TRUE(proxy1->Open());
264 EXPECT_TRUE(proxy2->Open());
265 proxy1->Close();
266 CloseAndWaitForCloseTimer(proxy2, &stream);
267 EXPECT_FALSE(stream.stop_called());
268 EXPECT_FALSE(stream.start_called());
271 // Open() method failed.
272 void OpenFailed(AudioOutputDispatcher* dispatcher) {
273 MockAudioOutputStream stream(&manager_, params_);
275 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
276 .WillOnce(Return(&stream));
277 EXPECT_CALL(stream, Open())
278 .WillOnce(Return(false));
279 EXPECT_CALL(stream, Close())
280 .Times(1);
282 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
283 EXPECT_FALSE(proxy->Open());
284 proxy->Close();
285 EXPECT_FALSE(stream.stop_called());
286 EXPECT_FALSE(stream.start_called());
289 void CreateAndWait(AudioOutputDispatcher* dispatcher) {
290 MockAudioOutputStream stream(&manager_, params_);
292 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
293 .WillOnce(Return(&stream));
294 EXPECT_CALL(stream, Open())
295 .WillOnce(Return(true));
297 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
298 EXPECT_TRUE(proxy->Open());
300 WaitForCloseTimer(&stream);
301 proxy->Close();
302 EXPECT_FALSE(stream.stop_called());
303 EXPECT_FALSE(stream.start_called());
306 void OneStream_TwoPlays(AudioOutputDispatcher* dispatcher) {
307 MockAudioOutputStream stream(&manager_, params_);
309 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
310 .WillOnce(Return(&stream));
312 EXPECT_CALL(stream, Open())
313 .WillOnce(Return(true));
314 EXPECT_CALL(stream, SetVolume(_))
315 .Times(2);
317 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
318 EXPECT_TRUE(proxy1->Open());
320 proxy1->Start(&callback_);
321 OnStart();
322 proxy1->Stop();
324 // The stream should now be idle and get reused by |proxy2|.
325 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
326 EXPECT_TRUE(proxy2->Open());
327 proxy2->Start(&callback_);
328 OnStart();
329 proxy2->Stop();
331 proxy1->Close();
332 CloseAndWaitForCloseTimer(proxy2, &stream);
333 EXPECT_TRUE(stream.stop_called());
334 EXPECT_TRUE(stream.start_called());
337 void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) {
338 MockAudioOutputStream stream1(&manager_, params_);
339 MockAudioOutputStream stream2(&manager_, params_);
341 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
342 .WillOnce(Return(&stream1))
343 .WillOnce(Return(&stream2));
345 EXPECT_CALL(stream1, Open())
346 .WillOnce(Return(true));
347 EXPECT_CALL(stream1, SetVolume(_))
348 .Times(1);
350 EXPECT_CALL(stream2, Open())
351 .WillOnce(Return(true));
352 EXPECT_CALL(stream2, SetVolume(_))
353 .Times(1);
355 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
356 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
357 EXPECT_TRUE(proxy1->Open());
358 EXPECT_TRUE(proxy2->Open());
360 proxy1->Start(&callback_);
361 proxy2->Start(&callback_);
362 OnStart();
363 proxy1->Stop();
364 CloseAndWaitForCloseTimer(proxy1, &stream1);
366 proxy2->Stop();
367 CloseAndWaitForCloseTimer(proxy2, &stream2);
369 EXPECT_TRUE(stream1.stop_called());
370 EXPECT_TRUE(stream1.start_called());
371 EXPECT_TRUE(stream2.stop_called());
372 EXPECT_TRUE(stream2.start_called());
375 void StartFailed(AudioOutputDispatcher* dispatcher) {
376 MockAudioOutputStream stream(&manager_, params_);
378 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
379 .WillOnce(Return(&stream));
380 EXPECT_CALL(stream, Open())
381 .WillOnce(Return(true));
383 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
384 EXPECT_TRUE(proxy->Open());
386 WaitForCloseTimer(&stream);
388 // |stream| is closed at this point. Start() should reopen it again.
389 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
390 .Times(2)
391 .WillRepeatedly(Return(reinterpret_cast<AudioOutputStream*>(NULL)));
393 EXPECT_CALL(callback_, OnError(_))
394 .Times(2);
396 proxy->Start(&callback_);
398 // Double Start() in the error case should be allowed since it's possible a
399 // callback may not have had time to process the OnError() in between.
400 proxy->Stop();
401 proxy->Start(&callback_);
403 Mock::VerifyAndClear(&callback_);
405 proxy->Close();
408 base::MessageLoop message_loop_;
409 scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_;
410 MockAudioManager manager_;
411 MockAudioSourceCallback callback_;
412 AudioParameters params_;
415 class AudioOutputResamplerTest : public AudioOutputProxyTest {
416 public:
417 virtual void TearDown() {
418 AudioOutputProxyTest::TearDown();
421 virtual void InitDispatcher(base::TimeDelta close_delay) OVERRIDE {
422 // Use a low sample rate and large buffer size when testing otherwise the
423 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
424 // RunUntilIdle() will never terminate.
425 resampler_params_ = AudioParameters(
426 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
427 16000, 16, 1024);
428 resampler_ = new AudioOutputResampler(
429 &manager(), params_, resampler_params_, std::string(), close_delay);
432 virtual void OnStart() OVERRIDE {
433 // Let Start() run for a bit.
434 base::RunLoop run_loop;
435 message_loop_.PostDelayedTask(
436 FROM_HERE,
437 run_loop.QuitClosure(),
438 base::TimeDelta::FromMilliseconds(kStartRunTimeMs));
439 run_loop.Run();
442 protected:
443 AudioParameters resampler_params_;
444 scoped_refptr<AudioOutputResampler> resampler_;
447 TEST_F(AudioOutputProxyTest, CreateAndClose) {
448 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_);
449 proxy->Close();
452 TEST_F(AudioOutputResamplerTest, CreateAndClose) {
453 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
454 proxy->Close();
457 TEST_F(AudioOutputProxyTest, OpenAndClose) {
458 OpenAndClose(dispatcher_impl_);
461 TEST_F(AudioOutputResamplerTest, OpenAndClose) {
462 OpenAndClose(resampler_);
465 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
466 // if it doesn't start playing.
467 TEST_F(AudioOutputProxyTest, CreateAndWait) {
468 CreateAndWait(dispatcher_impl_);
471 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
472 // if it doesn't start playing.
473 TEST_F(AudioOutputResamplerTest, CreateAndWait) {
474 CreateAndWait(resampler_);
477 TEST_F(AudioOutputProxyTest, StartAndStop) {
478 StartAndStop(dispatcher_impl_);
481 TEST_F(AudioOutputResamplerTest, StartAndStop) {
482 StartAndStop(resampler_);
485 TEST_F(AudioOutputProxyTest, CloseAfterStop) {
486 CloseAfterStop(dispatcher_impl_);
489 TEST_F(AudioOutputResamplerTest, CloseAfterStop) {
490 CloseAfterStop(resampler_);
493 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_); }
495 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_); }
497 // Two streams: verify that second stream is allocated when the first
498 // starts playing.
499 TEST_F(AudioOutputProxyTest, OneStream_TwoPlays) {
500 OneStream_TwoPlays(dispatcher_impl_);
503 TEST_F(AudioOutputResamplerTest, OneStream_TwoPlays) {
504 OneStream_TwoPlays(resampler_);
507 // Two streams, both are playing. Dispatcher should not open a third stream.
508 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) {
509 TwoStreams_BothPlaying(dispatcher_impl_);
512 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) {
513 TwoStreams_BothPlaying(resampler_);
516 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_); }
518 // Start() method failed.
519 TEST_F(AudioOutputProxyTest, StartFailed) {
520 StartFailed(dispatcher_impl_);
523 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_); }
525 // Simulate AudioOutputStream::Create() failure with a low latency stream and
526 // ensure AudioOutputResampler falls back to the high latency path.
527 TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) {
528 MockAudioOutputStream stream(&manager_, params_);
529 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
530 .Times(2)
531 .WillOnce(Return(static_cast<AudioOutputStream*>(NULL)))
532 .WillRepeatedly(Return(&stream));
533 EXPECT_CALL(stream, Open())
534 .WillOnce(Return(true));
536 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
537 EXPECT_TRUE(proxy->Open());
538 CloseAndWaitForCloseTimer(proxy, &stream);
541 // Simulate AudioOutputStream::Open() failure with a low latency stream and
542 // ensure AudioOutputResampler falls back to the high latency path.
543 TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) {
544 MockAudioOutputStream failed_stream(&manager_, params_);
545 MockAudioOutputStream okay_stream(&manager_, params_);
546 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
547 .Times(2)
548 .WillOnce(Return(&failed_stream))
549 .WillRepeatedly(Return(&okay_stream));
550 EXPECT_CALL(failed_stream, Open())
551 .WillOnce(Return(false));
552 EXPECT_CALL(failed_stream, Close())
553 .Times(1);
554 EXPECT_CALL(okay_stream, Open())
555 .WillOnce(Return(true));
557 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
558 EXPECT_TRUE(proxy->Open());
559 CloseAndWaitForCloseTimer(proxy, &okay_stream);
562 // Simulate failures to open both the low latency and the fallback high latency
563 // stream and ensure AudioOutputResampler falls back to a fake stream.
564 TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) {
565 MockAudioOutputStream okay_stream(&manager_, params_);
567 // Only Windows has a high latency output driver that is not the same as the low
568 // latency path.
569 #if defined(OS_WIN)
570 static const int kFallbackCount = 2;
571 #else
572 static const int kFallbackCount = 1;
573 #endif
574 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
575 .Times(kFallbackCount)
576 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
578 // To prevent shared memory issues the sample rate and buffer size should
579 // match the input stream parameters.
580 EXPECT_CALL(manager(), MakeAudioOutputStream(AllOf(
581 testing::Property(&AudioParameters::format, AudioParameters::AUDIO_FAKE),
582 testing::Property(&AudioParameters::sample_rate, params_.sample_rate()),
583 testing::Property(
584 &AudioParameters::frames_per_buffer, params_.frames_per_buffer())),
586 .Times(1)
587 .WillOnce(Return(&okay_stream));
588 EXPECT_CALL(okay_stream, Open())
589 .WillOnce(Return(true));
591 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
592 EXPECT_TRUE(proxy->Open());
593 CloseAndWaitForCloseTimer(proxy, &okay_stream);
596 // Simulate failures to open both the low latency, the fallback high latency
597 // stream, and the fake audio output stream and ensure AudioOutputResampler
598 // terminates normally.
599 TEST_F(AudioOutputResamplerTest, AllFallbackFailed) {
600 // Only Windows has a high latency output driver that is not the same as the low
601 // latency path.
602 #if defined(OS_WIN)
603 static const int kFallbackCount = 3;
604 #else
605 static const int kFallbackCount = 2;
606 #endif
607 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
608 .Times(kFallbackCount)
609 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
611 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
612 EXPECT_FALSE(proxy->Open());
613 proxy->Close();
616 // Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls
617 // eventually followed by one which fails; root cause of http://crbug.com/150619
618 TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) {
619 MockAudioOutputStream stream1(&manager_, params_);
620 MockAudioOutputStream stream2(&manager_, params_);
622 // Setup the mock such that all three streams are successfully created.
623 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
624 .WillOnce(Return(&stream1))
625 .WillOnce(Return(&stream2))
626 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
628 // Stream1 should be able to successfully open and start.
629 EXPECT_CALL(stream1, Open())
630 .WillOnce(Return(true));
631 EXPECT_CALL(stream1, SetVolume(_))
632 .Times(1);
634 // Stream2 should also be able to successfully open and start.
635 EXPECT_CALL(stream2, Open())
636 .WillOnce(Return(true));
637 EXPECT_CALL(stream2, SetVolume(_))
638 .Times(1);
640 // Open and start the first proxy and stream.
641 AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_);
642 EXPECT_TRUE(proxy1->Open());
643 proxy1->Start(&callback_);
644 OnStart();
646 // Open and start the second proxy and stream.
647 AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_);
648 EXPECT_TRUE(proxy2->Open());
649 proxy2->Start(&callback_);
650 OnStart();
652 // Attempt to open the third stream which should fail.
653 AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_);
654 EXPECT_FALSE(proxy3->Open());
655 proxy3->Close();
657 // Perform the required Stop()/Close() shutdown dance for each proxy. Under
658 // the hood each proxy should correctly call CloseStream() if OpenStream()
659 // succeeded or not.
660 proxy2->Stop();
661 CloseAndWaitForCloseTimer(proxy2, &stream2);
663 proxy1->Stop();
664 CloseAndWaitForCloseTimer(proxy1, &stream1);
666 EXPECT_TRUE(stream1.stop_called());
667 EXPECT_TRUE(stream1.start_called());
668 EXPECT_TRUE(stream2.stop_called());
669 EXPECT_TRUE(stream2.start_called());
672 } // namespace media