Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Unified Diff: media/audio/restartable_audio_output_device_impl_unittest.cc

Issue 1666363005: Switching audio clients to using RestartableAudioRendererSink interface as a sink. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698