// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdint.h>

#include <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "media/audio/audio_manager.h"
#include "media/audio/audio_manager_base.h"
#include "media/audio/audio_output_dispatcher_impl.h"
#include "media/audio/audio_output_proxy.h"
#include "media/audio/audio_output_resampler.h"
#include "media/audio/fake_audio_log_factory.h"
#include "media/audio/fake_audio_output_stream.h"
#include "media/audio/test_audio_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::AllOf;
using ::testing::DoAll;
using ::testing::Field;
using ::testing::Mock;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::SetArrayArgument;
using media::AudioBus;
using media::AudioInputStream;
using media::AudioManager;
using media::AudioManagerBase;
using media::AudioOutputDispatcher;
using media::AudioOutputProxy;
using media::AudioOutputStream;
using media::AudioParameters;
using media::FakeAudioOutputStream;
using media::TestAudioThread;

namespace {

static const int kTestCloseDelayMs = 10;

// Delay between callbacks to AudioSourceCallback::OnMoreData.
static const int kOnMoreDataCallbackDelayMs = 10;

// Let start run long enough for many OnMoreData callbacks to occur.
static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10;

// Dummy function.
std::unique_ptr<media::AudioDebugRecorder> RegisterDebugRecording(
    const media::AudioParameters& params) {
  return nullptr;
}

class MockAudioOutputStream : public AudioOutputStream {
 public:
  MockAudioOutputStream(AudioManagerBase* manager,
                        const AudioParameters& params)
      : start_called_(false),
        stop_called_(false),
        params_(params),
        fake_output_stream_(
            FakeAudioOutputStream::MakeFakeStream(manager, params_)) {
  }

  void Start(AudioSourceCallback* callback) override {
    start_called_ = true;
    fake_output_stream_->Start(callback);
  }

  void Stop() override {
    stop_called_ = true;
    fake_output_stream_->Stop();
  }

  ~MockAudioOutputStream() override = default;

  bool start_called() { return start_called_; }
  bool stop_called() { return stop_called_; }

  MOCK_METHOD0(Open, bool());
  MOCK_METHOD1(SetVolume, void(double volume));
  MOCK_METHOD1(GetVolume, void(double* volume));
  MOCK_METHOD0(Close, void());
  MOCK_METHOD0(Flush, void());

 private:
  bool start_called_;
  bool stop_called_;
  AudioParameters params_;
  std::unique_ptr<AudioOutputStream> fake_output_stream_;
};

class MockAudioManager : public AudioManagerBase {
 public:
  MockAudioManager()
      : AudioManagerBase(std::make_unique<TestAudioThread>(),
                         &fake_audio_log_factory_) {}
  ~MockAudioManager() override { Shutdown(); }

  MOCK_METHOD3(MakeAudioOutputStream,
               AudioOutputStream*(const AudioParameters& params,
                                  const std::string& device_id,
                                  const LogCallback& log_callback));
  MOCK_METHOD2(MakeAudioOutputStreamProxy, AudioOutputStream*(
      const AudioParameters& params,
      const std::string& device_id));
  MOCK_METHOD3(MakeAudioInputStream,
               AudioInputStream*(const AudioParameters& params,
                                 const std::string& device_id,
                                 const LogCallback& log_callback));
  MOCK_METHOD0(GetTaskRunner, scoped_refptr<base::SingleThreadTaskRunner>());
  MOCK_METHOD0(GetWorkerTaskRunner,
               scoped_refptr<base::SingleThreadTaskRunner>());
  MOCK_METHOD0(GetName, const char*());

  MOCK_METHOD2(MakeLinearOutputStream,
               AudioOutputStream*(const AudioParameters& params,
                                  const LogCallback& log_callback));
  MOCK_METHOD3(MakeLowLatencyOutputStream,
               AudioOutputStream*(const AudioParameters& params,
                                  const std::string& device_id,
                                  const LogCallback& log_callback));
  MOCK_METHOD3(MakeLinearInputStream,
               AudioInputStream*(const AudioParameters& params,
                                 const std::string& device_id,
                                 const LogCallback& log_callback));
  MOCK_METHOD3(MakeLowLatencyInputStream,
               AudioInputStream*(const AudioParameters& params,
                                 const std::string& device_id,
                                 const LogCallback& log_callback));

