Home | History | Annotate | Download | only in audio
      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 "base/run_loop.h"
     10 #include "media/audio/audio_manager.h"
     11 #include "media/audio/audio_manager_base.h"
     12 #include "media/audio/audio_output_dispatcher_impl.h"
     13 #include "media/audio/audio_output_proxy.h"
     14 #include "media/audio/audio_output_resampler.h"
     15 #include "media/audio/fake_audio_log_factory.h"
     16 #include "media/audio/fake_audio_output_stream.h"
     17 #include "testing/gmock/include/gmock/gmock.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 
     20 using ::testing::_;
     21 using ::testing::AllOf;
     22 using ::testing::DoAll;
     23 using ::testing::Field;
     24 using ::testing::Mock;
     25 using ::testing::NotNull;
     26 using ::testing::Return;
     27 using ::testing::SetArrayArgument;
     28 using media::AudioBus;
     29 using media::AudioBuffersState;
     30 using media::AudioInputStream;
     31 using media::AudioManager;
     32 using media::AudioManagerBase;
     33 using media::AudioOutputDispatcher;
     34 using media::AudioOutputProxy;
     35 using media::AudioOutputStream;
     36 using media::AudioParameters;
     37 using media::FakeAudioOutputStream;
     38 
     39 namespace {
     40 
     41 static const int kTestCloseDelayMs = 10;
     42 
     43 // Delay between callbacks to AudioSourceCallback::OnMoreData.
     44 static const int kOnMoreDataCallbackDelayMs = 10;
     45 
     46 // Let start run long enough for many OnMoreData callbacks to occur.
     47 static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10;
     48 
     49 class MockAudioOutputStream : public AudioOutputStream {
     50  public:
     51   MockAudioOutputStream(AudioManagerBase* manager,
     52                         const AudioParameters& params)
     53       : start_called_(false),
     54         stop_called_(false),
     55         params_(params),
     56         fake_output_stream_(
     57             FakeAudioOutputStream::MakeFakeStream(manager, params_)) {
     58   }
     59 
     60   void Start(AudioSourceCallback* callback) {
     61     start_called_ = true;
     62     fake_output_stream_->Start(callback);
     63   }
     64 
     65   void Stop() {
     66     stop_called_ = true;
     67     fake_output_stream_->Stop();
     68   }
     69 
     70   ~MockAudioOutputStream() {}
     71 
     72   bool start_called() { return start_called_; }
     73   bool stop_called() { return stop_called_; }
     74 
     75   MOCK_METHOD0(Open, bool());
     76   MOCK_METHOD1(SetVolume, void(double volume));
     77   MOCK_METHOD1(GetVolume, void(double* volume));
     78   MOCK_METHOD0(Close, void());
     79 
     80  private:
     81   bool start_called_;
     82   bool stop_called_;
     83   AudioParameters params_;
     84   scoped_ptr<AudioOutputStream> fake_output_stream_;
     85 };
     86 
     87 class MockAudioManager : public AudioManagerBase {
     88  public:
     89   MockAudioManager() : AudioManagerBase(&fake_audio_log_factory_) {}
     90   virtual ~MockAudioManager() {
     91     Shutdown();
     92   }
     93 
     94   MOCK_METHOD0(HasAudioOutputDevices, bool());
     95   MOCK_METHOD0(HasAudioInputDevices, bool());
     96   MOCK_METHOD0(GetAudioInputDeviceModel, base::string16());
     97   MOCK_METHOD3(MakeAudioOutputStream, AudioOutputStream*(
     98       const AudioParameters& params,
     99       const std::string& device_id,
    100       const std::string& input_device_id));
    101   MOCK_METHOD3(MakeAudioOutputStreamProxy, AudioOutputStream*(
    102       const AudioParameters& params,
    103       const std::string& device_id,
    104       const std::string& input_device_id));
    105   MOCK_METHOD2(MakeAudioInputStream, AudioInputStream*(
    106       const AudioParameters& params, const std::string& device_id));
    107   MOCK_METHOD0(ShowAudioInputSettings, void());
    108   MOCK_METHOD0(GetMessageLoop, scoped_refptr<base::MessageLoopProxy>());
    109   MOCK_METHOD0(GetWorkerLoop, scoped_refptr<base::MessageLoopProxy>());
    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_, GetMessageLoop())
    150         .WillRepeatedly(Return(message_loop_.message_loop_proxy()));
    151     EXPECT_CALL(manager_, GetWorkerLoop())
    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
    753