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