 protected:
  MOCK_METHOD0(HasAudioOutputDevices, bool());
  MOCK_METHOD0(HasAudioInputDevices, bool());
  MOCK_METHOD1(GetAudioInputDeviceNames,
               void(media::AudioDeviceNames* device_name));
  MOCK_METHOD2(GetPreferredOutputStreamParameters, AudioParameters(
      const std::string& device_id, const AudioParameters& params));

 private:
  media::FakeAudioLogFactory fake_audio_log_factory_;
};

class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
 public:
  int OnMoreData(base::TimeDelta /* delay */,
                 base::TimeTicks /* delay_timestamp */,
                 int /* prior_frames_skipped */,
                 AudioBus* dest) override {
    dest->Zero();
    return dest->frames();
  }
  MOCK_METHOD1(OnError, void(ErrorType));
};

}  // namespace

namespace media {

class AudioOutputProxyTest : public testing::Test {
 protected:
  void SetUp() override {
    // Use a low sample rate and large buffer size when testing otherwise the
    // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
    // RunUntilIdle() will never terminate.
    params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
                              CHANNEL_LAYOUT_STEREO, 8000, 2048);
    InitDispatcher(base::Milliseconds(kTestCloseDelayMs));
  }

  void TearDown() override {
    // This is necessary to free all proxy objects that have been
    // closed by the test.
    base::RunLoop().RunUntilIdle();
  }

  virtual void InitDispatcher(base::TimeDelta close_delay) {
    dispatcher_impl_ = std::make_unique<AudioOutputDispatcherImpl>(
        &manager(), params_, std::string(), close_delay);
  }

  virtual void OnStart() {}

  MockAudioManager& manager() {
    return manager_;
  }

  void WaitForCloseTimer(MockAudioOutputStream* stream) {
    base::RunLoop run_loop;
    EXPECT_CALL(*stream, Close())
        .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
    run_loop.Run();
  }

  void CloseAndWaitForCloseTimer(AudioOutputProxy* proxy,
                                 MockAudioOutputStream* stream) {
    // Close the stream and verify it doesn't happen immediately.
    proxy->Close();
    Mock::VerifyAndClear(stream);

    // Wait for the actual close event to come from the close timer.
    WaitForCloseTimer(stream);
  }

