audio_output_proxy_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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/command_line.h"
8#include "base/message_loop.h"
9#include "base/message_loop_proxy.h"
10#include "media/audio/audio_output_dispatcher_impl.h"
11#include "media/audio/audio_output_proxy.h"
12#include "media/audio/audio_output_resampler.h"
13#include "media/audio/audio_manager.h"
14#include "media/audio/audio_manager_base.h"
15#include "media/audio/fake_audio_output_stream.h"
16#include "media/base/media_switches.h"
17#include "testing/gmock/include/gmock/gmock.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
20// TODO(dalecurtis): Temporarily disabled while switching pipeline to use float,
21// http://crbug.com/114700
22#if defined(ENABLE_AUDIO_MIXER)
23#include "media/audio/audio_output_mixer.h"
24#endif
25
26using ::testing::_;
27using ::testing::AllOf;
28using ::testing::DoAll;
29using ::testing::Field;
30using ::testing::Mock;
31using ::testing::NotNull;
32using ::testing::Return;
33using ::testing::SetArrayArgument;
34using media::AudioBus;
35using media::AudioBuffersState;
36using media::AudioInputStream;
37using media::AudioManager;
38using media::AudioManagerBase;
39using media::AudioOutputDispatcher;
40using media::AudioOutputProxy;
41using media::AudioOutputStream;
42using media::AudioParameters;
43using media::FakeAudioOutputStream;
44
45namespace {
46
47static const int kTestCloseDelayMs = 100;
48
49// Used in the test where we don't want a stream to be closed unexpectedly.
50static const int kTestBigCloseDelaySeconds = 1000;
51
52// Delay between callbacks to AudioSourceCallback::OnMoreData.
53static const int kOnMoreDataCallbackDelayMs = 10;
54
55// Let start run long enough for many OnMoreData callbacks to occur.
56static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10;
57
58class MockAudioOutputStream : public AudioOutputStream {
59 public:
60  MockAudioOutputStream(AudioManagerBase* manager,
61                        const AudioParameters& params)
62      : start_called_(false),
63        stop_called_(false),
64        params_(params),
65        fake_output_stream_(
66            FakeAudioOutputStream::MakeFakeStream(manager, params_)) {
67  }
68
69  void Start(AudioSourceCallback* callback) {
70    start_called_ = true;
71    fake_output_stream_->Start(callback);
72  }
73
74  void Stop() {
75    stop_called_ = true;
76    fake_output_stream_->Stop();
77  }
78
79  ~MockAudioOutputStream() {}
80
81  bool start_called() { return start_called_; }
82  bool stop_called() { return stop_called_; }
83
84  MOCK_METHOD0(Open, bool());
85  MOCK_METHOD1(SetVolume, void(double volume));
86  MOCK_METHOD1(GetVolume, void(double* volume));
87  MOCK_METHOD0(Close, void());
88
89 private:
90  bool start_called_;
91  bool stop_called_;
92  AudioParameters params_;
93  scoped_ptr<AudioOutputStream> fake_output_stream_;
94};
95
96class MockAudioManager : public AudioManagerBase {
97 public:
98  MockAudioManager() {}
99  virtual ~MockAudioManager() {
100    Shutdown();
101  }
102
103  MOCK_METHOD0(HasAudioOutputDevices, bool());
104  MOCK_METHOD0(HasAudioInputDevices, bool());
105  MOCK_METHOD0(GetAudioInputDeviceModel, string16());
106  MOCK_METHOD1(MakeAudioOutputStream, AudioOutputStream*(
107      const AudioParameters& params));
108  MOCK_METHOD1(MakeAudioOutputStreamProxy, AudioOutputStream*(
109      const AudioParameters& params));
110  MOCK_METHOD2(MakeAudioInputStream, AudioInputStream*(
111      const AudioParameters& params, const std::string& device_id));
112  MOCK_METHOD0(CanShowAudioInputSettings, bool());
113  MOCK_METHOD0(ShowAudioInputSettings, void());
114  MOCK_METHOD0(GetMessageLoop, scoped_refptr<base::MessageLoopProxy>());
115  MOCK_METHOD1(GetAudioInputDeviceNames, void(
116      media::AudioDeviceNames* device_name));
117  MOCK_METHOD0(IsRecordingInProcess, bool());
118
119  MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*(
120      const AudioParameters& params));
121  MOCK_METHOD1(MakeLowLatencyOutputStream, AudioOutputStream*(
122      const AudioParameters& params));
123  MOCK_METHOD2(MakeLinearInputStream, AudioInputStream*(
124      const AudioParameters& params, const std::string& device_id));
125  MOCK_METHOD2(MakeLowLatencyInputStream, AudioInputStream*(
126      const AudioParameters& params, const std::string& device_id));
127};
128
129class 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_METHOD2(OnError, void(AudioOutputStream* stream, int code));
140};
141
142}  // namespace
143
144namespace media {
145
146class AudioOutputProxyTest : public testing::Test {
147 protected:
148  virtual void SetUp() {
149    EXPECT_CALL(manager_, GetMessageLoop())
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_.RunAllPending();
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    // RunAllPending() 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                                                     close_delay);
172#if defined(ENABLE_AUDIO_MIXER)
173    mixer_ = new AudioOutputMixer(&manager(), params_, close_delay);
174#endif
175
176    // Necessary to know how long the dispatcher will wait before posting
177    // StopStreamTask.
178    pause_delay_ = dispatcher_impl_->pause_delay_;
179  }
180
181  virtual void OnStart() {}
182
183  MockAudioManager& manager() {
184    return manager_;
185  }
186
187  // Wait for the close timer to fire.
188  void WaitForCloseTimer(const int timer_delay_ms) {
189    message_loop_.RunAllPending();  // OpenTask() may reset the timer.
190    base::PlatformThread::Sleep(
191        base::TimeDelta::FromMilliseconds(timer_delay_ms) * 2);
192    message_loop_.RunAllPending();
193  }
194
195  // Methods that do actual tests.
196  void OpenAndClose(AudioOutputDispatcher* dispatcher) {
197    MockAudioOutputStream stream(&manager_, params_);
198
199    EXPECT_CALL(manager(), MakeAudioOutputStream(_))
200        .WillOnce(Return(&stream));
201    EXPECT_CALL(stream, Open())
202        .WillOnce(Return(true));
203    EXPECT_CALL(stream, Close())
204        .Times(1);
205
206    AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
207    EXPECT_TRUE(proxy->Open());
208    proxy->Close();
209    WaitForCloseTimer(kTestCloseDelayMs);
210  }
211
212  // Create 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    EXPECT_CALL(stream, Close())
223        .Times(1);
224
225    AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
226    EXPECT_TRUE(proxy->Open());
227
228    proxy->Start(&callback_);
229    OnStart();
230    proxy->Stop();
231
232    proxy->Close();
233    WaitForCloseTimer(kTestCloseDelayMs);
234    EXPECT_TRUE(stream.stop_called());
235    EXPECT_TRUE(stream.start_called());
236  }
237
238  // Verify that the stream is closed after Stop is called.
239  void CloseAfterStop(AudioOutputDispatcher* dispatcher) {
240    MockAudioOutputStream stream(&manager_, params_);
241
242    EXPECT_CALL(manager(), MakeAudioOutputStream(_))
243        .WillOnce(Return(&stream));
244    EXPECT_CALL(stream, Open())
245        .WillOnce(Return(true));
246    EXPECT_CALL(stream, SetVolume(_))
247        .Times(1);
248    EXPECT_CALL(stream, Close())
249        .Times(1);
250
251    AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
252    EXPECT_TRUE(proxy->Open());
253
254    proxy->Start(&callback_);
255    OnStart();
256    proxy->Stop();
257
258    // Wait for StopStream() to post StopStreamTask().
259    base::PlatformThread::Sleep(pause_delay_ * 2);
260    WaitForCloseTimer(kTestCloseDelayMs);
261
262    // Verify expectation before calling Close().
263    Mock::VerifyAndClear(&stream);
264
265    proxy->Close();
266    EXPECT_TRUE(stream.stop_called());
267    EXPECT_TRUE(stream.start_called());
268  }
269
270  // Create two streams, but don't start them. Only one device must be open.
271  void TwoStreams(AudioOutputDispatcher* dispatcher) {
272    MockAudioOutputStream stream(&manager_, params_);
273
274    EXPECT_CALL(manager(), MakeAudioOutputStream(_))
275        .WillOnce(Return(&stream));
276    EXPECT_CALL(stream, Open())
277        .WillOnce(Return(true));
278    EXPECT_CALL(stream, Close())
279        .Times(1);
280
281    AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
282    AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
283    EXPECT_TRUE(proxy1->Open());
284    EXPECT_TRUE(proxy2->Open());
285    proxy1->Close();
286    proxy2->Close();
287    WaitForCloseTimer(kTestCloseDelayMs);
288    EXPECT_FALSE(stream.stop_called());
289    EXPECT_FALSE(stream.start_called());
290  }
291
292  // Open() method failed.
293  void OpenFailed(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(false));
300    EXPECT_CALL(stream, Close())
301        .Times(1);
302
303    AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
304    EXPECT_FALSE(proxy->Open());
305    proxy->Close();
306    WaitForCloseTimer(kTestCloseDelayMs);
307    EXPECT_FALSE(stream.stop_called());
308    EXPECT_FALSE(stream.start_called());
309  }
310
311  void CreateAndWait(AudioOutputDispatcher* dispatcher) {
312    MockAudioOutputStream stream(&manager_, params_);
313
314    EXPECT_CALL(manager(), MakeAudioOutputStream(_))
315        .WillOnce(Return(&stream));
316    EXPECT_CALL(stream, Open())
317        .WillOnce(Return(true));
318    EXPECT_CALL(stream, Close())
319        .Times(1);
320
321    AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
322    EXPECT_TRUE(proxy->Open());
323
324    // Simulate a delay.
325    base::PlatformThread::Sleep(
326        base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2);
327    message_loop_.RunAllPending();
328
329    // Verify expectation before calling Close().
330    Mock::VerifyAndClear(&stream);
331
332    proxy->Close();
333    EXPECT_FALSE(stream.stop_called());
334    EXPECT_FALSE(stream.start_called());
335  }
336
337  void TwoStreams_OnePlaying(AudioOutputDispatcher* dispatcher) {
338    MockAudioOutputStream stream1(&manager_, params_);
339    MockAudioOutputStream stream2(&manager_, params_);
340
341    EXPECT_CALL(manager(), MakeAudioOutputStream(_))
342        .WillOnce(Return(&stream1))
343        .WillOnce(Return(&stream2));
344
345    EXPECT_CALL(stream1, Open())
346        .WillOnce(Return(true));
347    EXPECT_CALL(stream1, SetVolume(_))
348        .Times(1);
349    EXPECT_CALL(stream1, Close())
350        .Times(1);
351
352    EXPECT_CALL(stream2, Open())
353        .WillOnce(Return(true));
354    EXPECT_CALL(stream2, Close())
355        .Times(1);
356
357    AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
358    AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
359    EXPECT_TRUE(proxy1->Open());
360    EXPECT_TRUE(proxy2->Open());
361
362    proxy1->Start(&callback_);
363    message_loop_.RunAllPending();
364    OnStart();
365    proxy1->Stop();
366
367    proxy1->Close();
368    proxy2->Close();
369    EXPECT_TRUE(stream1.stop_called());
370    EXPECT_TRUE(stream1.start_called());
371    EXPECT_FALSE(stream2.stop_called());
372    EXPECT_FALSE(stream2.start_called());
373  }
374
375  void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) {
376    MockAudioOutputStream stream1(&manager_, params_);
377    MockAudioOutputStream stream2(&manager_, params_);
378
379    EXPECT_CALL(manager(), MakeAudioOutputStream(_))
380        .WillOnce(Return(&stream1))
381        .WillOnce(Return(&stream2));
382
383    EXPECT_CALL(stream1, Open())
384        .WillOnce(Return(true));
385    EXPECT_CALL(stream1, SetVolume(_))
386        .Times(1);
387    EXPECT_CALL(stream1, Close())
388        .Times(1);
389
390    EXPECT_CALL(stream2, Open())
391        .WillOnce(Return(true));
392    EXPECT_CALL(stream2, SetVolume(_))
393        .Times(1);
394    EXPECT_CALL(stream2, Close())
395        .Times(1);
396
397    AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
398    AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
399    EXPECT_TRUE(proxy1->Open());
400    EXPECT_TRUE(proxy2->Open());
401
402    proxy1->Start(&callback_);
403    proxy2->Start(&callback_);
404    OnStart();
405    proxy1->Stop();
406    proxy2->Stop();
407
408    proxy1->Close();
409    proxy2->Close();
410    EXPECT_TRUE(stream1.stop_called());
411    EXPECT_TRUE(stream1.start_called());
412    EXPECT_TRUE(stream2.stop_called());
413    EXPECT_TRUE(stream2.start_called());
414  }
415
416  void StartFailed(AudioOutputDispatcher* dispatcher) {
417    MockAudioOutputStream stream(&manager_, params_);
418
419    EXPECT_CALL(manager(), MakeAudioOutputStream(_))
420        .WillOnce(Return(&stream));
421    EXPECT_CALL(stream, Open())
422        .WillOnce(Return(true));
423    EXPECT_CALL(stream, Close())
424        .Times(1);
425
426    AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_);
427    EXPECT_TRUE(proxy->Open());
428
429    // Simulate a delay.
430    base::PlatformThread::Sleep(
431        base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2);
432    message_loop_.RunAllPending();
433
434    // Verify expectation before calling Close().
435    Mock::VerifyAndClear(&stream);
436
437    // |stream| is closed at this point. Start() should reopen it again.
438    EXPECT_CALL(manager(), MakeAudioOutputStream(_))
439        .WillOnce(Return(reinterpret_cast<AudioOutputStream*>(NULL)));
440
441    EXPECT_CALL(callback_, OnError(_, _))
442        .Times(1);
443
444    proxy->Start(&callback_);
445
446    Mock::VerifyAndClear(&callback_);
447
448    proxy->Close();
449  }
450
451  MessageLoop message_loop_;
452  scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_;
453#if defined(ENABLE_AUDIO_MIXER)
454  scoped_refptr<AudioOutputMixer> mixer_;
455#endif
456  base::TimeDelta pause_delay_;
457  MockAudioManager manager_;
458  MockAudioSourceCallback callback_;
459  AudioParameters params_;
460};
461
462class AudioOutputResamplerTest : public AudioOutputProxyTest {
463 public:
464  virtual void TearDown() {
465    AudioOutputProxyTest::TearDown();
466  }
467
468  virtual void InitDispatcher(base::TimeDelta close_delay) {
469    AudioOutputProxyTest::InitDispatcher(close_delay);
470    // Use a low sample rate and large buffer size when testing otherwise the
471    // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
472    // RunAllPending() will never terminate.
473    resampler_params_ = AudioParameters(
474        AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
475        16000, 16, 1024);
476    resampler_ = new AudioOutputResampler(
477        &manager(), params_, resampler_params_, close_delay);
478  }
479
480  virtual void OnStart() {
481    // Let start run for a bit.
482    message_loop_.RunAllPending();
483    base::PlatformThread::Sleep(
484        base::TimeDelta::FromMilliseconds(kStartRunTimeMs));
485  }
486
487 protected:
488  AudioParameters resampler_params_;
489  scoped_refptr<AudioOutputResampler> resampler_;
490};
491
492TEST_F(AudioOutputProxyTest, CreateAndClose) {
493  AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_);
494  proxy->Close();
495}
496
497#if defined(ENABLE_AUDIO_MIXER)
498TEST_F(AudioOutputProxyTest, CreateAndClose_Mixer) {
499  AudioOutputProxy* proxy = new AudioOutputProxy(mixer_);
500  proxy->Close();
501}
502#endif
503
504TEST_F(AudioOutputResamplerTest, CreateAndClose) {
505  AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
506  proxy->Close();
507}
508
509TEST_F(AudioOutputProxyTest, OpenAndClose) {
510  OpenAndClose(dispatcher_impl_);
511}
512
513#if defined(ENABLE_AUDIO_MIXER)
514TEST_F(AudioOutputProxyTest, OpenAndClose_Mixer) {
515  OpenAndClose(mixer_);
516}
517#endif
518
519TEST_F(AudioOutputResamplerTest, OpenAndClose) {
520  OpenAndClose(resampler_);
521}
522
523// Create a stream, and verify that it is closed after kTestCloseDelayMs.
524// if it doesn't start playing.
525TEST_F(AudioOutputProxyTest, CreateAndWait) {
526  CreateAndWait(dispatcher_impl_);
527}
528
529// Create a stream, and verify that it is closed after kTestCloseDelayMs.
530// if it doesn't start playing.
531TEST_F(AudioOutputResamplerTest, CreateAndWait) {
532  CreateAndWait(resampler_);
533}
534
535TEST_F(AudioOutputProxyTest, StartAndStop) {
536  StartAndStop(dispatcher_impl_);
537}
538
539#if defined(ENABLE_AUDIO_MIXER)
540TEST_F(AudioOutputProxyTest, StartAndStop_Mixer) {
541  StartAndStop(mixer_);
542}
543#endif
544
545TEST_F(AudioOutputResamplerTest, StartAndStop) {
546  StartAndStop(resampler_);
547}
548
549TEST_F(AudioOutputProxyTest, CloseAfterStop) {
550  CloseAfterStop(dispatcher_impl_);
551}
552
553#if defined(ENABLE_AUDIO_MIXER)
554TEST_F(AudioOutputProxyTest, CloseAfterStop_Mixer) {
555  CloseAfterStop(mixer_);
556}
557#endif
558
559TEST_F(AudioOutputResamplerTest, CloseAfterStop) {
560  CloseAfterStop(resampler_);
561}
562
563TEST_F(AudioOutputProxyTest, TwoStreams) {
564  TwoStreams(dispatcher_impl_);
565}
566
567#if defined(ENABLE_AUDIO_MIXER)
568TEST_F(AudioOutputProxyTest, TwoStreams_Mixer) {
569  TwoStreams(mixer_);
570}
571#endif
572
573TEST_F(AudioOutputResamplerTest, TwoStreams) {
574  TwoStreams(resampler_);
575}
576
577// Two streams: verify that second stream is allocated when the first
578// starts playing.
579TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) {
580  InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
581  TwoStreams_OnePlaying(dispatcher_impl_);
582}
583
584#if defined(ENABLE_AUDIO_MIXER)
585// Two streams: verify that only one device will be created.
586TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying_Mixer) {
587  MockAudioOutputStream stream(&manager_, params_);
588
589  InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs));
590
591  EXPECT_CALL(manager(), MakeAudioOutputStream(_))
592      .WillOnce(Return(&stream));
593
594  EXPECT_CALL(stream, Open())
595      .WillOnce(Return(true));
596  EXPECT_CALL(stream, Start(_))
597      .Times(1);
598  EXPECT_CALL(stream, SetVolume(_))
599      .Times(1);
600  EXPECT_CALL(stream, Stop())
601      .Times(1);
602  EXPECT_CALL(stream, Close())
603      .Times(1);
604
605  AudioOutputProxy* proxy1 = new AudioOutputProxy(mixer_);
606  AudioOutputProxy* proxy2 = new AudioOutputProxy(mixer_);
607  EXPECT_TRUE(proxy1->Open());
608  EXPECT_TRUE(proxy2->Open());
609
610  proxy1->Start(&callback_);
611  proxy1->Stop();
612
613  proxy1->Close();
614  proxy2->Close();
615  WaitForCloseTimer(kTestCloseDelayMs);
616}
617#endif
618
619TEST_F(AudioOutputResamplerTest, TwoStreams_OnePlaying) {
620  InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
621  TwoStreams_OnePlaying(resampler_);
622}
623
624// Two streams, both are playing. Dispatcher should not open a third stream.
625TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) {
626  InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
627  TwoStreams_BothPlaying(dispatcher_impl_);
628}
629
630#if defined(ENABLE_AUDIO_MIXER)
631// Two streams, both are playing. Still have to use single device.
632// Also verifies that every proxy stream gets its own pending_bytes.
633TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying_Mixer) {
634  MockAudioOutputStream stream(&manager_, params_);
635
636  InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs));
637
638  EXPECT_CALL(manager(), MakeAudioOutputStream(_))
639      .WillOnce(Return(&stream));
640
641  EXPECT_CALL(stream, Open())
642      .WillOnce(Return(true));
643  EXPECT_CALL(stream, Start(_))
644      .Times(1);
645  EXPECT_CALL(stream, SetVolume(_))
646      .Times(1);
647  EXPECT_CALL(stream, Stop())
648      .Times(1);
649  EXPECT_CALL(stream, Close())
650      .Times(1);
651
652  AudioOutputProxy* proxy1 = new AudioOutputProxy(mixer_);
653  AudioOutputProxy* proxy2 = new AudioOutputProxy(mixer_);
654  EXPECT_TRUE(proxy1->Open());
655  EXPECT_TRUE(proxy2->Open());
656
657  proxy1->Start(&callback_);
658
659  // Mute the proxy. Resulting stream should still have correct length.
660  proxy1->SetVolume(0.0);
661
662  uint8 zeroes[4] = {0, 0, 0, 0};
663  uint8 buf1[4] = {0};
664  EXPECT_CALL(callback_,
665      OnMoreData(NotNull(), 4,
666                 AllOf(Field(&AudioBuffersState::pending_bytes, 0),
667                       Field(&AudioBuffersState::hardware_delay_bytes, 0))))
668      .WillOnce(DoAll(SetArrayArgument<0>(zeroes, zeroes + sizeof(zeroes)),
669                      Return(4)));
670  mixer_->OnMoreData(buf1, sizeof(buf1), AudioBuffersState(0, 0));
671  proxy2->Start(&callback_);
672  uint8 buf2[4] = {0};
673  EXPECT_CALL(callback_,
674      OnMoreData(NotNull(), 4,
675                 AllOf(Field(&AudioBuffersState::pending_bytes, 4),
676                       Field(&AudioBuffersState::hardware_delay_bytes, 0))))
677      .WillOnce(DoAll(SetArrayArgument<0>(zeroes, zeroes + sizeof(zeroes)),
678                      Return(4)));
679  EXPECT_CALL(callback_,
680      OnMoreData(NotNull(), 4,
681                 AllOf(Field(&AudioBuffersState::pending_bytes, 0),
682                       Field(&AudioBuffersState::hardware_delay_bytes, 0))))
683      .WillOnce(DoAll(SetArrayArgument<0>(zeroes, zeroes + sizeof(zeroes)),
684                      Return(4)));
685  mixer_->OnMoreData(buf2, sizeof(buf2), AudioBuffersState(4, 0));
686  proxy1->Stop();
687  proxy2->Stop();
688
689  proxy1->Close();
690  proxy2->Close();
691  WaitForCloseTimer(kTestCloseDelayMs);
692}
693#endif
694
695TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) {
696  InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
697  TwoStreams_BothPlaying(resampler_);
698}
699
700TEST_F(AudioOutputProxyTest, OpenFailed) {
701  OpenFailed(dispatcher_impl_);
702}
703
704#if defined(ENABLE_AUDIO_MIXER)
705TEST_F(AudioOutputProxyTest, OpenFailed_Mixer) {
706  OpenFailed(mixer_);
707}
708#endif
709
710TEST_F(AudioOutputResamplerTest, OpenFailed) {
711  CommandLine::ForCurrentProcess()->AppendSwitch(
712      switches::kDisableAudioFallback);
713  OpenFailed(resampler_);
714}
715
716// Start() method failed.
717TEST_F(AudioOutputProxyTest, StartFailed) {
718  StartFailed(dispatcher_impl_);
719}
720
721#if defined(ENABLE_AUDIO_MIXER)
722// Start() method failed.
723TEST_F(AudioOutputProxyTest, StartFailed_Mixer) {
724  MockAudioOutputStream stream(&manager_, params_);
725
726  EXPECT_CALL(manager(), MakeAudioOutputStream(_))
727      .WillOnce(Return(&stream));
728  EXPECT_CALL(stream, Open())
729      .WillOnce(Return(true));
730  EXPECT_CALL(stream, Close())
731      .Times(1);
732  EXPECT_CALL(stream, Start(_))
733      .Times(1);
734  EXPECT_CALL(stream, SetVolume(_))
735      .Times(1);
736  EXPECT_CALL(stream, Stop())
737      .Times(1);
738
739  AudioOutputProxy* proxy1 = new AudioOutputProxy(mixer_);
740  AudioOutputProxy* proxy2 = new AudioOutputProxy(mixer_);
741  EXPECT_TRUE(proxy1->Open());
742  EXPECT_TRUE(proxy2->Open());
743  proxy1->Start(&callback_);
744  proxy1->Stop();
745  proxy1->Close();
746  WaitForCloseTimer(kTestCloseDelayMs);
747
748  // Verify expectation before continueing.
749  Mock::VerifyAndClear(&stream);
750
751  // |stream| is closed at this point. Start() should reopen it again.
752  EXPECT_CALL(manager(), MakeAudioOutputStream(_))
753      .WillOnce(Return(reinterpret_cast<AudioOutputStream*>(NULL)));
754
755  EXPECT_CALL(callback_, OnError(_, _))
756      .Times(1);
757
758  proxy2->Start(&callback_);
759
760  Mock::VerifyAndClear(&callback_);
761
762  proxy2->Close();
763  WaitForCloseTimer(kTestCloseDelayMs);
764}
765#endif
766
767TEST_F(AudioOutputResamplerTest, StartFailed) {
768  StartFailed(resampler_);
769}
770
771// Simulate AudioOutputStream::Create() failure with a low latency stream and
772// ensure AudioOutputResampler falls back to the high latency path.
773TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) {
774  MockAudioOutputStream stream(&manager_, params_);
775  EXPECT_CALL(manager(), MakeAudioOutputStream(_))
776      .Times(2)
777      .WillOnce(Return(static_cast<AudioOutputStream*>(NULL)))
778      .WillRepeatedly(Return(&stream));
779  EXPECT_CALL(stream, Open())
780      .WillOnce(Return(true));
781  EXPECT_CALL(stream, Close())
782      .Times(1);
783
784  AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
785  EXPECT_TRUE(proxy->Open());
786  proxy->Close();
787  WaitForCloseTimer(kTestCloseDelayMs);
788}
789
790// Simulate AudioOutputStream::Open() failure with a low latency stream and
791// ensure AudioOutputResampler falls back to the high latency path.
792TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) {
793  MockAudioOutputStream failed_stream(&manager_, params_);
794  MockAudioOutputStream okay_stream(&manager_, params_);
795  EXPECT_CALL(manager(), MakeAudioOutputStream(_))
796      .Times(2)
797      .WillOnce(Return(&failed_stream))
798      .WillRepeatedly(Return(&okay_stream));
799  EXPECT_CALL(failed_stream, Open())
800      .WillOnce(Return(false));
801  EXPECT_CALL(failed_stream, Close())
802      .Times(1);
803  EXPECT_CALL(okay_stream, Open())
804      .WillOnce(Return(true));
805  EXPECT_CALL(okay_stream, Close())
806      .Times(1);
807
808  AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
809  EXPECT_TRUE(proxy->Open());
810  proxy->Close();
811  WaitForCloseTimer(kTestCloseDelayMs);
812}
813
814// Simulate failures to open both the low latency and the fallback high latency
815// stream and ensure AudioOutputResampler terminates normally.
816TEST_F(AudioOutputResamplerTest, LowLatencyFallbackFailed) {
817  EXPECT_CALL(manager(), MakeAudioOutputStream(_))
818      .Times(2)
819      .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
820
821  AudioOutputProxy* proxy = new AudioOutputProxy(resampler_);
822  EXPECT_FALSE(proxy->Open());
823  proxy->Close();
824  WaitForCloseTimer(kTestCloseDelayMs);
825}
826
827// Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls
828// eventually followed by one which fails; root cause of http://crbug.com/150619
829TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) {
830  MockAudioOutputStream stream1(&manager_, params_);
831  MockAudioOutputStream stream2(&manager_, params_);
832  MockAudioOutputStream stream3(&manager_, params_);
833
834  // Setup the mock such that all three streams are successfully created.
835  EXPECT_CALL(manager(), MakeAudioOutputStream(_))
836      .WillOnce(Return(&stream1))
837      .WillOnce(Return(&stream2))
838      .WillOnce(Return(&stream3))
839      .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
840
841  // Stream1 should be able to successfully open and start.
842  EXPECT_CALL(stream1, Open())
843      .WillOnce(Return(true));
844  EXPECT_CALL(stream1, Close())
845      .Times(1);
846  EXPECT_CALL(stream1, SetVolume(_))
847      .Times(1);
848
849  // Stream2 should also be able to successfully open and start.
850  EXPECT_CALL(stream2, Open())
851      .WillOnce(Return(true));
852  EXPECT_CALL(stream2, Close())
853      .Times(1);
854  EXPECT_CALL(stream2, SetVolume(_))
855      .Times(1);
856
857  // Stream3 should fail on Open() (yet still be closed since
858  // MakeAudioOutputStream returned a valid AudioOutputStream object).
859  EXPECT_CALL(stream3, Open())
860      .WillOnce(Return(false));
861  EXPECT_CALL(stream3, Close())
862      .Times(1);
863
864  // Open and start the first proxy and stream.
865  AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_);
866  EXPECT_TRUE(proxy1->Open());
867  proxy1->Start(&callback_);
868  OnStart();
869
870  // Open and start the second proxy and stream.
871  AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_);
872  EXPECT_TRUE(proxy2->Open());
873  proxy2->Start(&callback_);
874  OnStart();
875
876  // Attempt to open the third stream which should fail.
877  AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_);
878  EXPECT_FALSE(proxy3->Open());
879
880  // Perform the required Stop()/Close() shutdown dance for each proxy.  Under
881  // the hood each proxy should correctly call CloseStream() if OpenStream()
882  // succeeded or not.
883  proxy3->Stop();
884  proxy3->Close();
885  proxy2->Stop();
886  proxy2->Close();
887  proxy1->Stop();
888  proxy1->Close();
889
890  // Wait for all of the messages to fly and then verify stream behavior.
891  WaitForCloseTimer(kTestCloseDelayMs);
892  EXPECT_TRUE(stream1.stop_called());
893  EXPECT_TRUE(stream1.start_called());
894  EXPECT_TRUE(stream2.stop_called());
895  EXPECT_TRUE(stream2.start_called());
896  EXPECT_FALSE(stream3.stop_called());
897  EXPECT_FALSE(stream3.start_called());
898}
899
900}  // namespace media
901