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.
7 #include "base/message_loop/message_loop.h"
8 #include "base/message_loop/message_loop_proxy.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_output_stream.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
19 using ::testing::AllOf;
20 using ::testing::DoAll;
21 using ::testing::Field;
22 using ::testing::Mock;
23 using ::testing::NotNull;
24 using ::testing::Return;
25 using ::testing::SetArrayArgument;
26 using media::AudioBus;
27 using media::AudioBuffersState;
28 using media::AudioInputStream;
29 using media::AudioManager;
30 using media::AudioManagerBase;
31 using media::AudioOutputDispatcher;
32 using media::AudioOutputProxy;
33 using media::AudioOutputStream;
34 using media::AudioParameters;
35 using media::FakeAudioOutputStream;
39 static const int kTestCloseDelayMs = 100;
41 // Used in the test where we don't want a stream to be closed unexpectedly.
42 static const int kTestBigCloseDelaySeconds = 1000;
44 // Delay between callbacks to AudioSourceCallback::OnMoreData.
45 static const int kOnMoreDataCallbackDelayMs = 10;
47 // Let start run long enough for many OnMoreData callbacks to occur.
48 static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10;
50 class MockAudioOutputStream : public AudioOutputStream {
52 MockAudioOutputStream(AudioManagerBase* manager,
53 const AudioParameters& params)
54 : start_called_(false),
58 FakeAudioOutputStream::MakeFakeStream(manager, params_)) {
61 void Start(AudioSourceCallback* callback) {
63 fake_output_stream_->Start(callback);
68 fake_output_stream_->Stop();
71 ~MockAudioOutputStream() {}
73 bool start_called() { return start_called_; }
74 bool stop_called() { return stop_called_; }
76 MOCK_METHOD0(Open, bool());
77 MOCK_METHOD1(SetVolume, void(double volume));
78 MOCK_METHOD1(GetVolume, void(double* volume));
79 MOCK_METHOD0(Close, void());
84 AudioParameters params_;
85 scoped_ptr<AudioOutputStream> fake_output_stream_;
88 class MockAudioManager : public AudioManagerBase {
91 virtual ~MockAudioManager() {
95 MOCK_METHOD0(HasAudioOutputDevices, bool());
96 MOCK_METHOD0(HasAudioInputDevices, bool());
97 MOCK_METHOD0(GetAudioInputDeviceModel, string16());
98 MOCK_METHOD3(MakeAudioOutputStream, AudioOutputStream*(
99 const AudioParameters& params,
100 const std::string& device_id,
101 const std::string& input_device_id));
102 MOCK_METHOD3(MakeAudioOutputStreamProxy, AudioOutputStream*(
103 const AudioParameters& params,
104 const std::string& device_id,
105 const std::string& input_device_id));
106 MOCK_METHOD2(MakeAudioInputStream, AudioInputStream*(
107 const AudioParameters& params, const std::string& device_id));
108 MOCK_METHOD0(ShowAudioInputSettings, void());
109 MOCK_METHOD0(GetMessageLoop, scoped_refptr<base::MessageLoopProxy>());
110 MOCK_METHOD0(GetWorkerLoop, scoped_refptr<base::MessageLoopProxy>());
111 MOCK_METHOD1(GetAudioInputDeviceNames, void(
112 media::AudioDeviceNames* device_name));
114 MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*(
115 const AudioParameters& params));
116 MOCK_METHOD3(MakeLowLatencyOutputStream, AudioOutputStream*(
117 const AudioParameters& params, const std::string& device_id,
118 const std::string& input_device_id));
119 MOCK_METHOD2(MakeLinearInputStream, AudioInputStream*(
120 const AudioParameters& params, const std::string& device_id));
121 MOCK_METHOD2(MakeLowLatencyInputStream, AudioInputStream*(
122 const AudioParameters& params, const std::string& device_id));
123 MOCK_METHOD2(GetPreferredOutputStreamParameters, AudioParameters(
124 const std::string& device_id, const AudioParameters& params));
127 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
129 int OnMoreData(AudioBus* audio_bus, AudioBuffersState buffers_state) {
131 return audio_bus->frames();
133 int OnMoreIOData(AudioBus* source, AudioBus* dest,
134 AudioBuffersState buffers_state) {
135 return OnMoreData(dest, buffers_state);
137 MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
144 class AudioOutputProxyTest : public testing::Test {
146 virtual void SetUp() {
147 EXPECT_CALL(manager_, GetMessageLoop())
148 .WillRepeatedly(Return(message_loop_.message_loop_proxy()));
149 EXPECT_CALL(manager_, GetWorkerLoop())
150 .WillRepeatedly(Return(message_loop_.message_loop_proxy()));
151 InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs));
154 virtual void TearDown() {
155 // All paused proxies should have been closed at this point.
156 EXPECT_EQ(0u, dispatcher_impl_->paused_proxies_);
158 // This is necessary to free all proxy objects that have been
159 // closed by the test.
160 message_loop_.RunUntilIdle();
163 virtual void InitDispatcher(base::TimeDelta close_delay) {
164 // Use a low sample rate and large buffer size when testing otherwise the
165 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
166 // RunUntilIdle() will never terminate.
167 params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
168 CHANNEL_LAYOUT_STEREO, 8000, 16, 2048);
169 dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(),
175 // Necessary to know how long the dispatcher will wait before posting
177 pause_delay_ = dispatcher_impl_->pause_delay_;
180 virtual void OnStart() {}
182 MockAudioManager& manager() {
186 // Wait for the close timer to fire.
187 void WaitForCloseTimer(const int timer_delay_ms) {
188 message_loop_.RunUntilIdle(); // OpenTask() may reset the timer.
189 base::PlatformThread::Sleep(
190 base::TimeDelta::FromMilliseconds(timer_delay_ms) * 2);
191 message_loop_.RunUntilIdle();
194 // Methods that do actual tests.
195 void OpenAndClose(AudioOutputDispatcher* dispatcher) {
196 MockAudioOutputStream stream(&manager_, params_);
198 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
199 .WillOnce(Return(&stream));
200 EXPECT_CALL(stream, Open())
201 .WillOnce(Return(true));
202 EXPECT_CALL(stream, Close())
205 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
206 EXPECT_TRUE(proxy->Open());
208 WaitForCloseTimer(kTestCloseDelayMs);
211 // Create a stream, and then calls Start() and Stop().
212 void StartAndStop(AudioOutputDispatcher* dispatcher) {
213 MockAudioOutputStream stream(&manager_, params_);
215 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
216 .WillOnce(Return(&stream));
217 EXPECT_CALL(stream, Open())
218 .WillOnce(Return(true));
219 EXPECT_CALL(stream, SetVolume(_))
221 EXPECT_CALL(stream, Close())
224 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
225 EXPECT_TRUE(proxy->Open());
227 proxy->Start(&callback_);
232 WaitForCloseTimer(kTestCloseDelayMs);
233 EXPECT_TRUE(stream.stop_called());
234 EXPECT_TRUE(stream.start_called());
237 // Verify that the stream is closed after Stop is called.
238 void CloseAfterStop(AudioOutputDispatcher* dispatcher) {
239 MockAudioOutputStream stream(&manager_, params_);
241 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
242 .WillOnce(Return(&stream));
243 EXPECT_CALL(stream, Open())
244 .WillOnce(Return(true));
245 EXPECT_CALL(stream, SetVolume(_))
247 EXPECT_CALL(stream, Close())
250 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
251 EXPECT_TRUE(proxy->Open());
253 proxy->Start(&callback_);
257 // Wait for StopStream() to post StopStreamTask().
258 base::PlatformThread::Sleep(pause_delay_ * 2);
259 WaitForCloseTimer(kTestCloseDelayMs);
261 // Verify expectation before calling Close().
262 Mock::VerifyAndClear(&stream);
265 EXPECT_TRUE(stream.stop_called());
266 EXPECT_TRUE(stream.start_called());
269 // Create two streams, but don't start them. Only one device must be open.
270 void TwoStreams(AudioOutputDispatcher* dispatcher) {
271 MockAudioOutputStream stream(&manager_, params_);
273 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
274 .WillOnce(Return(&stream));
275 EXPECT_CALL(stream, Open())
276 .WillOnce(Return(true));
277 EXPECT_CALL(stream, Close())
280 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
281 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
282 EXPECT_TRUE(proxy1->Open());
283 EXPECT_TRUE(proxy2->Open());
286 WaitForCloseTimer(kTestCloseDelayMs);
287 EXPECT_FALSE(stream.stop_called());
288 EXPECT_FALSE(stream.start_called());
291 // Open() method failed.
292 void OpenFailed(AudioOutputDispatcher* dispatcher) {
293 MockAudioOutputStream stream(&manager_, params_);
295 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
296 .WillOnce(Return(&stream));
297 EXPECT_CALL(stream, Open())
298 .WillOnce(Return(false));
299 EXPECT_CALL(stream, Close())
302 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
303 EXPECT_FALSE(proxy->Open());
305 WaitForCloseTimer(kTestCloseDelayMs);
306 EXPECT_FALSE(stream.stop_called());
307 EXPECT_FALSE(stream.start_called());
310 void CreateAndWait(AudioOutputDispatcher* dispatcher) {
311 MockAudioOutputStream stream(&manager_, params_);
313 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
314 .WillOnce(Return(&stream));
315 EXPECT_CALL(stream, Open())
316 .WillOnce(Return(true));
317 EXPECT_CALL(stream, Close())
320 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
321 EXPECT_TRUE(proxy->Open());
324 base::PlatformThread::Sleep(
325 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2);
326 message_loop_.RunUntilIdle();
328 // Verify expectation before calling Close().
329 Mock::VerifyAndClear(&stream);
332 EXPECT_FALSE(stream.stop_called());
333 EXPECT_FALSE(stream.start_called());
336 void TwoStreams_OnePlaying(AudioOutputDispatcher* dispatcher) {
337 MockAudioOutputStream stream1(&manager_, params_);
338 MockAudioOutputStream stream2(&manager_, params_);
340 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
341 .WillOnce(Return(&stream1))
342 .WillOnce(Return(&stream2));
344 EXPECT_CALL(stream1, Open())
345 .WillOnce(Return(true));
346 EXPECT_CALL(stream1, SetVolume(_))
348 EXPECT_CALL(stream1, Close())
351 EXPECT_CALL(stream2, Open())
352 .WillOnce(Return(true));
353 EXPECT_CALL(stream2, Close())
356 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
357 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
358 EXPECT_TRUE(proxy1->Open());
360 proxy1->Start(&callback_);
361 EXPECT_TRUE(proxy2->Open());
362 message_loop_.RunUntilIdle();
368 EXPECT_TRUE(stream1.stop_called());
369 EXPECT_TRUE(stream1.start_called());
370 EXPECT_FALSE(stream2.stop_called());
371 EXPECT_FALSE(stream2.start_called());
374 void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) {
375 MockAudioOutputStream stream1(&manager_, params_);
376 MockAudioOutputStream stream2(&manager_, params_);
378 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
379 .WillOnce(Return(&stream1))
380 .WillOnce(Return(&stream2));
382 EXPECT_CALL(stream1, Open())
383 .WillOnce(Return(true));
384 EXPECT_CALL(stream1, SetVolume(_))
386 EXPECT_CALL(stream1, Close())
389 EXPECT_CALL(stream2, Open())
390 .WillOnce(Return(true));
391 EXPECT_CALL(stream2, SetVolume(_))
393 EXPECT_CALL(stream2, Close())
396 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
397 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
398 EXPECT_TRUE(proxy1->Open());
399 EXPECT_TRUE(proxy2->Open());
401 proxy1->Start(&callback_);
402 proxy2->Start(&callback_);
409 EXPECT_TRUE(stream1.stop_called());
410 EXPECT_TRUE(stream1.start_called());
411 EXPECT_TRUE(stream2.stop_called());
412 EXPECT_TRUE(stream2.start_called());
415 void StartFailed(AudioOutputDispatcher* dispatcher) {
416 MockAudioOutputStream stream(&manager_, params_);
418 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
419 .WillOnce(Return(&stream));
420 EXPECT_CALL(stream, Open())
421 .WillOnce(Return(true));
422 EXPECT_CALL(stream, Close())
425 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
426 EXPECT_TRUE(proxy->Open());
429 base::PlatformThread::Sleep(
430 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2);
431 message_loop_.RunUntilIdle();
433 // Verify expectation before calling Close().
434 Mock::VerifyAndClear(&stream);
436 // |stream| is closed at this point. Start() should reopen it again.
437 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
439 .WillRepeatedly(Return(reinterpret_cast<AudioOutputStream*>(NULL)));
441 EXPECT_CALL(callback_, OnError(_))
444 proxy->Start(&callback_);
446 // Double Start() in the error case should be allowed since it's possible a
447 // callback may not have had time to process the OnError() in between.
449 proxy->Start(&callback_);
451 Mock::VerifyAndClear(&callback_);
456 base::MessageLoop message_loop_;
457 scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_;
458 base::TimeDelta pause_delay_;
459 MockAudioManager manager_;
460 MockAudioSourceCallback callback_;
461 AudioParameters params_;
464 class AudioOutputResamplerTest : public AudioOutputProxyTest {
466 virtual void TearDown() {
467 AudioOutputProxyTest::TearDown();
470 virtual void InitDispatcher(base::TimeDelta close_delay) OVERRIDE {
471 AudioOutputProxyTest::InitDispatcher(close_delay);
472 // Use a low sample rate and large buffer size when testing otherwise the
473 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
474 // RunUntilIdle() will never terminate.
475 resampler_params_ = AudioParameters(
476 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
478 resampler_ = new AudioOutputResampler(
479 &manager(), params_, resampler_params_, std::string(), std::string(),
483 virtual void OnStart() OVERRIDE {
484 // Let start run for a bit.
485 message_loop_.RunUntilIdle();
486 base::PlatformThread::Sleep(
487 base::TimeDelta::FromMilliseconds(kStartRunTimeMs));
491 AudioParameters resampler_params_;
492 scoped_refptr<AudioOutputResampler> resampler_;
495 TEST_F(AudioOutputProxyTest, CreateAndClose) {
496 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_.get());
500 TEST_F(AudioOutputResamplerTest, CreateAndClose) {
501 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
505 TEST_F(AudioOutputProxyTest, OpenAndClose) {
506 OpenAndClose(dispatcher_impl_.get());
509 TEST_F(AudioOutputResamplerTest, OpenAndClose) {
510 OpenAndClose(resampler_.get());
513 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
514 // if it doesn't start playing.
515 TEST_F(AudioOutputProxyTest, CreateAndWait) {
516 CreateAndWait(dispatcher_impl_.get());
519 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
520 // if it doesn't start playing.
521 TEST_F(AudioOutputResamplerTest, CreateAndWait) {
522 CreateAndWait(resampler_.get());
525 TEST_F(AudioOutputProxyTest, StartAndStop) {
526 StartAndStop(dispatcher_impl_.get());
529 TEST_F(AudioOutputResamplerTest, StartAndStop) {
530 StartAndStop(resampler_.get());
533 TEST_F(AudioOutputProxyTest, CloseAfterStop) {
534 CloseAfterStop(dispatcher_impl_.get());
537 TEST_F(AudioOutputResamplerTest, CloseAfterStop) {
538 CloseAfterStop(resampler_.get());
541 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_.get()); }
543 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_.get()); }
545 // Two streams: verify that second stream is allocated when the first
547 TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) {
548 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
549 TwoStreams_OnePlaying(dispatcher_impl_.get());
552 TEST_F(AudioOutputResamplerTest, TwoStreams_OnePlaying) {
553 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
554 TwoStreams_OnePlaying(resampler_.get());
557 // Two streams, both are playing. Dispatcher should not open a third stream.
558 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) {
559 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
560 TwoStreams_BothPlaying(dispatcher_impl_.get());
563 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) {
564 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
565 TwoStreams_BothPlaying(resampler_.get());
568 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_.get()); }
570 // Start() method failed.
571 TEST_F(AudioOutputProxyTest, StartFailed) {
572 StartFailed(dispatcher_impl_.get());
575 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_.get()); }
577 // Simulate AudioOutputStream::Create() failure with a low latency stream and
578 // ensure AudioOutputResampler falls back to the high latency path.
579 TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) {
580 MockAudioOutputStream stream(&manager_, params_);
581 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
583 .WillOnce(Return(static_cast<AudioOutputStream*>(NULL)))
584 .WillRepeatedly(Return(&stream));
585 EXPECT_CALL(stream, Open())
586 .WillOnce(Return(true));
587 EXPECT_CALL(stream, Close())
590 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
591 EXPECT_TRUE(proxy->Open());
593 WaitForCloseTimer(kTestCloseDelayMs);
596 // Simulate AudioOutputStream::Open() failure with a low latency stream and
597 // ensure AudioOutputResampler falls back to the high latency path.
598 TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) {
599 MockAudioOutputStream failed_stream(&manager_, params_);
600 MockAudioOutputStream okay_stream(&manager_, params_);
601 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
603 .WillOnce(Return(&failed_stream))
604 .WillRepeatedly(Return(&okay_stream));
605 EXPECT_CALL(failed_stream, Open())
606 .WillOnce(Return(false));
607 EXPECT_CALL(failed_stream, Close())
609 EXPECT_CALL(okay_stream, Open())
610 .WillOnce(Return(true));
611 EXPECT_CALL(okay_stream, Close())
614 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
615 EXPECT_TRUE(proxy->Open());
617 WaitForCloseTimer(kTestCloseDelayMs);
620 // Simulate failures to open both the low latency and the fallback high latency
621 // stream and ensure AudioOutputResampler falls back to a fake stream.
622 TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) {
623 MockAudioOutputStream okay_stream(&manager_, params_);
625 // Only Windows has a high latency output driver that is not the same as the low
628 static const int kFallbackCount = 2;
630 static const int kFallbackCount = 1;
632 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
633 .Times(kFallbackCount)
634 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
636 // To prevent shared memory issues the sample rate and buffer size should
637 // match the input stream parameters.
638 EXPECT_CALL(manager(), MakeAudioOutputStream(AllOf(
639 testing::Property(&AudioParameters::format, AudioParameters::AUDIO_FAKE),
640 testing::Property(&AudioParameters::sample_rate, params_.sample_rate()),
642 &AudioParameters::frames_per_buffer, params_.frames_per_buffer())),
645 .WillOnce(Return(&okay_stream));
646 EXPECT_CALL(okay_stream, Open())
647 .WillOnce(Return(true));
648 EXPECT_CALL(okay_stream, Close())
651 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
652 EXPECT_TRUE(proxy->Open());
654 WaitForCloseTimer(kTestCloseDelayMs);
657 // Simulate failures to open both the low latency, the fallback high latency
658 // stream, and the fake audio output stream and ensure AudioOutputResampler
659 // terminates normally.
660 TEST_F(AudioOutputResamplerTest, AllFallbackFailed) {
661 // Only Windows has a high latency output driver that is not the same as the low
664 static const int kFallbackCount = 3;
666 static const int kFallbackCount = 2;
668 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
669 .Times(kFallbackCount)
670 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
672 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
673 EXPECT_FALSE(proxy->Open());
675 WaitForCloseTimer(kTestCloseDelayMs);
678 // Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls
679 // eventually followed by one which fails; root cause of http://crbug.com/150619
680 TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) {
681 MockAudioOutputStream stream1(&manager_, params_);
682 MockAudioOutputStream stream2(&manager_, params_);
683 MockAudioOutputStream stream3(&manager_, params_);
685 // Setup the mock such that all three streams are successfully created.
686 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
687 .WillOnce(Return(&stream1))
688 .WillOnce(Return(&stream2))
689 .WillOnce(Return(&stream3))
690 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
692 // Stream1 should be able to successfully open and start.
693 EXPECT_CALL(stream1, Open())
694 .WillOnce(Return(true));
695 EXPECT_CALL(stream1, Close())
697 EXPECT_CALL(stream1, SetVolume(_))
700 // Stream2 should also be able to successfully open and start.
701 EXPECT_CALL(stream2, Open())
702 .WillOnce(Return(true));
703 EXPECT_CALL(stream2, Close())
705 EXPECT_CALL(stream2, SetVolume(_))
708 // Stream3 should fail on Open() (yet still be closed since
709 // MakeAudioOutputStream returned a valid AudioOutputStream object).
710 EXPECT_CALL(stream3, Open())
711 .WillOnce(Return(false));
712 EXPECT_CALL(stream3, Close())
715 // Open and start the first proxy and stream.
716 AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_.get());
717 EXPECT_TRUE(proxy1->Open());
718 proxy1->Start(&callback_);
721 // Open and start the second proxy and stream.
722 AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_.get());
723 EXPECT_TRUE(proxy2->Open());
724 proxy2->Start(&callback_);
727 // Attempt to open the third stream which should fail.
728 AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_.get());
729 EXPECT_FALSE(proxy3->Open());
731 // Perform the required Stop()/Close() shutdown dance for each proxy. Under
732 // the hood each proxy should correctly call CloseStream() if OpenStream()
741 // Wait for all of the messages to fly and then verify stream behavior.
742 WaitForCloseTimer(kTestCloseDelayMs);
743 EXPECT_TRUE(stream1.stop_called());
744 EXPECT_TRUE(stream1.start_called());
745 EXPECT_TRUE(stream2.stop_called());
746 EXPECT_TRUE(stream2.start_called());
747 EXPECT_FALSE(stream3.stop_called());
748 EXPECT_FALSE(stream3.start_called());