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 "media/audio/audio_manager.h"
     10 #include "media/audio/audio_manager_base.h"
     11 #include "media/audio/audio_output_dispatcher_impl.h"
     12 #include "media/audio/audio_output_proxy.h"
     13 #include "media/audio/audio_output_resampler.h"
     14 #include "media/audio/fake_audio_output_stream.h"
     15 #include "testing/gmock/include/gmock/gmock.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 using ::testing::_;
     19 using ::testing::AllOf;
     20 using ::testing::DoAll;
     21 using ::testing::Field;
     22 using ::testing::Mock;
     23 using ::testing::NotNull;
     24 using ::testing::Return;
     25 using ::testing::SetArrayArgument;
     26 using media::AudioBus;
     27 using media::AudioBuffersState;
     28 using media::AudioInputStream;
     29 using media::AudioManager;
     30 using media::AudioManagerBase;
     31 using media::AudioOutputDispatcher;
     32 using media::AudioOutputProxy;
     33 using media::AudioOutputStream;
     34 using media::AudioParameters;
     35 using media::FakeAudioOutputStream;
     36 
     37 namespace {
     38 
     39 static const int kTestCloseDelayMs = 100;
     40 
     41 // Used in the test where we don't want a stream to be closed unexpectedly.
     42 static const int kTestBigCloseDelaySeconds = 1000;
     43 
     44 // Delay between callbacks to AudioSourceCallback::OnMoreData.
     45 static const int kOnMoreDataCallbackDelayMs = 10;
     46 
     47 // Let start run long enough for many OnMoreData callbacks to occur.
     48 static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10;
     49 
     50 class MockAudioOutputStream : public AudioOutputStream {
     51  public:
     52   MockAudioOutputStream(AudioManagerBase* manager,
     53                         const AudioParameters& params)
     54       : start_called_(false),
     55         stop_called_(false),
     56         params_(params),
     57         fake_output_stream_(
     58             FakeAudioOutputStream::MakeFakeStream(manager, params_)) {
     59   }
     60 
     61   void Start(AudioSourceCallback* callback) {
     62     start_called_ = true;
     63     fake_output_stream_->Start(callback);
     64   }
     65 
     66   void Stop() {
     67     stop_called_ = true;
     68     fake_output_stream_->Stop();
     69   }
     70 
     71   ~MockAudioOutputStream() {}
     72 
     73   bool start_called() { return start_called_; }
     74   bool stop_called() { return stop_called_; }
     75 
     76   MOCK_METHOD0(Open, bool());
     77   MOCK_METHOD1(SetVolume, void(double volume));
     78   MOCK_METHOD1(GetVolume, void(double* volume));
     79   MOCK_METHOD0(Close, void());
     80 
     81  private:
     82   bool start_called_;
     83   bool stop_called_;
     84   AudioParameters params_;
     85   scoped_ptr<AudioOutputStream> fake_output_stream_;
     86 };
     87 
     88 class MockAudioManager : public AudioManagerBase {
     89  public:
     90   MockAudioManager() {}
     91   virtual ~MockAudioManager() {
     92     Shutdown();
     93   }
     94 
     95   MOCK_METHOD0(HasAudioOutputDevices, bool());
     96   MOCK_METHOD0(HasAudioInputDevices, bool());
     97   MOCK_METHOD0(GetAudioInputDeviceModel, string16());
     98   MOCK_METHOD2(MakeAudioOutputStream, AudioOutputStream*(
     99       const AudioParameters& params, const std::string& input_device_id));
    100   MOCK_METHOD2(MakeAudioOutputStreamProxy, AudioOutputStream*(
    101       const AudioParameters& params, const std::string& input_device_id));
    102   MOCK_METHOD2(MakeAudioInputStream, AudioInputStream*(
    103       const AudioParameters& params, const std::string& device_id));
    104   MOCK_METHOD0(ShowAudioInputSettings, void());
    105   MOCK_METHOD0(GetMessageLoop, scoped_refptr<base::MessageLoopProxy>());
    106   MOCK_METHOD1(GetAudioInputDeviceNames, void(
    107       media::AudioDeviceNames* device_name));
    108 
    109   MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*(
    110       const AudioParameters& params));
    111   MOCK_METHOD2(MakeLowLatencyOutputStream, AudioOutputStream*(
    112       const AudioParameters& params, const std::string& input_device_id));
    113   MOCK_METHOD2(MakeLinearInputStream, AudioInputStream*(
    114       const AudioParameters& params, const std::string& device_id));
    115   MOCK_METHOD2(MakeLowLatencyInputStream, AudioInputStream*(
    116       const AudioParameters& params, const std::string& device_id));
    117   MOCK_METHOD1(GetPreferredOutputStreamParameters, AudioParameters(
    118       const AudioParameters& params));
    119 };
    120 
    121 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
    122  public:
    123   int OnMoreData(AudioBus* audio_bus, AudioBuffersState buffers_state) {
    124     audio_bus->Zero();
    125     return audio_bus->frames();
    126   }
    127   int OnMoreIOData(AudioBus* source, AudioBus* dest,
    128                    AudioBuffersState buffers_state) {
    129     return OnMoreData(dest, buffers_state);
    130   }
    131   MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
    132 };
    133 
    134 }  // namespace
    135 
    136 namespace media {
    137 
    138 class AudioOutputProxyTest : public testing::Test {
    139  protected:
    140   virtual void SetUp() {
    141     EXPECT_CALL(manager_, GetMessageLoop())
    142         .WillRepeatedly(Return(message_loop_.message_loop_proxy()));
    143     InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs));
    144   }
    145 
    146   virtual void TearDown() {
    147     // All paused proxies should have been closed at this point.
    148     EXPECT_EQ(0u, dispatcher_impl_->paused_proxies_);
    149 
    150     // This is necessary to free all proxy objects that have been
    151     // closed by the test.
    152     message_loop_.RunUntilIdle();
    153   }
    154 
    155   virtual void InitDispatcher(base::TimeDelta close_delay) {
    156     // Use a low sample rate and large buffer size when testing otherwise the
    157     // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
    158     // RunUntilIdle() will never terminate.
    159     params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
    160                               CHANNEL_LAYOUT_STEREO, 8000, 16, 2048);
    161     dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(),
    162                                                      params_,
    163                                                      std::string(),
    164                                                      close_delay);
    165 
    166     // Necessary to know how long the dispatcher will wait before posting
    167     // StopStreamTask.
    168     pause_delay_ = dispatcher_impl_->pause_delay_;
    169   }
    170 
    171   virtual void OnStart() {}
    172 
    173   MockAudioManager& manager() {
    174     return manager_;
    175   }
    176 
    177   // Wait for the close timer to fire.
    178   void WaitForCloseTimer(const int timer_delay_ms) {
    179     message_loop_.RunUntilIdle();  // OpenTask() may reset the timer.
    180     base::PlatformThread::Sleep(
    181         base::TimeDelta::FromMilliseconds(timer_delay_ms) * 2);
    182     message_loop_.RunUntilIdle();
    183   }
    184 
    185   // Methods that do actual tests.
    186   void OpenAndClose(AudioOutputDispatcher* dispatcher) {
    187     MockAudioOutputStream stream(&manager_, params_);
    188 
    189     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    190         .WillOnce(Return(&stream));
    191     EXPECT_CALL(stream, Open())
    192         .WillOnce(Return(true));
    193     EXPECT_CALL(stream, Close())
    194         .Times(1);
    195 
    196     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
    197     EXPECT_TRUE(proxy->Open());
    198     proxy->Close();
    199     WaitForCloseTimer(kTestCloseDelayMs);
    200   }
    201 
    202   // Create a stream, and then calls Start() and Stop().
    203   void StartAndStop(AudioOutputDispatcher* dispatcher) {
    204     MockAudioOutputStream stream(&manager_, params_);
    205 
    206     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    207         .WillOnce(Return(&stream));
    208     EXPECT_CALL(stream, Open())
    209         .WillOnce(Return(true));
    210     EXPECT_CALL(stream, SetVolume(_))
    211         .Times(1);
    212     EXPECT_CALL(stream, Close())
    213         .Times(1);
    214 
    215     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
    216     EXPECT_TRUE(proxy->Open());
    217 
    218     proxy->Start(&callback_);
    219     OnStart();
    220     proxy->Stop();
    221 
    222     proxy->Close();
    223     WaitForCloseTimer(kTestCloseDelayMs);
    224     EXPECT_TRUE(stream.stop_called());
    225     EXPECT_TRUE(stream.start_called());
    226   }
    227 
    228   // Verify that the stream is closed after Stop is called.
    229   void CloseAfterStop(AudioOutputDispatcher* dispatcher) {
    230     MockAudioOutputStream stream(&manager_, params_);
    231 
    232     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    233         .WillOnce(Return(&stream));
    234     EXPECT_CALL(stream, Open())
    235         .WillOnce(Return(true));
    236     EXPECT_CALL(stream, SetVolume(_))
    237         .Times(1);
    238     EXPECT_CALL(stream, Close())
    239         .Times(1);
    240 
    241     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
    242     EXPECT_TRUE(proxy->Open());
    243 
    244     proxy->Start(&callback_);
    245     OnStart();
    246     proxy->Stop();
    247 
    248     // Wait for StopStream() to post StopStreamTask().
    249     base::PlatformThread::Sleep(pause_delay_ * 2);
    250     WaitForCloseTimer(kTestCloseDelayMs);
    251 
    252     // Verify expectation before calling Close().
    253     Mock::VerifyAndClear(&stream);
    254 
    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 open.
    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     EXPECT_CALL(stream, Close())
    269         .Times(1);
    270 
    271     AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
    272     AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
    273     EXPECT_TRUE(proxy1->Open());
    274     EXPECT_TRUE(proxy2->Open());
    275     proxy1->Close();
    276     proxy2->Close();
    277     WaitForCloseTimer(kTestCloseDelayMs);
    278     EXPECT_FALSE(stream.stop_called());
    279     EXPECT_FALSE(stream.start_called());
    280   }
    281 
    282   // Open() method failed.
    283   void OpenFailed(AudioOutputDispatcher* dispatcher) {
    284     MockAudioOutputStream stream(&manager_, params_);
    285 
    286     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    287         .WillOnce(Return(&stream));
    288     EXPECT_CALL(stream, Open())
    289         .WillOnce(Return(false));
    290     EXPECT_CALL(stream, Close())
    291         .Times(1);
    292 
    293     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
    294     EXPECT_FALSE(proxy->Open());
    295     proxy->Close();
    296     WaitForCloseTimer(kTestCloseDelayMs);
    297     EXPECT_FALSE(stream.stop_called());
    298     EXPECT_FALSE(stream.start_called());
    299   }
    300 
    301   void CreateAndWait(AudioOutputDispatcher* dispatcher) {
    302     MockAudioOutputStream stream(&manager_, params_);
    303 
    304     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    305         .WillOnce(Return(&stream));
    306     EXPECT_CALL(stream, Open())
    307         .WillOnce(Return(true));
    308     EXPECT_CALL(stream, Close())
    309         .Times(1);
    310 
    311     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
    312     EXPECT_TRUE(proxy->Open());
    313 
    314     // Simulate a delay.
    315     base::PlatformThread::Sleep(
    316         base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2);
    317     message_loop_.RunUntilIdle();
    318 
    319     // Verify expectation before calling Close().
    320     Mock::VerifyAndClear(&stream);
    321 
    322     proxy->Close();
    323     EXPECT_FALSE(stream.stop_called());
    324     EXPECT_FALSE(stream.start_called());
    325   }
    326 
    327   void TwoStreams_OnePlaying(AudioOutputDispatcher* dispatcher) {
    328     MockAudioOutputStream stream1(&manager_, params_);
    329     MockAudioOutputStream stream2(&manager_, params_);
    330 
    331     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    332         .WillOnce(Return(&stream1))
    333         .WillOnce(Return(&stream2));
    334 
    335     EXPECT_CALL(stream1, Open())
    336         .WillOnce(Return(true));
    337     EXPECT_CALL(stream1, SetVolume(_))
    338         .Times(1);
    339     EXPECT_CALL(stream1, Close())
    340         .Times(1);
    341 
    342     EXPECT_CALL(stream2, Open())
    343         .WillOnce(Return(true));
    344     EXPECT_CALL(stream2, Close())
    345         .Times(1);
    346 
    347     AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
    348     AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
    349     EXPECT_TRUE(proxy1->Open());
    350     EXPECT_TRUE(proxy2->Open());
    351 
    352     proxy1->Start(&callback_);
    353     message_loop_.RunUntilIdle();
    354     OnStart();
    355     proxy1->Stop();
    356 
    357     proxy1->Close();
    358     proxy2->Close();
    359     EXPECT_TRUE(stream1.stop_called());
    360     EXPECT_TRUE(stream1.start_called());
    361     EXPECT_FALSE(stream2.stop_called());
    362     EXPECT_FALSE(stream2.start_called());
    363   }
    364 
    365   void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) {
    366     MockAudioOutputStream stream1(&manager_, params_);
    367     MockAudioOutputStream stream2(&manager_, params_);
    368 
    369     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    370         .WillOnce(Return(&stream1))
    371         .WillOnce(Return(&stream2));
    372 
    373     EXPECT_CALL(stream1, Open())
    374         .WillOnce(Return(true));
    375     EXPECT_CALL(stream1, SetVolume(_))
    376         .Times(1);
    377     EXPECT_CALL(stream1, Close())
    378         .Times(1);
    379 
    380     EXPECT_CALL(stream2, Open())
    381         .WillOnce(Return(true));
    382     EXPECT_CALL(stream2, SetVolume(_))
    383         .Times(1);
    384     EXPECT_CALL(stream2, Close())
    385         .Times(1);
    386 
    387     AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
    388     AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
    389     EXPECT_TRUE(proxy1->Open());
    390     EXPECT_TRUE(proxy2->Open());
    391 
    392     proxy1->Start(&callback_);
    393     proxy2->Start(&callback_);
    394     OnStart();
    395     proxy1->Stop();
    396     proxy2->Stop();
    397 
    398     proxy1->Close();
    399     proxy2->Close();
    400     EXPECT_TRUE(stream1.stop_called());
    401     EXPECT_TRUE(stream1.start_called());
    402     EXPECT_TRUE(stream2.stop_called());
    403     EXPECT_TRUE(stream2.start_called());
    404   }
    405 
    406   void StartFailed(AudioOutputDispatcher* dispatcher) {
    407     MockAudioOutputStream stream(&manager_, params_);
    408 
    409     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    410         .WillOnce(Return(&stream));
    411     EXPECT_CALL(stream, Open())
    412         .WillOnce(Return(true));
    413     EXPECT_CALL(stream, Close())
    414         .Times(1);
    415 
    416     AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
    417     EXPECT_TRUE(proxy->Open());
    418 
    419     // Simulate a delay.
    420     base::PlatformThread::Sleep(
    421         base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2);
    422     message_loop_.RunUntilIdle();
    423 
    424     // Verify expectation before calling Close().
    425     Mock::VerifyAndClear(&stream);
    426 
    427     // |stream| is closed at this point. Start() should reopen it again.
    428     EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    429         .Times(2)
    430         .WillRepeatedly(Return(reinterpret_cast<AudioOutputStream*>(NULL)));
    431 
    432     EXPECT_CALL(callback_, OnError(_))
    433         .Times(2);
    434 
    435     proxy->Start(&callback_);
    436 
    437     // Double Start() in the error case should be allowed since it's possible a
    438     // callback may not have had time to process the OnError() in between.
    439     proxy->Stop();
    440     proxy->Start(&callback_);
    441 
    442     Mock::VerifyAndClear(&callback_);
    443 
    444     proxy->Close();
    445   }
    446 
    447   base::MessageLoop message_loop_;
    448   scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_;
    449   base::TimeDelta pause_delay_;
    450   MockAudioManager manager_;
    451   MockAudioSourceCallback callback_;
    452   AudioParameters params_;
    453 };
    454 
    455 class AudioOutputResamplerTest : public AudioOutputProxyTest {
    456  public:
    457   virtual void TearDown() {
    458     AudioOutputProxyTest::TearDown();
    459   }
    460 
    461   virtual void InitDispatcher(base::TimeDelta close_delay) OVERRIDE {
    462     AudioOutputProxyTest::InitDispatcher(close_delay);
    463     // Use a low sample rate and large buffer size when testing otherwise the
    464     // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
    465     // RunUntilIdle() will never terminate.
    466     resampler_params_ = AudioParameters(
    467         AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
    468         16000, 16, 1024);
    469     resampler_ = new AudioOutputResampler(
    470         &manager(), params_, resampler_params_, std::string(), close_delay);
    471   }
    472 
    473   virtual void OnStart() OVERRIDE {
    474     // Let start run for a bit.
    475     message_loop_.RunUntilIdle();
    476     base::PlatformThread::Sleep(
    477         base::TimeDelta::FromMilliseconds(kStartRunTimeMs));
    478   }
    479 
    480  protected:
    481   AudioParameters resampler_params_;
    482   scoped_refptr<AudioOutputResampler> resampler_;
    483 };
    484 
    485 TEST_F(AudioOutputProxyTest, CreateAndClose) {
    486   AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_.get());
    487   proxy->Close();
    488 }
    489 
    490 TEST_F(AudioOutputResamplerTest, CreateAndClose) {
    491   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
    492   proxy->Close();
    493 }
    494 
    495 TEST_F(AudioOutputProxyTest, OpenAndClose) {
    496   OpenAndClose(dispatcher_impl_.get());
    497 }
    498 
    499 TEST_F(AudioOutputResamplerTest, OpenAndClose) {
    500   OpenAndClose(resampler_.get());
    501 }
    502 
    503 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
    504 // if it doesn't start playing.
    505 TEST_F(AudioOutputProxyTest, CreateAndWait) {
    506   CreateAndWait(dispatcher_impl_.get());
    507 }
    508 
    509 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
    510 // if it doesn't start playing.
    511 TEST_F(AudioOutputResamplerTest, CreateAndWait) {
    512   CreateAndWait(resampler_.get());
    513 }
    514 
    515 TEST_F(AudioOutputProxyTest, StartAndStop) {
    516   StartAndStop(dispatcher_impl_.get());
    517 }
    518 
    519 TEST_F(AudioOutputResamplerTest, StartAndStop) {
    520   StartAndStop(resampler_.get());
    521 }
    522 
    523 TEST_F(AudioOutputProxyTest, CloseAfterStop) {
    524   CloseAfterStop(dispatcher_impl_.get());
    525 }
    526 
    527 TEST_F(AudioOutputResamplerTest, CloseAfterStop) {
    528   CloseAfterStop(resampler_.get());
    529 }
    530 
    531 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_.get()); }
    532 
    533 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_.get()); }
    534 
    535 // Two streams: verify that second stream is allocated when the first
    536 // starts playing.
    537 TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) {
    538   InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
    539   TwoStreams_OnePlaying(dispatcher_impl_.get());
    540 }
    541 
    542 TEST_F(AudioOutputResamplerTest, TwoStreams_OnePlaying) {
    543   InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
    544   TwoStreams_OnePlaying(resampler_.get());
    545 }
    546 
    547 // Two streams, both are playing. Dispatcher should not open a third stream.
    548 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) {
    549   InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
    550   TwoStreams_BothPlaying(dispatcher_impl_.get());
    551 }
    552 
    553 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) {
    554   InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds));
    555   TwoStreams_BothPlaying(resampler_.get());
    556 }
    557 
    558 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_.get()); }
    559 
    560 // Start() method failed.
    561 TEST_F(AudioOutputProxyTest, StartFailed) {
    562   StartFailed(dispatcher_impl_.get());
    563 }
    564 
    565 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_.get()); }
    566 
    567 // Simulate AudioOutputStream::Create() failure with a low latency stream and
    568 // ensure AudioOutputResampler falls back to the high latency path.
    569 TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) {
    570   MockAudioOutputStream stream(&manager_, params_);
    571   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    572       .Times(2)
    573       .WillOnce(Return(static_cast<AudioOutputStream*>(NULL)))
    574       .WillRepeatedly(Return(&stream));
    575   EXPECT_CALL(stream, Open())
    576       .WillOnce(Return(true));
    577   EXPECT_CALL(stream, Close())
    578       .Times(1);
    579 
    580   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
    581   EXPECT_TRUE(proxy->Open());
    582   proxy->Close();
    583   WaitForCloseTimer(kTestCloseDelayMs);
    584 }
    585 
    586 // Simulate AudioOutputStream::Open() failure with a low latency stream and
    587 // ensure AudioOutputResampler falls back to the high latency path.
    588 TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) {
    589   MockAudioOutputStream failed_stream(&manager_, params_);
    590   MockAudioOutputStream okay_stream(&manager_, params_);
    591   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    592       .Times(2)
    593       .WillOnce(Return(&failed_stream))
    594       .WillRepeatedly(Return(&okay_stream));
    595   EXPECT_CALL(failed_stream, Open())
    596       .WillOnce(Return(false));
    597   EXPECT_CALL(failed_stream, Close())
    598       .Times(1);
    599   EXPECT_CALL(okay_stream, Open())
    600       .WillOnce(Return(true));
    601   EXPECT_CALL(okay_stream, Close())
    602       .Times(1);
    603 
    604   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
    605   EXPECT_TRUE(proxy->Open());
    606   proxy->Close();
    607   WaitForCloseTimer(kTestCloseDelayMs);
    608 }
    609 
    610 // Simulate failures to open both the low latency and the fallback high latency
    611 // stream and ensure AudioOutputResampler falls back to a fake stream.
    612 TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) {
    613   MockAudioOutputStream okay_stream(&manager_, params_);
    614 
    615 // Only Windows has a high latency output driver that is not the same as the low
    616 // latency path.
    617 #if defined(OS_WIN)
    618   static const int kFallbackCount = 2;
    619 #else
    620   static const int kFallbackCount = 1;
    621 #endif
    622   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    623       .Times(kFallbackCount)
    624       .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
    625 
    626   // To prevent shared memory issues the sample rate and buffer size should
    627   // match the input stream parameters.
    628   EXPECT_CALL(manager(), MakeAudioOutputStream(AllOf(
    629       testing::Property(&AudioParameters::format, AudioParameters::AUDIO_FAKE),
    630       testing::Property(&AudioParameters::sample_rate, params_.sample_rate()),
    631       testing::Property(
    632           &AudioParameters::frames_per_buffer, params_.frames_per_buffer())),
    633                          _))
    634       .Times(1)
    635       .WillOnce(Return(&okay_stream));
    636   EXPECT_CALL(okay_stream, Open())
    637       .WillOnce(Return(true));
    638   EXPECT_CALL(okay_stream, Close())
    639       .Times(1);
    640 
    641   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
    642   EXPECT_TRUE(proxy->Open());
    643   proxy->Close();
    644   WaitForCloseTimer(kTestCloseDelayMs);
    645 }
    646 
    647 // Simulate failures to open both the low latency, the fallback high latency
    648 // stream, and the fake audio output stream and ensure AudioOutputResampler
    649 // terminates normally.
    650 TEST_F(AudioOutputResamplerTest, AllFallbackFailed) {
    651 // Only Windows has a high latency output driver that is not the same as the low
    652 // latency path.
    653 #if defined(OS_WIN)
    654   static const int kFallbackCount = 3;
    655 #else
    656   static const int kFallbackCount = 2;
    657 #endif
    658   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    659       .Times(kFallbackCount)
    660       .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
    661 
    662   AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get());
    663   EXPECT_FALSE(proxy->Open());
    664   proxy->Close();
    665   WaitForCloseTimer(kTestCloseDelayMs);
    666 }
    667 
    668 // Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls
    669 // eventually followed by one which fails; root cause of http://crbug.com/150619
    670 TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) {
    671   MockAudioOutputStream stream1(&manager_, params_);
    672   MockAudioOutputStream stream2(&manager_, params_);
    673   MockAudioOutputStream stream3(&manager_, params_);
    674 
    675   // Setup the mock such that all three streams are successfully created.
    676   EXPECT_CALL(manager(), MakeAudioOutputStream(_, _))
    677       .WillOnce(Return(&stream1))
    678       .WillOnce(Return(&stream2))
    679       .WillOnce(Return(&stream3))
    680       .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
    681 
    682   // Stream1 should be able to successfully open and start.
    683   EXPECT_CALL(stream1, Open())
    684       .WillOnce(Return(true));
    685   EXPECT_CALL(stream1, Close())
    686       .Times(1);
    687   EXPECT_CALL(stream1, SetVolume(_))
    688       .Times(1);
    689 
    690   // Stream2 should also be able to successfully open and start.
    691   EXPECT_CALL(stream2, Open())
    692       .WillOnce(Return(true));
    693   EXPECT_CALL(stream2, Close())
    694       .Times(1);
    695   EXPECT_CALL(stream2, SetVolume(_))
    696       .Times(1);
    697 
    698   // Stream3 should fail on Open() (yet still be closed since
    699   // MakeAudioOutputStream returned a valid AudioOutputStream object).
    700   EXPECT_CALL(stream3, Open())
    701       .WillOnce(Return(false));
    702   EXPECT_CALL(stream3, Close())
    703       .Times(1);
    704 
    705   // Open and start the first proxy and stream.
    706   AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_.get());
    707   EXPECT_TRUE(proxy1->Open());
    708   proxy1->Start(&callback_);
    709   OnStart();
    710 
    711   // Open and start the second proxy and stream.
    712   AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_.get());
    713   EXPECT_TRUE(proxy2->Open());
    714   proxy2->Start(&callback_);
    715   OnStart();
    716 
    717   // Attempt to open the third stream which should fail.
    718   AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_.get());
    719   EXPECT_FALSE(proxy3->Open());
    720 
    721   // Perform the required Stop()/Close() shutdown dance for each proxy.  Under
    722   // the hood each proxy should correctly call CloseStream() if OpenStream()
    723   // succeeded or not.
    724   proxy3->Stop();
    725   proxy3->Close();
    726   proxy2->Stop();
    727   proxy2->Close();
    728   proxy1->Stop();
    729   proxy1->Close();
    730 
    731   // Wait for all of the messages to fly and then verify stream behavior.
    732   WaitForCloseTimer(kTestCloseDelayMs);
    733   EXPECT_TRUE(stream1.stop_called());
    734   EXPECT_TRUE(stream1.start_called());
    735   EXPECT_TRUE(stream2.stop_called());
    736   EXPECT_TRUE(stream2.start_called());
    737   EXPECT_FALSE(stream3.stop_called());
    738   EXPECT_FALSE(stream3.start_called());
    739 }
    740 
    741 }  // namespace media
    742