Upstream version 5.34.104.0
[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/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"
18
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;
37
38 namespace {
39
40 static const int kTestCloseDelayMs = 10;
41
42 // Delay between callbacks to AudioSourceCallback::OnMoreData.
43 static const int kOnMoreDataCallbackDelayMs = 10;
44
45 // Let start run long enough for many OnMoreData callbacks to occur.
46 static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10;
47
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_)) {
57   }
58
59   void Start(AudioSourceCallback* callback) {
60     start_called_ = true;
61     fake_output_stream_->Start(callback);
62   }
63
64   void Stop() {
65     stop_called_ = true;
66     fake_output_stream_->Stop();
67   }
68
69   ~MockAudioOutputStream() {}
70
71   bool start_called() { return start_called_; }
72   bool stop_called() { return stop_called_; }
73
74   MOCK_METHOD0(Open, bool());
75   MOCK_METHOD1(SetVolume, void(double volume));
76   MOCK_METHOD1(GetVolume, void(double* volume));
77   MOCK_METHOD0(Close, void());
78
79  private:
80   bool start_called_;
81   bool stop_called_;
82   AudioParameters params_;
83   scoped_ptr<AudioOutputStream> fake_output_stream_;
84 };
85
86 class MockAudioManager : public AudioManagerBase {
87  public:
88   MockAudioManager() : AudioManagerBase(&fake_audio_log_factory_) {}
89   virtual ~MockAudioManager() {
90     Shutdown();
91   }
92
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));
110
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));
121
122  private:
123   media::FakeAudioLogFactory fake_audio_log_factory_;
124 };
125
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();
131   }
132   int OnMoreIOData(AudioBus* source, AudioBus* dest,
133                    AudioBuffersState buffers_state) {
134     return OnMoreData(dest, buffers_state);
135   }
136   MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
137 };
138
139 }  // namespace
140
141 namespace media {
142
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));
156   }
157
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();
162   }
163
164   virtual void InitDispatcher(base::TimeDelta close_delay) {
165     dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(),
166                                                      params_,
167                                                      std::string(),
168                                                      close_delay);
169   }
170
171   virtual void OnStart() {}
172
173   MockAudioManager& manager() {
174     return manager_;
175   }
176
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();
182   }
183
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);
189
190     // Wait for the actual close event to come from the close timer.
191     WaitForCloseTimer(stream);
192   }
193
194   // Basic Open() and Close() test.
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
203     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
204     EXPECT_TRUE(proxy->Open());
205     CloseAndWaitForCloseTimer(proxy, &stream);
206   }
207
208   // Creates a stream, and then calls Start() and Stop().
209   void StartAndStop(AudioOutputDispatcher* dispatcher) {
210     MockAudioOutputStream stream(&manager_, params_);
211
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);
218
219     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
220     EXPECT_TRUE(proxy->Open());
221
222     proxy->Start(&callback_);
223     OnStart();
224     proxy->Stop();
225
226     CloseAndWaitForCloseTimer(proxy, &stream);
227     EXPECT_TRUE(stream.stop_called());
228     EXPECT_TRUE(stream.start_called());
229   }
230
231   // Verify that the stream is closed after Stop() is called.
232   void CloseAfterStop(AudioOutputDispatcher* dispatcher) {
233     MockAudioOutputStream stream(&manager_, params_);
234
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);
241
242     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
243     EXPECT_TRUE(proxy->Open());
244
245     proxy->Start(&callback_);
246     OnStart();
247     proxy->Stop();
248
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());
254   }
255
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_);
259
260     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
261         .WillOnce(Return(&stream));
262     EXPECT_CALL(stream, Open())
263         .WillOnce(Return(true));
264
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());
273   }
274
275   // Open() method failed.
276   void OpenFailed(AudioOutputDispatcher* dispatcher) {
277     MockAudioOutputStream stream(&manager_, params_);
278
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);
285
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());
291   }
292
293   void CreateAndWait(AudioOutputDispatcher* dispatcher) {
294     MockAudioOutputStream stream(&manager_, params_);
295
296     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
297         .WillOnce(Return(&stream));
298     EXPECT_CALL(stream, Open())
299         .WillOnce(Return(true));
300
301     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
302     EXPECT_TRUE(proxy->Open());
303
304     WaitForCloseTimer(&stream);
305     proxy->Close();
306     EXPECT_FALSE(stream.stop_called());
307     EXPECT_FALSE(stream.start_called());
308   }
309
310   void OneStream_TwoPlays(AudioOutputDispatcher* dispatcher) {
311     MockAudioOutputStream stream(&manager_, params_);
312
313     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
314         .WillOnce(Return(&stream));
315
316     EXPECT_CALL(stream, Open())
317         .WillOnce(Return(true));
318     EXPECT_CALL(stream, SetVolume(_))
319         .Times(2);
320
321     AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
322     EXPECT_TRUE(proxy1->Open());
323
324     proxy1->Start(&callback_);
325     OnStart();
326     proxy1->Stop();
327
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();
334
335     proxy1->Close();
336     CloseAndWaitForCloseTimer(proxy2, &stream);
337     EXPECT_TRUE(stream.stop_called());
338     EXPECT_TRUE(stream.start_called());
339   }
340
341   void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) {
342     MockAudioOutputStream stream1(&manager_, params_);
343     MockAudioOutputStream stream2(&manager_, params_);
344
345     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
346         .WillOnce(Return(&stream1))
347         .WillOnce(Return(&stream2));
348
349     EXPECT_CALL(stream1, Open())
350         .WillOnce(Return(true));
351     EXPECT_CALL(stream1, SetVolume(_))
352         .Times(1);
353
354     EXPECT_CALL(stream2, Open())
355         .WillOnce(Return(true));
356     EXPECT_CALL(stream2, SetVolume(_))
357         .Times(1);
358
359     AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
360     AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
361     EXPECT_TRUE(proxy1->Open());
362     EXPECT_TRUE(proxy2->Open());
363
364     proxy1->Start(&callback_);
365     proxy2->Start(&callback_);
366     OnStart();
367     proxy1->Stop();
368     CloseAndWaitForCloseTimer(proxy1, &stream1);
369
370     proxy2->Stop();
371     CloseAndWaitForCloseTimer(proxy2, &stream2);
372
373     EXPECT_TRUE(stream1.stop_called());
374     EXPECT_TRUE(stream1.start_called());
375     EXPECT_TRUE(stream2.stop_called());
376     EXPECT_TRUE(stream2.start_called());
377   }
378
379   void StartFailed(AudioOutputDispatcher* dispatcher) {
380     MockAudioOutputStream stream(&manager_, params_);
381
382     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
383         .WillOnce(Return(&stream));
384     EXPECT_CALL(stream, Open())
385         .WillOnce(Return(true));
386
387     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
388     EXPECT_TRUE(proxy->Open());
389
390     WaitForCloseTimer(&stream);
391
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)));
396
397     EXPECT_CALL(callback_, OnError(_))
398         .Times(2);
399
400     proxy->Start(&callback_);
401
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_);
406
407     Mock::VerifyAndClear(&callback_);
408
409     proxy->Close();
410   }
411
412   base::MessageLoop message_loop_;
413   scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_;
414   MockAudioManager manager_;
415   MockAudioSourceCallback callback_;
416   AudioParameters params_;
417 };
418
419 class AudioOutputResamplerTest : public AudioOutputProxyTest {
420  public:
421   virtual void TearDown() {
422     AudioOutputProxyTest::TearDown();
423   }
424
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);
434   }
435
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();
444   }
445
446  protected:
447   AudioParameters resampler_params_;
448   scoped_refptr<AudioOutputResampler> resampler_;
449 };
450
451 TEST_F(AudioOutputProxyTest, CreateAndClose) {
452   AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_);
453   proxy->Close();
454 }
455
456 TEST_F(AudioOutputResamplerTest, CreateAndClose) {
457   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
458   proxy->Close();
459 }
460
461 TEST_F(AudioOutputProxyTest, OpenAndClose) {
462   OpenAndClose(dispatcher_impl_);
463 }
464
465 TEST_F(AudioOutputResamplerTest, OpenAndClose) {
466   OpenAndClose(resampler_);
467 }
468
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_);
473 }
474
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_);
479 }
480
481 TEST_F(AudioOutputProxyTest, StartAndStop) {
482   StartAndStop(dispatcher_impl_);
483 }
484
485 TEST_F(AudioOutputResamplerTest, StartAndStop) {
486   StartAndStop(resampler_);
487 }
488
489 TEST_F(AudioOutputProxyTest, CloseAfterStop) {
490   CloseAfterStop(dispatcher_impl_);
491 }
492
493 TEST_F(AudioOutputResamplerTest, CloseAfterStop) {
494   CloseAfterStop(resampler_);
495 }
496
497 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_); }
498
499 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_); }
500
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_);
505 }
506
507 TEST_F(AudioOutputResamplerTest, OneStream_TwoPlays) {
508   OneStream_TwoPlays(resampler_);
509 }
510
511 // Two streams, both are playing. Dispatcher should not open a third stream.
512 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) {
513   TwoStreams_BothPlaying(dispatcher_impl_);
514 }
515
516 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) {
517   TwoStreams_BothPlaying(resampler_);
518 }
519
520 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_); }
521
522 // Start() method failed.
523 TEST_F(AudioOutputProxyTest, StartFailed) {
524   StartFailed(dispatcher_impl_);
525 }
526
527 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_); }
528
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));
539
540   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
541   EXPECT_TRUE(proxy->Open());
542   CloseAndWaitForCloseTimer(proxy, &stream);
543 }
544
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));
560
561   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
562   EXPECT_TRUE(proxy->Open());
563   CloseAndWaitForCloseTimer(proxy, &okay_stream);
564 }
565
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_);
570
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)));
581
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())),
589                          _))
590       .Times(1)
591       .WillOnce(Return(&okay_stream));
592   EXPECT_CALL(okay_stream, Open())
593       .WillOnce(Return(true));
594
595   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
596   EXPECT_TRUE(proxy->Open());
597   CloseAndWaitForCloseTimer(proxy, &okay_stream);
598 }
599
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)));
614
615   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
616   EXPECT_FALSE(proxy->Open());
617   proxy->Close();
618 }
619
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_);
625
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)));
631
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);
637
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);
643
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();
649
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();
655
656   // Attempt to open the third stream which should fail.
657   AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_);
658   EXPECT_FALSE(proxy3->Open());
659   proxy3->Close();
660
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);
666
667   proxy1->Stop();
668   CloseAndWaitForCloseTimer(proxy1, &stream1);
669
670   EXPECT_TRUE(stream1.stop_called());
671   EXPECT_TRUE(stream1.start_called());
672   EXPECT_TRUE(stream2.stop_called());
673   EXPECT_TRUE(stream2.start_called());
674 }
675
676 // Ensures the methods used to fix audio output wedges are working correctly.
677 TEST_F(AudioOutputResamplerTest, WedgeFix) {
678   MockAudioOutputStream stream1(&manager_, params_);
679   MockAudioOutputStream stream2(&manager_, params_);
680   MockAudioOutputStream stream3(&manager_, params_);
681
682   // Setup the mock such that all three streams are successfully created.
683   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
684       .WillOnce(Return(&stream1))
685       .WillOnce(Return(&stream2))
686       .WillOnce(Return(&stream3));
687
688   // Stream1 should be able to successfully open and start.
689   EXPECT_CALL(stream1, Open())
690       .WillOnce(Return(true));
691   EXPECT_CALL(stream1, SetVolume(_));
692   EXPECT_CALL(stream2, Open())
693       .WillOnce(Return(true));
694   EXPECT_CALL(stream2, SetVolume(_));
695
696   // Open and start the first proxy and stream.
697   AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_.get());
698   EXPECT_TRUE(proxy1->Open());
699   proxy1->Start(&callback_);
700   OnStart();
701
702   // Open, but do not start the second proxy.
703   AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_.get());
704   EXPECT_TRUE(proxy2->Open());
705
706   // Open, start and then stop the third proxy.
707   AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_.get());
708   EXPECT_TRUE(proxy3->Open());
709   proxy3->Start(&callback_);
710   OnStart();
711   proxy3->Stop();
712
713   // Wait for stream to timeout and shutdown.
714   WaitForCloseTimer(&stream2);
715
716   EXPECT_CALL(stream1, Close());
717   resampler_->CloseStreamsForWedgeFix();
718
719   // Don't pump the MessageLoop between CloseStreamsForWedgeFix() and
720   // RestartStreamsForWedgeFix() to simulate intended usage.  The OnStart() call
721   // will take care of necessary work.
722
723   // Stream3 should take Stream1's place after RestartStreamsForWedgeFix().  No
724   // additional streams should be opened for proxy2 and proxy3.
725   EXPECT_CALL(stream3, Open())
726       .WillOnce(Return(true));
727   EXPECT_CALL(stream3, SetVolume(_));
728
729   resampler_->RestartStreamsForWedgeFix();
730   OnStart();
731
732   // Perform the required Stop()/Close() shutdown dance for each proxy.
733   proxy3->Close();
734   proxy2->Close();
735   proxy1->Stop();
736   CloseAndWaitForCloseTimer(proxy1, &stream3);
737
738   // Wait for all of the messages to fly and then verify stream behavior.
739   EXPECT_TRUE(stream1.stop_called());
740   EXPECT_TRUE(stream1.start_called());
741   EXPECT_TRUE(stream2.stop_called());
742   EXPECT_TRUE(stream2.start_called());
743   EXPECT_TRUE(stream3.stop_called());
744   EXPECT_TRUE(stream3.start_called());
745 }
746
747 }  // namespace media