  // Basic Open() and Close() test.
  void OpenAndClose(AudioOutputDispatcher* dispatcher) {
    MockAudioOutputStream stream(&manager_, params_);

    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream));
    EXPECT_CALL(stream, Open())
        .WillOnce(Return(true));

    AudioOutputProxy* proxy = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy->Open());
    CloseAndWaitForCloseTimer(proxy, &stream);
  }

  // Creates a stream, and then calls Start() and Stop().
  void StartAndStop(AudioOutputDispatcher* dispatcher) {
    MockAudioOutputStream stream(&manager_, params_);

    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream));
    EXPECT_CALL(stream, Open())
        .WillOnce(Return(true));
    EXPECT_CALL(stream, SetVolume(_))
        .Times(1);

    AudioOutputProxy* proxy = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy->Open());

    proxy->Start(&callback_);
    OnStart();
    proxy->Stop();

    CloseAndWaitForCloseTimer(proxy, &stream);
    EXPECT_TRUE(stream.stop_called());
    EXPECT_TRUE(stream.start_called());
  }

  // Verify that the stream is closed after Stop() is called.
  void CloseAfterStop(AudioOutputDispatcher* dispatcher) {
    MockAudioOutputStream stream(&manager_, params_);

    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream));
    EXPECT_CALL(stream, Open())
        .WillOnce(Return(true));
    EXPECT_CALL(stream, SetVolume(_))
        .Times(1);

    AudioOutputProxy* proxy = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy->Open());

    proxy->Start(&callback_);
    OnStart();
    proxy->Stop();

    // Wait for the close timer to fire after StopStream().
    WaitForCloseTimer(&stream);
    proxy->Close();
    EXPECT_TRUE(stream.stop_called());
    EXPECT_TRUE(stream.start_called());
  }

  // Create two streams, but don't start them.  Only one device must be opened.
  void TwoStreams(AudioOutputDispatcher* dispatcher) {
    MockAudioOutputStream stream(&manager_, params_);

    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream));
    EXPECT_CALL(stream, Open())
        .WillOnce(Return(true));

    AudioOutputProxy* proxy1 = dispatcher->CreateStreamProxy();
    AudioOutputProxy* proxy2 = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy1->Open());
    EXPECT_TRUE(proxy2->Open());
    proxy1->Close();
    CloseAndWaitForCloseTimer(proxy2, &stream);
    EXPECT_FALSE(stream.stop_called());
    EXPECT_FALSE(stream.start_called());
  }

  // Open() method failed.
  void OpenFailed(AudioOutputDispatcher* dispatcher) {
    MockAudioOutputStream stream(&manager_, params_);

    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream));
    EXPECT_CALL(stream, Open())
        .WillOnce(Return(false));
    EXPECT_CALL(stream, Close())
        .Times(1);

    AudioOutputProxy* proxy = dispatcher->CreateStreamProxy();
    EXPECT_FALSE(proxy->Open());
    proxy->Close();
    EXPECT_FALSE(stream.stop_called());
    EXPECT_FALSE(stream.start_called());
  }

  void CreateAndWait(AudioOutputDispatcher* dispatcher) {
    MockAudioOutputStream stream(&manager_, params_);

    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream));
    EXPECT_CALL(stream, Open())
        .WillOnce(Return(true));

    AudioOutputProxy* proxy = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy->Open());

    WaitForCloseTimer(&stream);
    proxy->Close();
    EXPECT_FALSE(stream.stop_called());
    EXPECT_FALSE(stream.start_called());
  }

  void OneStream_TwoPlays(AudioOutputDispatcher* dispatcher) {
    MockAudioOutputStream stream(&manager_, params_);

    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream));

    EXPECT_CALL(stream, Open())
        .WillOnce(Return(true));
    EXPECT_CALL(stream, SetVolume(_))
        .Times(2);

    AudioOutputProxy* proxy1 = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy1->Open());

    proxy1->Start(&callback_);
    OnStart();
    proxy1->Stop();

    // The stream should now be idle and get reused by |proxy2|.
    AudioOutputProxy* proxy2 = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy2->Open());
    proxy2->Start(&callback_);
    OnStart();
    proxy2->Stop();

    proxy1->Close();
    CloseAndWaitForCloseTimer(proxy2, &stream);
    EXPECT_TRUE(stream.stop_called());
    EXPECT_TRUE(stream.start_called());
  }

  void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) {
    MockAudioOutputStream stream1(&manager_, params_);
    MockAudioOutputStream stream2(&manager_, params_);

    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream1))
        .WillOnce(Return(&stream2));

    EXPECT_CALL(stream1, Open())
        .WillOnce(Return(true));
    EXPECT_CALL(stream1, SetVolume(_))
        .Times(1);

    EXPECT_CALL(stream2, Open())
        .WillOnce(Return(true));
    EXPECT_CALL(stream2, SetVolume(_))
        .Times(1);

    AudioOutputProxy* proxy1 = dispatcher->CreateStreamProxy();
    AudioOutputProxy* proxy2 = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy1->Open());
    EXPECT_TRUE(proxy2->Open());

    proxy1->Start(&callback_);
    proxy2->Start(&callback_);
    OnStart();
    proxy1->Stop();
    CloseAndWaitForCloseTimer(proxy1, &stream1);

    proxy2->Stop();
    CloseAndWaitForCloseTimer(proxy2, &stream2);

    EXPECT_TRUE(stream1.stop_called());
    EXPECT_TRUE(stream1.start_called());
    EXPECT_TRUE(stream2.stop_called());
    EXPECT_TRUE(stream2.start_called());
  }

  void StartFailed(AudioOutputDispatcher* dispatcher) {
    MockAudioOutputStream stream(&manager_, params_);

    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream));
    EXPECT_CALL(stream, Open())
        .WillOnce(Return(true));

    AudioOutputProxy* proxy = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy->Open());

    WaitForCloseTimer(&stream);

    // |stream| is closed at this point. Start() should reopen it again.
    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .Times(2)
        .WillRepeatedly(Return(reinterpret_cast<AudioOutputStream*>(NULL)));

    EXPECT_CALL(callback_, OnError(_)).Times(2);

    proxy->Start(&callback_);

    // Double Start() in the error case should be allowed since it's possible a
    // callback may not have had time to process the OnError() in between.
    proxy->Stop();
    proxy->Start(&callback_);

    Mock::VerifyAndClear(&callback_);

    proxy->Close();
  }

  void DispatcherDestroyed_BeforeOpen(
      std::unique_ptr<AudioOutputDispatcher> dispatcher) {
    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)).Times(0);
    AudioOutputProxy* proxy = dispatcher->CreateStreamProxy();
    dispatcher.reset();
    EXPECT_FALSE(proxy->Open());
    proxy->Close();
  }

  void DispatcherDestroyed_BeforeStart(
      std::unique_ptr<AudioOutputDispatcher> dispatcher) {
    MockAudioOutputStream stream(&manager_, params_);
    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream));
    EXPECT_CALL(stream, Open()).WillOnce(Return(true));
    EXPECT_CALL(stream, Close()).Times(1);
    AudioOutputProxy* proxy = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy->Open());

    EXPECT_CALL(callback_, OnError(_)).Times(1);
    dispatcher.reset();
    proxy->Start(&callback_);
    proxy->Stop();
    proxy->Close();
  }

  void DispatcherDestroyed_BeforeStop(
      std::unique_ptr<AudioOutputDispatcher> dispatcher) {
    MockAudioOutputStream stream(&manager_, params_);
    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream));
    EXPECT_CALL(stream, Open()).WillOnce(Return(true));
    EXPECT_CALL(stream, Close()).Times(1);
    EXPECT_CALL(stream, SetVolume(_)).Times(1);

    AudioOutputProxy* proxy = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy->Open());
    proxy->Start(&callback_);
    dispatcher.reset();
    proxy->Stop();
    proxy->Close();
  }

  void DispatcherDestroyed_AfterStop(
      std::unique_ptr<AudioOutputDispatcher> dispatcher) {
    MockAudioOutputStream stream(&manager_, params_);
    EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
        .WillOnce(Return(&stream));
    EXPECT_CALL(stream, Open()).WillOnce(Return(true));
    EXPECT_CALL(stream, Close()).Times(1);
    EXPECT_CALL(stream, SetVolume(_)).Times(1);

    AudioOutputProxy* proxy = dispatcher->CreateStreamProxy();
    EXPECT_TRUE(proxy->Open());
    proxy->Start(&callback_);
    proxy->Stop();
    dispatcher.reset();
    proxy->Close();
  }

  base::test::SingleThreadTaskEnvironment task_environment_;
  MockAudioManager manager_;
  std::unique_ptr<AudioOutputDispatcherImpl> dispatcher_impl_;
  MockAudioSourceCallback callback_;
  AudioParameters params_;
};

