| Index: media/audio/restartable_audio_output_device_impl_unittest.cc
|
| diff --git a/media/audio/restartable_audio_output_device_impl_unittest.cc b/media/audio/restartable_audio_output_device_impl_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..046a0de8311296c45d8529043a62ee383daf66c4
|
| --- /dev/null
|
| +++ b/media/audio/restartable_audio_output_device_impl_unittest.cc
|
| @@ -0,0 +1,436 @@
|
| +// Copyright 2016 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 "media/audio/restartable_audio_output_device_impl.h"
|
| +
|
| +#include "base/single_thread_task_runner.h"
|
| +#include "media/audio/audio_output_device.h"
|
| +#include "media/audio/audio_output_ipc.h"
|
| +#include "media/audio/mock_audio_output_ipc.h"
|
| +#include "media/audio/mock_render_callback.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using testing::_;
|
| +using testing::Exactly;
|
| +using testing::InSequence;
|
| +
|
| +namespace media {
|
| +
|
| +namespace {
|
| +
|
| +const int kHWSampleRate = 22500;
|
| +const int kDefaultSampleRate = 32000;
|
| +const int kNewSampleRate = 44100;
|
| +const char kDefaultDeviceId[] = "";
|
| +const char kBrokenDeviceId[] = "broken-device";
|
| +
|
| +AudioParameters BuildHWParams() {
|
| + return AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
|
| + CHANNEL_LAYOUT_STEREO, kHWSampleRate, 16, 512);
|
| +}
|
| +
|
| +class FakeAudioOutputDevice : NON_EXPORTED_BASE(public AudioOutputDevice) {
|
| + public:
|
| + FakeAudioOutputDevice(
|
| + scoped_ptr<AudioOutputIPC> ipc,
|
| + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
|
| + const std::string& device_id)
|
| + : AudioOutputDevice(std::move(ipc),
|
| + io_task_runner,
|
| + 0,
|
| + std::string(),
|
| + url::Origin()),
|
| + device_id_(device_id),
|
| + sample_rate_(0),
|
| + volume_(1.0),
|
| + initialized_(false),
|
| + started_(false),
|
| + playing_(false) {}
|
| +
|
| + MOCK_METHOD0(MockStop, void());
|
| +
|
| + void Initialize(const AudioParameters& params, RenderCallback*) override {
|
| + initialized_ = true;
|
| + sample_rate_ = params.sample_rate();
|
| + }
|
| +
|
| + void Start() override {
|
| + EXPECT_TRUE(initialized_);
|
| + started_ = true;
|
| + playing_ = true; // AudioOutputDevice plays on start.
|
| + }
|
| +
|
| + void Play() override {
|
| + EXPECT_TRUE(initialized_);
|
| + playing_ = true;
|
| + }
|
| +
|
| + void Pause() override {
|
| + EXPECT_TRUE(initialized_);
|
| + playing_ = false;
|
| + }
|
| +
|
| + void Stop() override {
|
| + started_ = false;
|
| + playing_ = false;
|
| + MockStop();
|
| + }
|
| +
|
| + bool SetVolume(double volume) override {
|
| + EXPECT_TRUE(initialized_);
|
| + if (device_id_ == kBrokenDeviceId) {
|
| + volume_ = 0;
|
| + return false;
|
| + }
|
| + volume_ = volume;
|
| + return true;
|
| + }
|
| +
|
| + double GetVolume() { return volume_; }
|
| + int GetSampleRate() { return sample_rate_; }
|
| + bool IsPlaying() { return started_ && playing_; }
|
| +
|
| + OutputDeviceStatus GetDeviceStatus() override {
|
| + return device_id_ == kBrokenDeviceId ? OUTPUT_DEVICE_STATUS_ERROR_INTERNAL
|
| + : OUTPUT_DEVICE_STATUS_OK;
|
| + }
|
| +
|
| + AudioParameters GetOutputParameters() override {
|
| + AudioParameters params = BuildHWParams();
|
| + if (device_id_ == kBrokenDeviceId)
|
| + params.set_format(AudioParameters::AUDIO_FAKE);
|
| + return params;
|
| + }
|
| +
|
| + protected:
|
| + virtual ~FakeAudioOutputDevice() {}
|
| +
|
| + private:
|
| + const std::string device_id_;
|
| + int sample_rate_;
|
| + double volume_;
|
| + bool initialized_;
|
| + bool started_;
|
| + bool playing_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class RestartableAudioOutputDeviceImplTest : public testing::Test {
|
| + protected:
|
| + RestartableAudioOutputDeviceImplTest()
|
| + : message_loop_(new base::MessageLoopForIO),
|
| + mock_ipc_(nullptr),
|
| + default_params_(AudioParameters::AUDIO_PCM_LINEAR,
|
| + CHANNEL_LAYOUT_STEREO,
|
| + kDefaultSampleRate,
|
| + 16,
|
| + 512),
|
| + new_params_(AudioParameters::AUDIO_PCM_LINEAR,
|
| + CHANNEL_LAYOUT_STEREO,
|
| + kNewSampleRate,
|
| + 16,
|
| + 512) {}
|
| +
|
| + MOCK_METHOD0(MockCreateOutputDevice, void());
|
| +
|
| + scoped_refptr<media::AudioOutputDevice> CreateOutputDevice(
|
| + int render_frame_id,
|
| + int session_id,
|
| + const std::string& device_id,
|
| + const url::Origin& security_origin) {
|
| + mock_ipc_ = new MockAudioOutputIPC();
|
| + mock_output_device_ =
|
| + new FakeAudioOutputDevice(scoped_ptr<media::AudioOutputIPC>(mock_ipc_),
|
| + message_loop_->task_runner(), device_id);
|
| + ;
|
| + EXPECT_CALL(*mock_output_device_.get(), MockStop()).Times(Exactly(1));
|
| + MockCreateOutputDevice();
|
| + return mock_output_device_;
|
| + }
|
| +
|
| + void PrepareSink(const std::string& device_id, int times_to_restart = 0) {
|
| + static const int kRendererFrameId = 0;
|
| + static const int kSessionId = 0;
|
| + static const url::Origin kSecurityOrigin;
|
| + EXPECT_CALL(*this, MockCreateOutputDevice()).Times(times_to_restart + 1);
|
| + sink_ = new media::RestartableAudioOutputDeviceImpl(
|
| + base::Bind(&RestartableAudioOutputDeviceImplTest::CreateOutputDevice,
|
| + base::Unretained(this), kRendererFrameId, kSessionId,
|
| + device_id, kSecurityOrigin),
|
| + base::Bind(&BuildHWParams));
|
| + }
|
| +
|
| + void TearDown() override {
|
| + mock_output_device_ = nullptr;
|
| + sink_ = nullptr;
|
| + }
|
| +
|
| + // Used to construct |mock_output_device_|.
|
| + scoped_ptr<base::MessageLoopForIO> message_loop_;
|
| + MockAudioOutputIPC* mock_ipc_; // Owned by AudioOuputDevice.
|
| + scoped_refptr<FakeAudioOutputDevice> mock_output_device_;
|
| +
|
| + // Sink under test.
|
| + scoped_refptr<media::RestartableAudioOutputDeviceImpl> sink_;
|
| +
|
| + // Data used for initializations.
|
| + media::AudioParameters default_params_;
|
| + media::AudioParameters new_params_;
|
| + MockRenderCallback callback_;
|
| +};
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, StopNotInitializedSink) {
|
| + PrepareSink(kDefaultDeviceId);
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, InitializeAndStopSink) {
|
| + PrepareSink(kDefaultDeviceId);
|
| + sink_->Initialize(default_params_, &callback_);
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, StartAndStopSink) {
|
| + PrepareSink(kDefaultDeviceId);
|
| +
|
| + sink_->Initialize(default_params_, &callback_);
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| +
|
| + sink_->Start();
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| +
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, StartPlayAndStopSink) {
|
| + PrepareSink(kDefaultDeviceId);
|
| +
|
| + sink_->Initialize(default_params_, &callback_);
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| +
|
| + sink_->Start();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| +
|
| + EXPECT_EQ(kDefaultSampleRate, mock_output_device_->GetSampleRate());
|
| +
|
| + sink_->Play();
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| +
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, StartPauseStopSink) {
|
| + PrepareSink(kDefaultDeviceId);
|
| +
|
| + sink_->Initialize(default_params_, &callback_);
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| +
|
| + sink_->Start();
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| +
|
| + sink_->Pause();
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| +
|
| + sink_->Stop();
|
| +}
|
| +
|
| +//*
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, PausePausedSink) {
|
| + PrepareSink(kDefaultDeviceId);
|
| +
|
| + sink_->Initialize(default_params_, &callback_);
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + sink_->Start();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + sink_->Pause();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + sink_->Pause();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + sink_->Stop();
|
| +}
|
| +//*
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, PlayPlayingSink) {
|
| + PrepareSink(kDefaultDeviceId);
|
| +
|
| + sink_->Initialize(default_params_, &callback_);
|
| + sink_->Start();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, StartPausePlayStopSink) {
|
| + PrepareSink(kDefaultDeviceId);
|
| +
|
| + sink_->Initialize(default_params_, &callback_);
|
| + sink_->Start();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + sink_->Pause();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, PauseAfterPlay) {
|
| + PrepareSink(kDefaultDeviceId);
|
| +
|
| + sink_->Initialize(default_params_, &callback_);
|
| + sink_->Start();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + sink_->Pause();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, MultiplePlayPause) {
|
| + PrepareSink(kDefaultDeviceId);
|
| +
|
| + sink_->Initialize(default_params_, &callback_);
|
| + sink_->Start();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + sink_->Pause();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + sink_->Pause();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, RestartSinkNoReinit) {
|
| + PrepareSink(kDefaultDeviceId, 1);
|
| +
|
| + sink_->Initialize(default_params_, &callback_);
|
| + sink_->Start();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(kDefaultSampleRate, mock_output_device_->GetSampleRate());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + sink_->Stop();
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + sink_->Start();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(kDefaultSampleRate, mock_output_device_->GetSampleRate());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, RestartAndReinitSink) {
|
| + PrepareSink(kDefaultDeviceId, 1);
|
| +
|
| + sink_->Initialize(default_params_, &callback_);
|
| + sink_->Start();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(kDefaultSampleRate, mock_output_device_->GetSampleRate());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + sink_->Stop();
|
| +
|
| + sink_->Initialize(new_params_, &callback_);
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| + sink_->Start();
|
| + EXPECT_FALSE(mock_output_device_->IsPlaying());
|
| + EXPECT_EQ(kNewSampleRate, mock_output_device_->GetSampleRate());
|
| + sink_->Play();
|
| + EXPECT_TRUE(mock_output_device_->IsPlaying());
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, GetOutputParameters) {
|
| + PrepareSink(kDefaultDeviceId, 1);
|
| + EXPECT_EQ(kHWSampleRate, sink_->GetOutputParameters().sample_rate());
|
| + sink_->Initialize(default_params_, &callback_);
|
| + EXPECT_EQ(kHWSampleRate, sink_->GetOutputParameters().sample_rate());
|
| + sink_->Start();
|
| + EXPECT_EQ(kHWSampleRate, sink_->GetOutputParameters().sample_rate());
|
| + sink_->Play();
|
| + EXPECT_EQ(kHWSampleRate, sink_->GetOutputParameters().sample_rate());
|
| + sink_->Stop();
|
| + EXPECT_EQ(kHWSampleRate, sink_->GetOutputParameters().sample_rate());
|
| + sink_->Start();
|
| + EXPECT_EQ(kHWSampleRate, sink_->GetOutputParameters().sample_rate());
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, SetVolume) {
|
| + PrepareSink(kDefaultDeviceId, 1);
|
| +
|
| + sink_->SetVolume(0.8); // Set volume before starting sink.
|
| + sink_->Initialize(default_params_, &callback_);
|
| + sink_->Start();
|
| + sink_->Play();
|
| + EXPECT_DOUBLE_EQ(0.8, mock_output_device_->GetVolume());
|
| + sink_->Stop();
|
| +
|
| + EXPECT_TRUE(sink_->SetVolume(0.1));
|
| + sink_->Initialize(default_params_, &callback_);
|
| + EXPECT_TRUE(sink_->SetVolume(0.2));
|
| + sink_->Start();
|
| + EXPECT_TRUE(sink_->SetVolume(0.3));
|
| + sink_->Play();
|
| + EXPECT_DOUBLE_EQ(0.3, mock_output_device_->GetVolume());
|
| + EXPECT_TRUE(sink_->SetVolume(0.4));
|
| + EXPECT_DOUBLE_EQ(0.4, mock_output_device_->GetVolume());
|
| + EXPECT_TRUE(sink_->SetVolume(0.5));
|
| + EXPECT_DOUBLE_EQ(0.5, mock_output_device_->GetVolume());
|
| + sink_->Pause();
|
| + EXPECT_TRUE(sink_->SetVolume(0.6));
|
| + EXPECT_TRUE(sink_->SetVolume(0.7));
|
| + sink_->Play();
|
| + EXPECT_DOUBLE_EQ(0.7, mock_output_device_->GetVolume());
|
| + sink_->Stop();
|
| +}
|
| +
|
| +TEST_F(RestartableAudioOutputDeviceImplTest, CorrectStatusFromInvalidDevice) {
|
| + PrepareSink(kBrokenDeviceId, 1);
|
| +
|
| + sink_->Initialize(default_params_, &callback_);
|
| + sink_->Start();
|
| + EXPECT_NE(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| +
|
| + sink_->Stop();
|
| + // Stopped device is OK.
|
| + EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| +
|
| + sink_->Start();
|
| + EXPECT_NE(OUTPUT_DEVICE_STATUS_OK, sink_->GetDeviceStatus());
|
| +
|
| + sink_->Stop();
|
| +}
|
| +
|
| +} // namespace content
|
|
|