Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / media / audio / audio_output_proxy_unittest.cc
blobb4afe5ae2323d88b06906404a387ddd4cc097e94
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 int OnMoreIOData(AudioBus* source, AudioBus* dest,
133 AudioBuffersState buffers_state) {
134 return OnMoreData(dest, buffers_state);
136 MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
139 } // namespace
141 namespace media {
143 class AudioOutputProxyTest : public testing::Test {
144 protected:
145 virtual void SetUp() {
146 EXPECT_CALL(manager_, GetTaskRunner())
147 .WillRepeatedly(Return(message_loop_.message_loop_proxy()));
148 EXPECT_CALL(manager_, GetWorkerTaskRunner())
149 .WillRepeatedly(Return(message_loop_.message_loop_proxy()));
150 // Use a low sample rate and large buffer size when testing otherwise the
151 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
152 // RunUntilIdle() will never terminate.
153 params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
154 CHANNEL_LAYOUT_STEREO, 8000, 16, 2048);
155 InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs));
158 virtual void TearDown() {
159 // This is necessary to free all proxy objects that have been
160 // closed by the test.
161 message_loop_.RunUntilIdle();
164 virtual void InitDispatcher(base::TimeDelta close_delay) {
165 dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(),
166 params_,
167 std::string(),
168 close_delay);
171 virtual void OnStart() {}
173 MockAudioManager& manager() {
174 return manager_;
177 void WaitForCloseTimer(MockAudioOutputStream* stream) {
178 base::RunLoop run_loop;
179 EXPECT_CALL(*stream, Close())
180 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
181 run_loop.Run();
184 void CloseAndWaitForCloseTimer(AudioOutputProxy* proxy,
185 MockAudioOutputStream* stream) {
186 // Close the stream and verify it doesn't happen immediately.
187 proxy->Close();
188 Mock::VerifyAndClear(stream);
190 // Wait for the actual close event to come from the close timer.
191 WaitForCloseTimer(stream);
194 // Basic Open() and Close() test.
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));
203 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
204 EXPECT_TRUE(proxy->Open());
205 CloseAndWaitForCloseTimer(proxy, &stream);
208 // Creates a stream, and then calls Start() and Stop().
209 void StartAndStop(AudioOutputDispatcher* dispatcher) {
210 MockAudioOutputStream stream(&manager_, params_);
212 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
213 .WillOnce(Return(&stream));
214 EXPECT_CALL(stream, Open())
215 .WillOnce(Return(true));
216 EXPECT_CALL(stream, SetVolume(_))
217 .Times(1);
219 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
220 EXPECT_TRUE(proxy->Open());
222 proxy->Start(&callback_);
223 OnStart();
224 proxy->Stop();
226 CloseAndWaitForCloseTimer(proxy, &stream);
227 EXPECT_TRUE(stream.stop_called());
228 EXPECT_TRUE(stream.start_called());
231 // Verify that the stream is closed after Stop() is called.
232 void CloseAfterStop(AudioOutputDispatcher* dispatcher) {
233 MockAudioOutputStream stream(&manager_, params_);
235 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
236 .WillOnce(Return(&stream));
237 EXPECT_CALL(stream, Open())
238 .WillOnce(Return(true));
239 EXPECT_CALL(stream, SetVolume(_))
240 .Times(1);
242 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
243 EXPECT_TRUE(proxy->Open());
245 proxy->Start(&callback_);
246 OnStart();
247 proxy->Stop();
249 // Wait for the close timer to fire after StopStream().
250 WaitForCloseTimer(&stream);
251 proxy->Close();
252 EXPECT_TRUE(stream.stop_called());
253 EXPECT_TRUE(stream.start_called());
256 // Create two streams, but don't start them. Only one device must be opened.
257 void TwoStreams(AudioOutputDispatcher* dispatcher) {
258 MockAudioOutputStream stream(&manager_, params_);
260 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
261 .WillOnce(Return(&stream));
262 EXPECT_CALL(stream, Open())
263 .WillOnce(Return(true));
265 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
266 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
267 EXPECT_TRUE(proxy1->Open());
268 EXPECT_TRUE(proxy2->Open());
269 proxy1->Close();
270 CloseAndWaitForCloseTimer(proxy2, &stream);
271 EXPECT_FALSE(stream.stop_called());
272 EXPECT_FALSE(stream.start_called());
275 // Open() method failed.
276 void OpenFailed(AudioOutputDispatcher* dispatcher) {
277 MockAudioOutputStream stream(&manager_, params_);
279 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
280 .WillOnce(Return(&stream));
281 EXPECT_CALL(stream, Open())
282 .WillOnce(Return(false));
283 EXPECT_CALL(stream, Close())
284 .Times(1);
286 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
287 EXPECT_FALSE(proxy->Open());
288 proxy->Close();
289 EXPECT_FALSE(stream.stop_called());
290 EXPECT_FALSE(stream.start_called());
293 void CreateAndWait(AudioOutputDispatcher* dispatcher) {
294 MockAudioOutputStream stream(&manager_, params_);
296 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
297 .WillOnce(Return(&stream));
298 EXPECT_CALL(stream, Open())
299 .WillOnce(Return(true));
301 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
302 EXPECT_TRUE(proxy->Open());
304 WaitForCloseTimer(&stream);
305 proxy->Close();
306 EXPECT_FALSE(stream.stop_called());
307 EXPECT_FALSE(stream.start_called());
310 void OneStream_TwoPlays(AudioOutputDispatcher* dispatcher) {
311 MockAudioOutputStream stream(&manager_, params_);
313 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
314 .WillOnce(Return(&stream));
316 EXPECT_CALL(stream, Open())
317 .WillOnce(Return(true));
318 EXPECT_CALL(stream, SetVolume(_))
319 .Times(2);
321 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
322 EXPECT_TRUE(proxy1->Open());
324 proxy1->Start(&callback_);
325 OnStart();
326 proxy1->Stop();
328 // The stream should now be idle and get reused by |proxy2|.
329 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
330 EXPECT_TRUE(proxy2->Open());
331 proxy2->Start(&callback_);
332 OnStart();
333 proxy2->Stop();
335 proxy1->Close();
336 CloseAndWaitForCloseTimer(proxy2, &stream);
337 EXPECT_TRUE(stream.stop_called());
338 EXPECT_TRUE(stream.start_called());
341 void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) {
342 MockAudioOutputStream stream1(&manager_, params_);
343 MockAudioOutputStream stream2(&manager_, params_);
345 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
346 .WillOnce(Return(&stream1))
347 .WillOnce(Return(&stream2));
349 EXPECT_CALL(stream1, Open())
350 .WillOnce(Return(true));
351 EXPECT_CALL(stream1, SetVolume(_))
352 .Times(1);
354 EXPECT_CALL(stream2, Open())
355 .WillOnce(Return(true));
356 EXPECT_CALL(stream2, SetVolume(_))
357 .Times(1);
359 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
360 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
361 EXPECT_TRUE(proxy1->Open());
362 EXPECT_TRUE(proxy2->Open());
364 proxy1->Start(&callback_);
365 proxy2->Start(&callback_);
366 OnStart();
367 proxy1->Stop();
368 CloseAndWaitForCloseTimer(proxy1, &stream1);
370 proxy2->Stop();
371 CloseAndWaitForCloseTimer(proxy2, &stream2);
373 EXPECT_TRUE(stream1.stop_called());
374 EXPECT_TRUE(stream1.start_called());
375 EXPECT_TRUE(stream2.stop_called());
376 EXPECT_TRUE(stream2.start_called());
379 void StartFailed(AudioOutputDispatcher* dispatcher) {
380 MockAudioOutputStream stream(&manager_, params_);
382 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
383 .WillOnce(Return(&stream));
384 EXPECT_CALL(stream, Open())
385 .WillOnce(Return(true));
387 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
388 EXPECT_TRUE(proxy->Open());
390 WaitForCloseTimer(&stream);
392 // |stream| is closed at this point. Start() should reopen it again.
393 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
394 .Times(2)
395 .WillRepeatedly(Return(reinterpret_cast<AudioOutputStream*>(NULL)));
397 EXPECT_CALL(callback_, OnError(_))
398 .Times(2);
400 proxy->Start(&callback_);
402 // Double Start() in the error case should be allowed since it's possible a
403 // callback may not have had time to process the OnError() in between.
404 proxy->Stop();
405 proxy->Start(&callback_);
407 Mock::VerifyAndClear(&callback_);
409 proxy->Close();
412 base::MessageLoop message_loop_;
413 scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_;
414 MockAudioManager manager_;
415 MockAudioSourceCallback callback_;
416 AudioParameters params_;
419 class AudioOutputResamplerTest : public AudioOutputProxyTest {
420 public:
421 virtual void TearDown() {
422 AudioOutputProxyTest::TearDown();
425 virtual void InitDispatcher(base::TimeDelta close_delay) OVERRIDE {
426 // Use a low sample rate and large buffer size when testing otherwise the
427 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
428 // RunUntilIdle() will never terminate.
429 resampler_params_ = AudioParameters(
430 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
431 16000, 16, 1024);
432 resampler_ = new AudioOutputResampler(
433 &manager(), params_, resampler_params_, std::string(), close_delay);
436 virtual void OnStart() OVERRIDE {
437 // Let Start() run for a bit.
438 base::RunLoop run_loop;
439 message_loop_.PostDelayedTask(
440 FROM_HERE,
441 run_loop.QuitClosure(),
442 base::TimeDelta::FromMilliseconds(kStartRunTimeMs));
443 run_loop.Run();
446 protected:
447 AudioParameters resampler_params_;
448 scoped_refptr<AudioOutputResampler> resampler_;
451 TEST_F(AudioOutputProxyTest, CreateAndClose) {
452 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_);
453 proxy->Close();
456 TEST_F(AudioOutputResamplerTest, CreateAndClose) {
457 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
458 proxy->Close();
461 TEST_F(AudioOutputProxyTest, OpenAndClose) {
462 OpenAndClose(dispatcher_impl_);
465 TEST_F(AudioOutputResamplerTest, OpenAndClose) {
466 OpenAndClose(resampler_);
469 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
470 // if it doesn't start playing.
471 TEST_F(AudioOutputProxyTest, CreateAndWait) {
472 CreateAndWait(dispatcher_impl_);
475 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
476 // if it doesn't start playing.
477 TEST_F(AudioOutputResamplerTest, CreateAndWait) {
478 CreateAndWait(resampler_);
481 TEST_F(AudioOutputProxyTest, StartAndStop) {
482 StartAndStop(dispatcher_impl_);
485 TEST_F(AudioOutputResamplerTest, StartAndStop) {
486 StartAndStop(resampler_);
489 TEST_F(AudioOutputProxyTest, CloseAfterStop) {
490 CloseAfterStop(dispatcher_impl_);
493 TEST_F(AudioOutputResamplerTest, CloseAfterStop) {
494 CloseAfterStop(resampler_);
497 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_); }
499 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_); }
501 // Two streams: verify that second stream is allocated when the first
502 // starts playing.
503 TEST_F(AudioOutputProxyTest, OneStream_TwoPlays) {
504 OneStream_TwoPlays(dispatcher_impl_);
507 TEST_F(AudioOutputResamplerTest, OneStream_TwoPlays) {
508 OneStream_TwoPlays(resampler_);
511 // Two streams, both are playing. Dispatcher should not open a third stream.
512 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) {
513 TwoStreams_BothPlaying(dispatcher_impl_);
516 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) {
517 TwoStreams_BothPlaying(resampler_);
520 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_); }
522 // Start() method failed.
523 TEST_F(AudioOutputProxyTest, StartFailed) {
524 StartFailed(dispatcher_impl_);
527 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_); }
529 // Simulate AudioOutputStream::Create() failure with a low latency stream and
530 // ensure AudioOutputResampler falls back to the high latency path.
531 TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) {
532 MockAudioOutputStream stream(&manager_, params_);
533 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
534 .Times(2)
535 .WillOnce(Return(static_cast<AudioOutputStream*>(NULL)))
536 .WillRepeatedly(Return(&stream));
537 EXPECT_CALL(stream, Open())
538 .WillOnce(Return(true));
540 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
541 EXPECT_TRUE(proxy->Open());
542 CloseAndWaitForCloseTimer(proxy, &stream);
545 // Simulate AudioOutputStream::Open() failure with a low latency stream and
546 // ensure AudioOutputResampler falls back to the high latency path.
547 TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) {
548 MockAudioOutputStream failed_stream(&manager_, params_);
549 MockAudioOutputStream okay_stream(&manager_, params_);
550 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
551 .Times(2)
552 .WillOnce(Return(&failed_stream))
553 .WillRepeatedly(Return(&okay_stream));
554 EXPECT_CALL(failed_stream, Open())
555 .WillOnce(Return(false));
556 EXPECT_CALL(failed_stream, Close())
557 .Times(1);
558 EXPECT_CALL(okay_stream, Open())
559 .WillOnce(Return(true));
561 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
562 EXPECT_TRUE(proxy->Open());
563 CloseAndWaitForCloseTimer(proxy, &okay_stream);
566 // Simulate failures to open both the low latency and the fallback high latency
567 // stream and ensure AudioOutputResampler falls back to a fake stream.
568 TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) {
569 MockAudioOutputStream okay_stream(&manager_, params_);
571 // Only Windows has a high latency output driver that is not the same as the low
572 // latency path.
573 #if defined(OS_WIN)
574 static const int kFallbackCount = 2;
575 #else
576 static const int kFallbackCount = 1;
577 #endif
578 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
579 .Times(kFallbackCount)
580 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
582 // To prevent shared memory issues the sample rate and buffer size should
583 // match the input stream parameters.
584 EXPECT_CALL(manager(), MakeAudioOutputStream(AllOf(
585 testing::Property(&AudioParameters::format, AudioParameters::AUDIO_FAKE),
586 testing::Property(&AudioParameters::sample_rate, params_.sample_rate()),
587 testing::Property(
588 &AudioParameters::frames_per_buffer, params_.frames_per_buffer())),
590 .Times(1)
591 .WillOnce(Return(&okay_stream));
592 EXPECT_CALL(okay_stream, Open())
593 .WillOnce(Return(true));
595 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
596 EXPECT_TRUE(proxy->Open());
597 CloseAndWaitForCloseTimer(proxy, &okay_stream);
600 // Simulate failures to open both the low latency, the fallback high latency
601 // stream, and the fake audio output stream and ensure AudioOutputResampler
602 // terminates normally.
603 TEST_F(AudioOutputResamplerTest, AllFallbackFailed) {
604 // Only Windows has a high latency output driver that is not the same as the low
605 // latency path.
606 #if defined(OS_WIN)
607 static const int kFallbackCount = 3;
608 #else
609 static const int kFallbackCount = 2;
610 #endif
611 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
612 .Times(kFallbackCount)
613 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
615 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
616 EXPECT_FALSE(proxy->Open());
617 proxy->Close();
620 // Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls
621 // eventually followed by one which fails; root cause of http://crbug.com/150619
622 TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) {
623 MockAudioOutputStream stream1(&manager_, params_);
624 MockAudioOutputStream stream2(&manager_, params_);
626 // Setup the mock such that all three streams are successfully created.
627 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
628 .WillOnce(Return(&stream1))
629 .WillOnce(Return(&stream2))
630 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
632 // Stream1 should be able to successfully open and start.
633 EXPECT_CALL(stream1, Open())
634 .WillOnce(Return(true));
635 EXPECT_CALL(stream1, SetVolume(_))
636 .Times(1);
638 // Stream2 should also be able to successfully open and start.
639 EXPECT_CALL(stream2, Open())
640 .WillOnce(Return(true));
641 EXPECT_CALL(stream2, SetVolume(_))
642 .Times(1);
644 // Open and start the first proxy and stream.
645 AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_);
646 EXPECT_TRUE(proxy1->Open());
647 proxy1->Start(&callback_);
648 OnStart();
650 // Open and start the second proxy and stream.
651 AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_);
652 EXPECT_TRUE(proxy2->Open());
653 proxy2->Start(&callback_);
654 OnStart();
656 // Attempt to open the third stream which should fail.
657 AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_);
658 EXPECT_FALSE(proxy3->Open());
659 proxy3->Close();
661 // Perform the required Stop()/Close() shutdown dance for each proxy. Under
662 // the hood each proxy should correctly call CloseStream() if OpenStream()
663 // succeeded or not.
664 proxy2->Stop();
665 CloseAndWaitForCloseTimer(proxy2, &stream2);
667 proxy1->Stop();
668 CloseAndWaitForCloseTimer(proxy1, &stream1);
670 EXPECT_TRUE(stream1.stop_called());
671 EXPECT_TRUE(stream1.start_called());
672 EXPECT_TRUE(stream2.stop_called());
673 EXPECT_TRUE(stream2.start_called());
676 } // namespace media