class AudioOutputResamplerTest : public AudioOutputProxyTest {
 public:
  void InitDispatcher(base::TimeDelta close_delay) override {
    // Use a low sample rate and large buffer size when testing otherwise the
    // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
    // RunUntilIdle() will never terminate.
    resampler_params_ = AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
                                        CHANNEL_LAYOUT_STEREO, 16000, 1024);
    resampler_ = std::make_unique<AudioOutputResampler>(
        &manager(), params_, resampler_params_, std::string(), close_delay,
        base::BindRepeating(&RegisterDebugRecording));
  }

  void OnStart() override {
    // Let Start() run for a bit.
    base::RunLoop run_loop;
    task_environment_.GetMainThreadTaskRunner()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(kStartRunTimeMs));
    run_loop.Run();
  }

 protected:
  AudioParameters resampler_params_;
  std::unique_ptr<AudioOutputResampler> resampler_;
};

TEST_F(AudioOutputProxyTest, CreateAndClose) {
  AudioOutputProxy* proxy = dispatcher_impl_->CreateStreamProxy();
  proxy->Close();
}

TEST_F(AudioOutputResamplerTest, CreateAndClose) {
  AudioOutputProxy* proxy = resampler_->CreateStreamProxy();
  proxy->Close();
}

TEST_F(AudioOutputProxyTest, OpenAndClose) {
  OpenAndClose(dispatcher_impl_.get());
}

