- add sources.
[platform/framework/web/crosswalk.git] / src / media / audio / audio_output_proxy_unittest.cc
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.
4
5 #include <string>
6
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"
17
18 using ::testing::_;
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;
36
37 namespace {
38
39 static const int kTestCloseDelayMs = 100;
40
41 // Used in the test where we don't want a stream to be closed unexpectedly.
42 static const int kTestBigCloseDelaySeconds = 1000;
43
44 // Delay between callbacks to AudioSourceCallback::OnMoreData.
45 static const int kOnMoreDataCallbackDelayMs = 10;
46
47 // Let start run long enough for many OnMoreData callbacks to occur.
48 static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10;
49
50 class MockAudioOutputStream : public AudioOutputStream {
51  public:
52   MockAudioOutputStream(AudioManagerBase* manager,
53                         const AudioParameters& params)
54       : start_called_(false),
55         stop_called_(false),
56         params_(params),
57         fake_output_stream_(
58             FakeAudioOutputStream::MakeFakeStream(manager, params_)) {
59   }
60
61   void Start(AudioSourceCallback* callback) {
62     start_called_ = true;
63     fake_output_stream_->Start(callback);
64   }
65
66   void Stop() {
67     stop_called_ = true;
68     fake_output_stream_->Stop();
69   }
70
71   ~MockAudioOutputStream() {}
72
73   bool start_called() { return start_called_; }
74   bool stop_called() { return stop_called_; }
75
76   MOCK_METHOD0(Open, bool());
77   MOCK_METHOD1(SetVolume, void(double volume));
78   MOCK_METHOD1(GetVolume, void(double* volume));
79   MOCK_METHOD0(Close, void());
80
81  private:
82   bool start_called_;
83   bool stop_called_;
84   AudioParameters params_;
85   scoped_ptr<AudioOutputStream> fake_output_stream_;
86 };
87
88 class MockAudioManager : public AudioManagerBase {
89  public:
90   MockAudioManager() {}
91   virtual ~MockAudioManager() {
92     Shutdown();
93   }
94
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));
113
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));
125 };
126
127 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
128  public:
129   int OnMoreData(AudioBus* audio_bus, AudioBuffersState buffers_state) {
130     audio_bus->Zero();
131     return audio_bus->frames();
132   }
133   int OnMoreIOData(AudioBus* source, AudioBus* dest,
134                    AudioBuffersState buffers_state) {
135     return OnMoreData(dest, buffers_state);
136   }
137   MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
138 };
139
140 }  // namespace
141
142 namespace media {
143
144 class AudioOutputProxyTest : public testing::Test {
145  protected:
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));
152   }
153
154   virtual void TearDown() {
155     // All paused proxies should have been closed at this point.
156     EXPECT_EQ(0u, dispatcher_impl_->paused_proxies_);
157
158     // This is necessary to free all proxy objects that have been
159     // closed by the test.
160     message_loop_.RunUntilIdle();
161   }
162
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(),
170                                                      params_,
171                                                      std::string(),
172                                                      std::string(),
173                                                      close_delay);
174
175     // Necessary to know how long the dispatcher will wait before posting
176     // StopStreamTask.
177     pause_delay_ = dispatcher_impl_->pause_delay_;
178   }
179
180   virtual void OnStart() {}
181
182   MockAudioManager& manager() {
183     return manager_;
184   }
185
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();
192   }
193
194   // Methods that do actual tests.
195   void OpenAndClose(AudioOutputDispatcher* dispatcher) {
196     MockAudioOutputStream stream(&manager_, params_);
197
198     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
199         .WillOnce(Return(&stream));
200     EXPECT_CALL(stream, Open())
201         .WillOnce(Return(true));
202     EXPECT_CALL(stream, Close())
203         .Times(1);
204
205     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
206     EXPECT_TRUE(proxy->Open());
207     proxy->Close();
208     WaitForCloseTimer(kTestCloseDelayMs);
209   }
210
211   // Create a stream, and then calls Start() and Stop().
212   void StartAndStop(AudioOutputDispatcher* dispatcher) {
213     MockAudioOutputStream stream(&manager_, params_);
214
215     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
216         .WillOnce(Return(&stream));
217     EXPECT_CALL(stream, Open())
218         .WillOnce(Return(true));
219     EXPECT_CALL(stream, SetVolume(_))
220         .Times(1);
221     EXPECT_CALL(stream, Close())
222         .Times(1);
223
224     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
225     EXPECT_TRUE(proxy->Open());
226
227     proxy->Start(&callback_);
228     OnStart();
229     proxy->Stop();
230
231     proxy->Close();
232     WaitForCloseTimer(kTestCloseDelayMs);
233     EXPECT_TRUE(stream.stop_called());
234     EXPECT_TRUE(stream.start_called());
235   }
236
237   // Verify that the stream is closed after Stop is called.
238   void CloseAfterStop(AudioOutputDispatcher* dispatcher) {
239     MockAudioOutputStream stream(&manager_, params_);
240
241     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
242         .WillOnce(Return(&stream));
243     EXPECT_CALL(stream, Open())
244         .WillOnce(Return(true));
245     EXPECT_CALL(stream, SetVolume(_))
246         .Times(1);
247     EXPECT_CALL(stream, Close())
248         .Times(1);
249
250     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
251     EXPECT_TRUE(proxy->Open());
252
253     proxy->Start(&callback_);
254     OnStart();
255     proxy->Stop();
256
257     // Wait for StopStream() to post StopStreamTask().
258     base::PlatformThread::Sleep(pause_delay_ * 2);
259     WaitForCloseTimer(kTestCloseDelayMs);
260
261     // Verify expectation before calling Close().
262     Mock::VerifyAndClear(&stream);
263
264     proxy->Close();
265     EXPECT_TRUE(stream.stop_called());
266     EXPECT_TRUE(stream.start_called());
267   }
268
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_);
272
273     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
274         .WillOnce(Return(&stream));
275     EXPECT_CALL(stream, Open())
276         .WillOnce(Return(true));
277     EXPECT_CALL(stream, Close())
278         .Times(1);
279
280     AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
281     AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
282     EXPECT_TRUE(proxy1->Open());
283     EXPECT_TRUE(proxy2->Open());
284     proxy1->Close();
285     proxy2->Close();
286     WaitForCloseTimer(kTestCloseDelayMs);
287     EXPECT_FALSE(stream.stop_called());
288     EXPECT_FALSE(stream.start_called());
289   }
290
291   // Open() method failed.
292   void OpenFailed(AudioOutputDispatcher* dispatcher) {
293     MockAudioOutputStream stream(&manager_, params_);
294
295     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
296         .WillOnce(Return(&stream));
297     EXPECT_CALL(stream, Open())
298         .WillOnce(Return(false));
299     EXPECT_CALL(stream, Close())
300         .Times(1);
301
302     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
303     EXPECT_FALSE(proxy->Open());
304     proxy->Close();
305     WaitForCloseTimer(kTestCloseDelayMs);
306     EXPECT_FALSE(stream.stop_called());
307     EXPECT_FALSE(stream.start_called());
308   }
309
310   void CreateAndWait(AudioOutputDispatcher* dispatcher) {
311     MockAudioOutputStream stream(&manager_, params_);
312
313     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
314         .WillOnce(Return(&stream));
315     EXPECT_CALL(stream, Open())
316         .WillOnce(Return(true));
317     EXPECT_CALL(stream, Close())
318         .Times(1);
319
320     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
321     EXPECT_TRUE(proxy->Open());
322
323     // Simulate a delay.
324     base::PlatformThread::Sleep(
325         base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2);
326     message_loop_.RunUntilIdle();
327
328     // Verify expectation before calling Close().
329     Mock::VerifyAndClear(&stream);
330
331     proxy->Close();
332     EXPECT_FALSE(stream.stop_called());
333     EXPECT_FALSE(stream.start_called());
334   }
335
336   void TwoStreams_OnePlaying(AudioOutputDispatcher* dispatcher) {
337     MockAudioOutputStream stream1(&manager_, params_);
338     MockAudioOutputStream stream2(&manager_, params_);
339
340     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
341         .WillOnce(Return(&stream1))
342         .WillOnce(Return(&stream2));
343
344     EXPECT_CALL(stream1, Open())
345         .WillOnce(Return(true));
346     EXPECT_CALL(stream1, SetVolume(_))
347         .Times(1);
348     EXPECT_CALL(stream1, Close())
349         .Times(1);
350
351     EXPECT_CALL(stream2, Open())
352         .WillOnce(Return(true));
353     EXPECT_CALL(stream2, Close())
354         .Times(1);
355
356     AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
357     AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
358     EXPECT_TRUE(proxy1->Open());
359
360     proxy1->Start(&callback_);
361     EXPECT_TRUE(proxy2->Open());
362     message_loop_.RunUntilIdle();
363     OnStart();
364     proxy1->Stop();
365
366     proxy1->Close();
367     proxy2->Close();
368     EXPECT_TRUE(stream1.stop_called());
369     EXPECT_TRUE(stream1.start_called());
370     EXPECT_FALSE(stream2.stop_called());
371     EXPECT_FALSE(stream2.start_called());
372   }
373
374   void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) {
375     MockAudioOutputStream stream1(&manager_, params_);
376     MockAudioOutputStream stream2(&manager_, params_);
377
378     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
379         .WillOnce(Return(&stream1))
380         .WillOnce(Return(&stream2));
381
382     EXPECT_CALL(stream1, Open())
383         .WillOnce(Return(true));
384     EXPECT_CALL(stream1, SetVolume(_))
385         .Times(1);
386     EXPECT_CALL(stream1, Close())
387         .Times(1);
388
389     EXPECT_CALL(stream2, Open())
390         .WillOnce(Return(true));
391     EXPECT_CALL(stream2, SetVolume(_))
392         .Times(1);
393     EXPECT_CALL(stream2, Close())
394         .Times(1);
395
396     AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
397     AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
398     EXPECT_TRUE(proxy1->Open());
399     EXPECT_TRUE(proxy2->Open());
400
401     proxy1->Start(&callback_);
402     proxy2->Start(&callback_);
403     OnStart();
404     proxy1->Stop();
405     proxy2->Stop();
406
407     proxy1->Close();
408     proxy2->Close();
409     EXPECT_TRUE(stream1.stop_called());
410     EXPECT_TRUE(stream1.start_called());
411     EXPECT_TRUE(stream2.stop_called());
412     EXPECT_TRUE(stream2.start_called());
413   }
414
415   void StartFailed(AudioOutputDispatcher* dispatcher) {
416     MockAudioOutputStream stream(&manager_, params_);
417
418     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
419         .WillOnce(Return(&stream));
420     EXPECT_CALL(stream, Open())
421         .WillOnce(Return(true));
422     EXPECT_CALL(stream, Close())
423         .Times(1);
424
425     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
426     EXPECT_TRUE(proxy->Open());
427
428     // Simulate a delay.
429     base::PlatformThread::Sleep(
430         base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2);
431     message_loop_.RunUntilIdle();
432
433     // Verify expectation before calling Close().
434     Mock::VerifyAndClear(&stream);
435
436     // |stream| is closed at this point. Start() should reopen it again.
437     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
438         .Times(2)
439         .WillRepeatedly(Return(reinterpret_cast<AudioOutputStream*>(NULL)));
440
441     EXPECT_CALL(callback_, OnError(_))
442         .Times(2);
443
444     proxy->Start(&callback_);
445
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.
448     proxy->Stop();
449     proxy->Start(&callback_);
450
451     Mock::VerifyAndClear(&callback_);
452
453     proxy->Close();
454   }
455
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_;
462 };
463
464 class AudioOutputResamplerTest : public AudioOutputProxyTest {
465  public:
466   virtual void TearDown() {
467     AudioOutputProxyTest::TearDown();
468   }
469
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,
477         16000, 16, 1024);
478     resampler_ = new AudioOutputResampler(
479         &manager(), params_, resampler_params_, std::string(), std::string(),
480         close_delay);
481   }
482
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));
488   }
489
490  protected:
491   AudioParameters resampler_params_;
492   scoped_refptr<AudioOutputResampler> resampler_;
493 };
494
495 TEST_F(AudioOutputProxyTest, CreateAndClose) {
496   AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_.get());
497   proxy->Close();
498 }
499
500 TEST_F(AudioOutputResamplerTest, CreateAndClose) {
501   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
502   proxy->Close();
503 }
504
505 TEST_F(AudioOutputProxyTest, OpenAndClose) {
506   OpenAndClose(dispatcher_impl_.get());
507 }
508
509 TEST_F(AudioOutputResamplerTest, OpenAndClose) {
510   OpenAndClose(resampler_.get());
511 }
512
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());
517 }
518
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());
523 }
524
525 TEST_F(AudioOutputProxyTest, StartAndStop) {
526   StartAndStop(dispatcher_impl_.get());
527 }
528
529 TEST_F(AudioOutputResamplerTest, StartAndStop) {
530   StartAndStop(resampler_.get());
531 }
532
533 TEST_F(AudioOutputProxyTest, CloseAfterStop) {
534   CloseAfterStop(dispatcher_impl_.get());
535 }
536
537 TEST_F(AudioOutputResamplerTest, CloseAfterStop) {
538   CloseAfterStop(resampler_.get());
539 }
540
541 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_.get()); }
542
543 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_.get()); }
544
545 // Two streams: verify that second stream is allocated when the first
546 // starts playing.
547 TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) {
548   InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
549   TwoStreams_OnePlaying(dispatcher_impl_.get());
550 }
551
552 TEST_F(AudioOutputResamplerTest, TwoStreams_OnePlaying) {
553   InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
554   TwoStreams_OnePlaying(resampler_.get());
555 }
556
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());
561 }
562
563 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) {
564   InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
565   TwoStreams_BothPlaying(resampler_.get());
566 }
567
568 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_.get()); }
569
570 // Start() method failed.
571 TEST_F(AudioOutputProxyTest, StartFailed) {
572   StartFailed(dispatcher_impl_.get());
573 }
574
575 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_.get()); }
576
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(_, _, _))
582       .Times(2)
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())
588       .Times(1);
589
590   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
591   EXPECT_TRUE(proxy->Open());
592   proxy->Close();
593   WaitForCloseTimer(kTestCloseDelayMs);
594 }
595
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(_, _, _))
602       .Times(2)
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())
608       .Times(1);
609   EXPECT_CALL(okay_stream, Open())
610       .WillOnce(Return(true));
611   EXPECT_CALL(okay_stream, Close())
612       .Times(1);
613
614   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
615   EXPECT_TRUE(proxy->Open());
616   proxy->Close();
617   WaitForCloseTimer(kTestCloseDelayMs);
618 }
619
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_);
624
625 // Only Windows has a high latency output driver that is not the same as the low
626 // latency path.
627 #if defined(OS_WIN)
628   static const int kFallbackCount = 2;
629 #else
630   static const int kFallbackCount = 1;
631 #endif
632   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
633       .Times(kFallbackCount)
634       .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
635
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()),
641       testing::Property(
642           &AudioParameters::frames_per_buffer, params_.frames_per_buffer())),
643                          _, _))
644       .Times(1)
645       .WillOnce(Return(&okay_stream));
646   EXPECT_CALL(okay_stream, Open())
647       .WillOnce(Return(true));
648   EXPECT_CALL(okay_stream, Close())
649       .Times(1);
650
651   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
652   EXPECT_TRUE(proxy->Open());
653   proxy->Close();
654   WaitForCloseTimer(kTestCloseDelayMs);
655 }
656
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
662 // latency path.
663 #if defined(OS_WIN)
664   static const int kFallbackCount = 3;
665 #else
666   static const int kFallbackCount = 2;
667 #endif
668   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
669       .Times(kFallbackCount)
670       .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
671
672   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
673   EXPECT_FALSE(proxy->Open());
674   proxy->Close();
675   WaitForCloseTimer(kTestCloseDelayMs);
676 }
677
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_);
684
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)));
691
692   // Stream1 should be able to successfully open and start.
693   EXPECT_CALL(stream1, Open())
694       .WillOnce(Return(true));
695   EXPECT_CALL(stream1, Close())
696       .Times(1);
697   EXPECT_CALL(stream1, SetVolume(_))
698       .Times(1);
699
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())
704       .Times(1);
705   EXPECT_CALL(stream2, SetVolume(_))
706       .Times(1);
707
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())
713       .Times(1);
714
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_);
719   OnStart();
720
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_);
725   OnStart();
726
727   // Attempt to open the third stream which should fail.
728   AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_.get());
729   EXPECT_FALSE(proxy3->Open());
730
731   // Perform the required Stop()/Close() shutdown dance for each proxy.  Under
732   // the hood each proxy should correctly call CloseStream() if OpenStream()
733   // succeeded or not.
734   proxy3->Stop();
735   proxy3->Close();
736   proxy2->Stop();
737   proxy2->Close();
738   proxy1->Stop();
739   proxy1->Close();
740
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());
749 }
750
751 }  // namespace media