Upstream version 5.34.92.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_METHOD3(MakeAudioOutputStream, AudioOutputStream*(
97       const AudioParameters& params,
98       const std::string& device_id,
99       const std::string& input_device_id));
100   MOCK_METHOD3(MakeAudioOutputStreamProxy, AudioOutputStream*(
101       const AudioParameters& params,
102       const std::string& device_id,
103       const std::string& input_device_id));
104   MOCK_METHOD2(MakeAudioInputStream, AudioInputStream*(
105       const AudioParameters& params, const std::string& device_id));
106   MOCK_METHOD0(ShowAudioInputSettings, void());
107   MOCK_METHOD0(GetTaskRunner, scoped_refptr<base::SingleThreadTaskRunner>());
108   MOCK_METHOD0(GetWorkerTaskRunner,
109                scoped_refptr<base::SingleThreadTaskRunner>());
110   MOCK_METHOD1(GetAudioInputDeviceNames, void(
111       media::AudioDeviceNames* device_name));
112
113   MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*(
114       const AudioParameters& params));
115   MOCK_METHOD3(MakeLowLatencyOutputStream, AudioOutputStream*(
116       const AudioParameters& params, const std::string& device_id,
117       const std::string& input_device_id));
118   MOCK_METHOD2(MakeLinearInputStream, AudioInputStream*(
119       const AudioParameters& params, const std::string& device_id));
120   MOCK_METHOD2(MakeLowLatencyInputStream, AudioInputStream*(
121       const AudioParameters& params, const std::string& device_id));
122   MOCK_METHOD2(GetPreferredOutputStreamParameters, AudioParameters(
123       const std::string& device_id, const AudioParameters& params));
124
125  private:
126   media::FakeAudioLogFactory fake_audio_log_factory_;
127 };
128
129 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
130  public:
131   int OnMoreData(AudioBus* audio_bus, AudioBuffersState buffers_state) {
132     audio_bus->Zero();
133     return audio_bus->frames();
134   }
135   int OnMoreIOData(AudioBus* source, AudioBus* dest,
136                    AudioBuffersState buffers_state) {
137     return OnMoreData(dest, buffers_state);
138   }
139   MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
140 };
141
142 }  // namespace
143
144 namespace media {
145
146 class AudioOutputProxyTest : public testing::Test {
147  protected:
148   virtual void SetUp() {
149     EXPECT_CALL(manager_, GetTaskRunner())
150         .WillRepeatedly(Return(message_loop_.message_loop_proxy()));
151     EXPECT_CALL(manager_, GetWorkerTaskRunner())
152         .WillRepeatedly(Return(message_loop_.message_loop_proxy()));
153     // Use a low sample rate and large buffer size when testing otherwise the
154     // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
155     // RunUntilIdle() will never terminate.
156     params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
157                               CHANNEL_LAYOUT_STEREO, 8000, 16, 2048);
158     InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs));
159   }
160
161   virtual void TearDown() {
162     // This is necessary to free all proxy objects that have been
163     // closed by the test.
164     message_loop_.RunUntilIdle();
165   }
166
167   virtual void InitDispatcher(base::TimeDelta close_delay) {
168     dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(),
169                                                      params_,
170                                                      std::string(),
171                                                      std::string(),
172                                                      close_delay);
173   }
174
175   virtual void OnStart() {}
176
177   MockAudioManager& manager() {
178     return manager_;
179   }
180
181   void WaitForCloseTimer(MockAudioOutputStream* stream) {
182     base::RunLoop run_loop;
183     EXPECT_CALL(*stream, Close())
184         .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
185     run_loop.Run();
186   }
187
188   void CloseAndWaitForCloseTimer(AudioOutputProxy* proxy,
189                                  MockAudioOutputStream* stream) {
190     // Close the stream and verify it doesn't happen immediately.
191     proxy->Close();
192     Mock::VerifyAndClear(stream);
193
194     // Wait for the actual close event to come from the close timer.
195     WaitForCloseTimer(stream);
196   }
197
198   // Basic Open() and Close() test.
199   void OpenAndClose(AudioOutputDispatcher* dispatcher) {
200     MockAudioOutputStream stream(&manager_, params_);
201
202     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
203         .WillOnce(Return(&stream));
204     EXPECT_CALL(stream, Open())
205         .WillOnce(Return(true));
206
207     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
208     EXPECT_TRUE(proxy->Open());
209     CloseAndWaitForCloseTimer(proxy, &stream);
210   }
211
212   // Creates a stream, and then calls Start() and Stop().
213   void StartAndStop(AudioOutputDispatcher* dispatcher) {
214     MockAudioOutputStream stream(&manager_, params_);
215
216     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
217         .WillOnce(Return(&stream));
218     EXPECT_CALL(stream, Open())
219         .WillOnce(Return(true));
220     EXPECT_CALL(stream, SetVolume(_))
221         .Times(1);
222
223     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
224     EXPECT_TRUE(proxy->Open());
225
226     proxy->Start(&callback_);
227     OnStart();
228     proxy->Stop();
229
230     CloseAndWaitForCloseTimer(proxy, &stream);
231     EXPECT_TRUE(stream.stop_called());
232     EXPECT_TRUE(stream.start_called());
233   }
234
235   // Verify that the stream is closed after Stop() is called.
236   void CloseAfterStop(AudioOutputDispatcher* dispatcher) {
237     MockAudioOutputStream stream(&manager_, params_);
238
239     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
240         .WillOnce(Return(&stream));
241     EXPECT_CALL(stream, Open())
242         .WillOnce(Return(true));
243     EXPECT_CALL(stream, SetVolume(_))
244         .Times(1);
245
246     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
247     EXPECT_TRUE(proxy->Open());
248
249     proxy->Start(&callback_);
250     OnStart();
251     proxy->Stop();
252
253     // Wait for the close timer to fire after StopStream().
254     WaitForCloseTimer(&stream);
255     proxy->Close();
256     EXPECT_TRUE(stream.stop_called());
257     EXPECT_TRUE(stream.start_called());
258   }
259
260   // Create two streams, but don't start them.  Only one device must be opened.
261   void TwoStreams(AudioOutputDispatcher* dispatcher) {
262     MockAudioOutputStream stream(&manager_, params_);
263
264     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
265         .WillOnce(Return(&stream));
266     EXPECT_CALL(stream, Open())
267         .WillOnce(Return(true));
268
269     AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
270     AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
271     EXPECT_TRUE(proxy1->Open());
272     EXPECT_TRUE(proxy2->Open());
273     proxy1->Close();
274     CloseAndWaitForCloseTimer(proxy2, &stream);
275     EXPECT_FALSE(stream.stop_called());
276     EXPECT_FALSE(stream.start_called());
277   }
278
279   // Open() method failed.
280   void OpenFailed(AudioOutputDispatcher* dispatcher) {
281     MockAudioOutputStream stream(&manager_, params_);
282
283     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
284         .WillOnce(Return(&stream));
285     EXPECT_CALL(stream, Open())
286         .WillOnce(Return(false));
287     EXPECT_CALL(stream, Close())
288         .Times(1);
289
290     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
291     EXPECT_FALSE(proxy->Open());
292     proxy->Close();
293     EXPECT_FALSE(stream.stop_called());
294     EXPECT_FALSE(stream.start_called());
295   }
296
297   void CreateAndWait(AudioOutputDispatcher* dispatcher) {
298     MockAudioOutputStream stream(&manager_, params_);
299
300     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
301         .WillOnce(Return(&stream));
302     EXPECT_CALL(stream, Open())
303         .WillOnce(Return(true));
304
305     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
306     EXPECT_TRUE(proxy->Open());
307
308     WaitForCloseTimer(&stream);
309     proxy->Close();
310     EXPECT_FALSE(stream.stop_called());
311     EXPECT_FALSE(stream.start_called());
312   }
313
314   void OneStream_TwoPlays(AudioOutputDispatcher* dispatcher) {
315     MockAudioOutputStream stream(&manager_, params_);
316
317     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
318         .WillOnce(Return(&stream));
319
320     EXPECT_CALL(stream, Open())
321         .WillOnce(Return(true));
322     EXPECT_CALL(stream, SetVolume(_))
323         .Times(2);
324
325     AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
326     EXPECT_TRUE(proxy1->Open());
327
328     proxy1->Start(&callback_);
329     OnStart();
330     proxy1->Stop();
331
332     // The stream should now be idle and get reused by |proxy2|.
333     AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
334     EXPECT_TRUE(proxy2->Open());
335     proxy2->Start(&callback_);
336     OnStart();
337     proxy2->Stop();
338
339     proxy1->Close();
340     CloseAndWaitForCloseTimer(proxy2, &stream);
341     EXPECT_TRUE(stream.stop_called());
342     EXPECT_TRUE(stream.start_called());
343   }
344
345   void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) {
346     MockAudioOutputStream stream1(&manager_, params_);
347     MockAudioOutputStream stream2(&manager_, params_);
348
349     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
350         .WillOnce(Return(&stream1))
351         .WillOnce(Return(&stream2));
352
353     EXPECT_CALL(stream1, Open())
354         .WillOnce(Return(true));
355     EXPECT_CALL(stream1, SetVolume(_))
356         .Times(1);
357
358     EXPECT_CALL(stream2, Open())
359         .WillOnce(Return(true));
360     EXPECT_CALL(stream2, SetVolume(_))
361         .Times(1);
362
363     AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
364     AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
365     EXPECT_TRUE(proxy1->Open());
366     EXPECT_TRUE(proxy2->Open());
367
368     proxy1->Start(&callback_);
369     proxy2->Start(&callback_);
370     OnStart();
371     proxy1->Stop();
372     CloseAndWaitForCloseTimer(proxy1, &stream1);
373
374     proxy2->Stop();
375     CloseAndWaitForCloseTimer(proxy2, &stream2);
376
377     EXPECT_TRUE(stream1.stop_called());
378     EXPECT_TRUE(stream1.start_called());
379     EXPECT_TRUE(stream2.stop_called());
380     EXPECT_TRUE(stream2.start_called());
381   }
382
383   void StartFailed(AudioOutputDispatcher* dispatcher) {
384     MockAudioOutputStream stream(&manager_, params_);
385
386     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
387         .WillOnce(Return(&stream));
388     EXPECT_CALL(stream, Open())
389         .WillOnce(Return(true));
390
391     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
392     EXPECT_TRUE(proxy->Open());
393
394     WaitForCloseTimer(&stream);
395
396     // |stream| is closed at this point. Start() should reopen it again.
397     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
398         .Times(2)
399         .WillRepeatedly(Return(reinterpret_cast<AudioOutputStream*>(NULL)));
400
401     EXPECT_CALL(callback_, OnError(_))
402         .Times(2);
403
404     proxy->Start(&callback_);
405
406     // Double Start() in the error case should be allowed since it's possible a
407     // callback may not have had time to process the OnError() in between.
408     proxy->Stop();
409     proxy->Start(&callback_);
410
411     Mock::VerifyAndClear(&callback_);
412
413     proxy->Close();
414   }
415
416   base::MessageLoop message_loop_;
417   scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_;
418   MockAudioManager manager_;
419   MockAudioSourceCallback callback_;
420   AudioParameters params_;
421 };
422
423 class AudioOutputResamplerTest : public AudioOutputProxyTest {
424  public:
425   virtual void TearDown() {
426     AudioOutputProxyTest::TearDown();
427   }
428
429   virtual void InitDispatcher(base::TimeDelta close_delay) OVERRIDE {
430     // Use a low sample rate and large buffer size when testing otherwise the
431     // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
432     // RunUntilIdle() will never terminate.
433     resampler_params_ = AudioParameters(
434         AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
435         16000, 16, 1024);
436     resampler_ = new AudioOutputResampler(
437         &manager(), params_, resampler_params_, std::string(), std::string(),
438         close_delay);
439   }
440
441   virtual void OnStart() OVERRIDE {
442     // Let Start() run for a bit.
443     base::RunLoop run_loop;
444     message_loop_.PostDelayedTask(
445         FROM_HERE,
446         run_loop.QuitClosure(),
447         base::TimeDelta::FromMilliseconds(kStartRunTimeMs));
448     run_loop.Run();
449   }
450
451  protected:
452   AudioParameters resampler_params_;
453   scoped_refptr<AudioOutputResampler> resampler_;
454 };
455
456 TEST_F(AudioOutputProxyTest, CreateAndClose) {
457   AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_);
458   proxy->Close();
459 }
460
461 TEST_F(AudioOutputResamplerTest, CreateAndClose) {
462   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
463   proxy->Close();
464 }
465
466 TEST_F(AudioOutputProxyTest, OpenAndClose) {
467   OpenAndClose(dispatcher_impl_);
468 }
469
470 TEST_F(AudioOutputResamplerTest, OpenAndClose) {
471   OpenAndClose(resampler_);
472 }
473
474 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
475 // if it doesn't start playing.
476 TEST_F(AudioOutputProxyTest, CreateAndWait) {
477   CreateAndWait(dispatcher_impl_);
478 }
479
480 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
481 // if it doesn't start playing.
482 TEST_F(AudioOutputResamplerTest, CreateAndWait) {
483   CreateAndWait(resampler_);
484 }
485
486 TEST_F(AudioOutputProxyTest, StartAndStop) {
487   StartAndStop(dispatcher_impl_);
488 }
489
490 TEST_F(AudioOutputResamplerTest, StartAndStop) {
491   StartAndStop(resampler_);
492 }
493
494 TEST_F(AudioOutputProxyTest, CloseAfterStop) {
495   CloseAfterStop(dispatcher_impl_);
496 }
497
498 TEST_F(AudioOutputResamplerTest, CloseAfterStop) {
499   CloseAfterStop(resampler_);
500 }
501
502 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_); }
503
504 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_); }
505
506 // Two streams: verify that second stream is allocated when the first
507 // starts playing.
508 TEST_F(AudioOutputProxyTest, OneStream_TwoPlays) {
509   OneStream_TwoPlays(dispatcher_impl_);
510 }
511
512 TEST_F(AudioOutputResamplerTest, OneStream_TwoPlays) {
513   OneStream_TwoPlays(resampler_);
514 }
515
516 // Two streams, both are playing. Dispatcher should not open a third stream.
517 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) {
518   TwoStreams_BothPlaying(dispatcher_impl_);
519 }
520
521 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) {
522   TwoStreams_BothPlaying(resampler_);
523 }
524
525 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_); }
526
527 // Start() method failed.
528 TEST_F(AudioOutputProxyTest, StartFailed) {
529   StartFailed(dispatcher_impl_);
530 }
531
532 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_); }
533
534 // Simulate AudioOutputStream::Create() failure with a low latency stream and
535 // ensure AudioOutputResampler falls back to the high latency path.
536 TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) {
537   MockAudioOutputStream stream(&manager_, params_);
538   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
539       .Times(2)
540       .WillOnce(Return(static_cast<AudioOutputStream*>(NULL)))
541       .WillRepeatedly(Return(&stream));
542   EXPECT_CALL(stream, Open())
543       .WillOnce(Return(true));
544
545   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
546   EXPECT_TRUE(proxy->Open());
547   CloseAndWaitForCloseTimer(proxy, &stream);
548 }
549
550 // Simulate AudioOutputStream::Open() failure with a low latency stream and
551 // ensure AudioOutputResampler falls back to the high latency path.
552 TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) {
553   MockAudioOutputStream failed_stream(&manager_, params_);
554   MockAudioOutputStream okay_stream(&manager_, params_);
555   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
556       .Times(2)
557       .WillOnce(Return(&failed_stream))
558       .WillRepeatedly(Return(&okay_stream));
559   EXPECT_CALL(failed_stream, Open())
560       .WillOnce(Return(false));
561   EXPECT_CALL(failed_stream, Close())
562       .Times(1);
563   EXPECT_CALL(okay_stream, Open())
564       .WillOnce(Return(true));
565
566   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
567   EXPECT_TRUE(proxy->Open());
568   CloseAndWaitForCloseTimer(proxy, &okay_stream);
569 }
570
571 // Simulate failures to open both the low latency and the fallback high latency
572 // stream and ensure AudioOutputResampler falls back to a fake stream.
573 TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) {
574   MockAudioOutputStream okay_stream(&manager_, params_);
575
576 // Only Windows has a high latency output driver that is not the same as the low
577 // latency path.
578 #if defined(OS_WIN)
579   static const int kFallbackCount = 2;
580 #else
581   static const int kFallbackCount = 1;
582 #endif
583   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
584       .Times(kFallbackCount)
585       .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
586
587   // To prevent shared memory issues the sample rate and buffer size should
588   // match the input stream parameters.
589   EXPECT_CALL(manager(), MakeAudioOutputStream(AllOf(
590       testing::Property(&AudioParameters::format, AudioParameters::AUDIO_FAKE),
591       testing::Property(&AudioParameters::sample_rate, params_.sample_rate()),
592       testing::Property(
593           &AudioParameters::frames_per_buffer, params_.frames_per_buffer())),
594                          _, _))
595       .Times(1)
596       .WillOnce(Return(&okay_stream));
597   EXPECT_CALL(okay_stream, Open())
598       .WillOnce(Return(true));
599
600   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
601   EXPECT_TRUE(proxy->Open());
602   CloseAndWaitForCloseTimer(proxy, &okay_stream);
603 }
604
605 // Simulate failures to open both the low latency, the fallback high latency
606 // stream, and the fake audio output stream and ensure AudioOutputResampler
607 // terminates normally.
608 TEST_F(AudioOutputResamplerTest, AllFallbackFailed) {
609 // Only Windows has a high latency output driver that is not the same as the low
610 // latency path.
611 #if defined(OS_WIN)
612   static const int kFallbackCount = 3;
613 #else
614   static const int kFallbackCount = 2;
615 #endif
616   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
617       .Times(kFallbackCount)
618       .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
619
620   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
621   EXPECT_FALSE(proxy->Open());
622   proxy->Close();
623 }
624
625 // Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls
626 // eventually followed by one which fails; root cause of http://crbug.com/150619
627 TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) {
628   MockAudioOutputStream stream1(&manager_, params_);
629   MockAudioOutputStream stream2(&manager_, params_);
630
631   // Setup the mock such that all three streams are successfully created.
632   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
633       .WillOnce(Return(&stream1))
634       .WillOnce(Return(&stream2))
635       .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
636
637   // Stream1 should be able to successfully open and start.
638   EXPECT_CALL(stream1, Open())
639       .WillOnce(Return(true));
640   EXPECT_CALL(stream1, SetVolume(_))
641       .Times(1);
642
643   // Stream2 should also be able to successfully open and start.
644   EXPECT_CALL(stream2, Open())
645       .WillOnce(Return(true));
646   EXPECT_CALL(stream2, SetVolume(_))
647       .Times(1);
648
649   // Open and start the first proxy and stream.
650   AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_);
651   EXPECT_TRUE(proxy1->Open());
652   proxy1->Start(&callback_);
653   OnStart();
654
655   // Open and start the second proxy and stream.
656   AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_);
657   EXPECT_TRUE(proxy2->Open());
658   proxy2->Start(&callback_);
659   OnStart();
660
661   // Attempt to open the third stream which should fail.
662   AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_);
663   EXPECT_FALSE(proxy3->Open());
664   proxy3->Close();
665
666   // Perform the required Stop()/Close() shutdown dance for each proxy.  Under
667   // the hood each proxy should correctly call CloseStream() if OpenStream()
668   // succeeded or not.
669   proxy2->Stop();
670   CloseAndWaitForCloseTimer(proxy2, &stream2);
671
672   proxy1->Stop();
673   CloseAndWaitForCloseTimer(proxy1, &stream1);
674
675   EXPECT_TRUE(stream1.stop_called());
676   EXPECT_TRUE(stream1.start_called());
677   EXPECT_TRUE(stream2.stop_called());
678   EXPECT_TRUE(stream2.start_called());
679 }
680
681 // Ensures the methods used to fix audio output wedges are working correctly.
682 TEST_F(AudioOutputResamplerTest, WedgeFix) {
683   MockAudioOutputStream stream1(&manager_, params_);
684   MockAudioOutputStream stream2(&manager_, params_);
685   MockAudioOutputStream stream3(&manager_, params_);
686
687   // Setup the mock such that all three streams are successfully created.
688   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
689       .WillOnce(Return(&stream1))
690       .WillOnce(Return(&stream2))
691       .WillOnce(Return(&stream3));
692
693   // Stream1 should be able to successfully open and start.
694   EXPECT_CALL(stream1, Open())
695       .WillOnce(Return(true));
696   EXPECT_CALL(stream1, SetVolume(_));
697   EXPECT_CALL(stream2, Open())
698       .WillOnce(Return(true));
699   EXPECT_CALL(stream2, SetVolume(_));
700
701   // Open and start the first proxy and stream.
702   AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_.get());
703   EXPECT_TRUE(proxy1->Open());
704   proxy1->Start(&callback_);
705   OnStart();
706
707   // Open, but do not start the second proxy.
708   AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_.get());
709   EXPECT_TRUE(proxy2->Open());
710
711   // Open, start and then stop the third proxy.
712   AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_.get());
713   EXPECT_TRUE(proxy3->Open());
714   proxy3->Start(&callback_);
715   OnStart();
716   proxy3->Stop();
717
718   // Wait for stream to timeout and shutdown.
719   WaitForCloseTimer(&stream2);
720
721   EXPECT_CALL(stream1, Close());
722   resampler_->CloseStreamsForWedgeFix();
723
724   // Don't pump the MessageLoop between CloseStreamsForWedgeFix() and
725   // RestartStreamsForWedgeFix() to simulate intended usage.  The OnStart() call
726   // will take care of necessary work.
727
728   // Stream3 should take Stream1's place after RestartStreamsForWedgeFix().  No
729   // additional streams should be opened for proxy2 and proxy3.
730   EXPECT_CALL(stream3, Open())
731       .WillOnce(Return(true));
732   EXPECT_CALL(stream3, SetVolume(_));
733
734   resampler_->RestartStreamsForWedgeFix();
735   OnStart();
736
737   // Perform the required Stop()/Close() shutdown dance for each proxy.
738   proxy3->Close();
739   proxy2->Close();
740   proxy1->Stop();
741   CloseAndWaitForCloseTimer(proxy1, &stream3);
742
743   // Wait for all of the messages to fly and then verify stream behavior.
744   EXPECT_TRUE(stream1.stop_called());
745   EXPECT_TRUE(stream1.start_called());
746   EXPECT_TRUE(stream2.stop_called());
747   EXPECT_TRUE(stream2.start_called());
748   EXPECT_TRUE(stream3.stop_called());
749   EXPECT_TRUE(stream3.start_called());
750 }
751
752 }  // namespace media