TEST_F(AudioOutputResamplerTest, OpenAndClose) {
  OpenAndClose(resampler_.get());
}

// Create a stream, and verify that it is closed after kTestCloseDelayMs.
// if it doesn't start playing.
TEST_F(AudioOutputProxyTest, CreateAndWait) {
  CreateAndWait(dispatcher_impl_.get());
}

// Create a stream, and verify that it is closed after kTestCloseDelayMs.
// if it doesn't start playing.
TEST_F(AudioOutputResamplerTest, CreateAndWait) {
  CreateAndWait(resampler_.get());
}

TEST_F(AudioOutputProxyTest, StartAndStop) {
  StartAndStop(dispatcher_impl_.get());
}

TEST_F(AudioOutputResamplerTest, StartAndStop) {
  StartAndStop(resampler_.get());
}

TEST_F(AudioOutputProxyTest, CloseAfterStop) {
  CloseAfterStop(dispatcher_impl_.get());
}

TEST_F(AudioOutputResamplerTest, CloseAfterStop) {
  CloseAfterStop(resampler_.get());
}

TEST_F(AudioOutputProxyTest, TwoStreams) {
  TwoStreams(dispatcher_impl_.get());
}

TEST_F(AudioOutputResamplerTest, TwoStreams) {
  TwoStreams(resampler_.get());
}

// Two streams: verify that second stream is allocated when the first
// starts playing.
TEST_F(AudioOutputProxyTest, OneStream_TwoPlays) {
  OneStream_TwoPlays(dispatcher_impl_.get());
}

TEST_F(AudioOutputResamplerTest, OneStream_TwoPlays) {
  OneStream_TwoPlays(resampler_.get());
}

// Two streams, both are playing. Dispatcher should not open a third stream.
TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) {
  TwoStreams_BothPlaying(dispatcher_impl_.get());
}

TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) {
  TwoStreams_BothPlaying(resampler_.get());
}

TEST_F(AudioOutputProxyTest, OpenFailed) {
  OpenFailed(dispatcher_impl_.get());
}

// Start() method failed.
TEST_F(AudioOutputProxyTest, StartFailed) {
  StartFailed(dispatcher_impl_.get());
}

TEST_F(AudioOutputResamplerTest, StartFailed) {
  StartFailed(resampler_.get());
}

TEST_F(AudioOutputProxyTest, DispatcherDestroyed_BeforeOpen) {
  DispatcherDestroyed_BeforeOpen(std::move(dispatcher_impl_));
}

TEST_F(AudioOutputResamplerTest, DispatcherDestroyed_BeforeOpen) {
  DispatcherDestroyed_BeforeOpen(std::move(resampler_));
}

TEST_F(AudioOutputProxyTest, DispatcherDestroyed_BeforeStart) {
  DispatcherDestroyed_BeforeStart(std::move(dispatcher_impl_));
}

TEST_F(AudioOutputResamplerTest, DispatcherDestroyed_BeforeStart) {
  DispatcherDestroyed_BeforeStart(std::move(resampler_));
}

TEST_F(AudioOutputProxyTest, DispatcherDestroyed_BeforeStop) {
  DispatcherDestroyed_BeforeStop(std::move(dispatcher_impl_));
}

TEST_F(AudioOutputResamplerTest, DispatcherDestroyed_BeforeStop) {
  DispatcherDestroyed_BeforeStop(std::move(resampler_));
}

TEST_F(AudioOutputProxyTest, DispatcherDestroyed_AfterStop) {
  DispatcherDestroyed_AfterStop(std::move(dispatcher_impl_));
}

TEST_F(AudioOutputResamplerTest, DispatcherDestroyed_AfterStop) {
  DispatcherDestroyed_AfterStop(std::move(resampler_));
}

TEST_F(AudioOutputProxyTest, DispatcherDeviceChangeClosesIdleStreams) {
  // Set close delay so long that it triggers a test timeout if relied upon.
  InitDispatcher(base::Seconds(1000));

  MockAudioOutputStream stream(&manager_, params_);

  EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
      .WillOnce(Return(&stream));
  EXPECT_CALL(stream, Open()).WillOnce(Return(true));

  AudioOutputProxy* proxy = dispatcher_impl_->CreateStreamProxy();
  EXPECT_TRUE(proxy->Open());

  // Close the stream and verify it doesn't happen immediately.
  proxy->Close();
  Mock::VerifyAndClear(&stream);

  // This should trigger a true close on the stream.
  dispatcher_impl_->OnDeviceChange();

  base::RunLoop run_loop;
  EXPECT_CALL(stream, Close())
      .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  run_loop.Run();
}

// Simulate AudioOutputStream::Create() failure with a low latency stream and
// ensure AudioOutputResampler falls back to the high latency path.
TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) {
  MockAudioOutputStream stream(&manager_, params_);
  EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
      .Times(2)
      .WillOnce(Return(static_cast<AudioOutputStream*>(NULL)))
      .WillRepeatedly(Return(&stream));
  EXPECT_CALL(stream, Open())
      .WillOnce(Return(true));

  AudioOutputProxy* proxy = resampler_->CreateStreamProxy();
  EXPECT_TRUE(proxy->Open());
  CloseAndWaitForCloseTimer(proxy, &stream);
}

// Simulate AudioOutputStream::Open() failure with a low latency stream and
// ensure AudioOutputResampler falls back to the high latency path.
TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) {
  MockAudioOutputStream failed_stream(&manager_, params_);
  MockAudioOutputStream okay_stream(&manager_, params_);
  EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
      .Times(2)
      .WillOnce(Return(&failed_stream))
      .WillRepeatedly(Return(&okay_stream));
  EXPECT_CALL(failed_stream, Open())
      .WillOnce(Return(false));
  EXPECT_CALL(failed_stream, Close())
      .Times(1);
  EXPECT_CALL(okay_stream, Open())
      .WillOnce(Return(true));

  AudioOutputProxy* proxy = resampler_->CreateStreamProxy();
  EXPECT_TRUE(proxy->Open());
  CloseAndWaitForCloseTimer(proxy, &okay_stream);
}

// Simulate failures to open both the low latency and the fallback high latency
// stream and ensure AudioOutputResampler falls back to a fake stream.
TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) {
  MockAudioOutputStream okay_stream(&manager_, params_);

// Only Windows has a high latency output driver that is not the same as the low
// latency path.
#if defined(OS_WIN)
  static const int kFallbackCount = 2;
#else
  static const int kFallbackCount = 1;
#endif
  EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
      .Times(kFallbackCount)
      .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));

  // To prevent shared memory issues the sample rate and buffer size should
  // match the input stream parameters.
  EXPECT_CALL(manager(),
              MakeAudioOutputStream(
                  AllOf(testing::Property(&AudioParameters::format,
                                          AudioParameters::AUDIO_FAKE),
                        testing::Property(&AudioParameters::sample_rate,
                                          params_.sample_rate()),
                        testing::Property(&AudioParameters::frames_per_buffer,
                                          params_.frames_per_buffer())),
                  _, _))
      .Times(1)
      .WillOnce(Return(&okay_stream));
  EXPECT_CALL(okay_stream, Open())
      .WillOnce(Return(true));

  AudioOutputProxy* proxy = resampler_->CreateStreamProxy();
  EXPECT_TRUE(proxy->Open());
  CloseAndWaitForCloseTimer(proxy, &okay_stream);
}

// Simulate failures to open both the low latency, the fallback high latency
// stream, and the fake audio output stream and ensure AudioOutputResampler
// terminates normally.
TEST_F(AudioOutputResamplerTest, AllFallbackFailed) {
// Only Windows has a high latency output driver that is not the same as the low
// latency path.
#if defined(OS_WIN)
  static const int kFallbackCount = 3;
#else
  static const int kFallbackCount = 2;
#endif
  EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
      .Times(kFallbackCount)
      .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));

  AudioOutputProxy* proxy = resampler_->CreateStreamProxy();
  EXPECT_FALSE(proxy->Open());
  proxy->Close();
}

// Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls
// eventually followed by one which fails; root cause of http://crbug.com/150619
TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) {
  MockAudioOutputStream stream1(&manager_, params_);
  MockAudioOutputStream stream2(&manager_, params_);

  // Setup the mock such that all three streams are successfully created.
  EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
      .WillOnce(Return(&stream1))
      .WillOnce(Return(&stream2))
      .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));

  // Stream1 should be able to successfully open and start.
  EXPECT_CALL(stream1, Open())
      .WillOnce(Return(true));
  EXPECT_CALL(stream1, SetVolume(_))
      .Times(1);

  // Stream2 should also be able to successfully open and start.
  EXPECT_CALL(stream2, Open())
      .WillOnce(Return(true));
  EXPECT_CALL(stream2, SetVolume(_))
      .Times(1);

  // Open and start the first proxy and stream.
  AudioOutputProxy* proxy1 = resampler_->CreateStreamProxy();
  EXPECT_TRUE(proxy1->Open());
  proxy1->Start(&callback_);
  OnStart();

  // Open and start the second proxy and stream.
  AudioOutputProxy* proxy2 = resampler_->CreateStreamProxy();
  EXPECT_TRUE(proxy2->Open());
  proxy2->Start(&callback_);
  OnStart();

  // Attempt to open the third stream which should fail.
  AudioOutputProxy* proxy3 = resampler_->CreateStreamProxy();
  EXPECT_FALSE(proxy3->Open());
  proxy3->Close();

  // Perform the required Stop()/Close() shutdown dance for each proxy.  Under
  // the hood each proxy should correctly call CloseStream() if OpenStream()
  // succeeded or not.
  proxy2->Stop();
  CloseAndWaitForCloseTimer(proxy2, &stream2);

  proxy1->Stop();
  CloseAndWaitForCloseTimer(proxy1, &stream1);

  EXPECT_TRUE(stream1.stop_called());
  EXPECT_TRUE(stream1.start_called());
  EXPECT_TRUE(stream2.stop_called());
  EXPECT_TRUE(stream2.start_called());
}

// Simulate failures to open both the low latency and the fallback high latency
// stream and ensure AudioOutputResampler falls back to a fake stream.  Ensure
// that after the close delay elapses, opening another stream succeeds with a
// non-fake stream.
TEST_F(AudioOutputResamplerTest, FallbackRecovery) {
  MockAudioOutputStream fake_stream(&manager_, params_);

  // Trigger the fallback mechanism until a fake output stream is created.
#if defined(OS_WIN)
  static const int kFallbackCount = 2;
#else
  static const int kFallbackCount = 1;
#endif
  EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _))
      .Times(kFallbackCount)
      .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL)));
  EXPECT_CALL(manager(),
              MakeAudioOutputStream(
                  AllOf(testing::Property(&AudioParameters::format,
                                          AudioParameters::AUDIO_FAKE),
                        testing::Property(&AudioParameters::sample_rate,
                                          params_.sample_rate()),
                        testing::Property(&AudioParameters::frames_per_buffer,
                                          params_.frames_per_buffer())),
                  _, _))
      .WillOnce(Return(&fake_stream));
  EXPECT_CALL(fake_stream, Open()).WillOnce(Return(true));
  AudioOutputProxy* proxy = resampler_->CreateStreamProxy();
  EXPECT_TRUE(proxy->Open());
  CloseAndWaitForCloseTimer(proxy, &fake_stream);

  // Once all proxies have been closed, AudioOutputResampler will start the
  // reinitialization timer and execute it after the close delay elapses.
  base::RunLoop run_loop;
  task_environment_.GetMainThreadTaskRunner()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(),
      base::Milliseconds(2 * kTestCloseDelayMs));
  run_loop.Run();

  // Verify a non-fake stream can be created.
  MockAudioOutputStream real_stream(&manager_, params_);
  EXPECT_CALL(manager(),
              MakeAudioOutputStream(
                  testing::Property(&AudioParameters::format,
                                    testing::Ne(AudioParameters::AUDIO_FAKE)),
                  _, _))
      .WillOnce(Return(&real_stream));

  // Stream1 should be able to successfully open and start.
  EXPECT_CALL(real_stream, Open()).WillOnce(Return(true));
  proxy = resampler_->CreateStreamProxy();
  EXPECT_TRUE(proxy->Open());
  CloseAndWaitForCloseTimer(proxy, &real_stream);
}

}  // namespace media
