| Index: media/base/silent_sink_suspender_unittest.cc
|
| diff --git a/media/base/silent_sink_suspender_unittest.cc b/media/base/silent_sink_suspender_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c69084b4c32593bffdb0cc9e86ed72e8cdd8da86
|
| --- /dev/null
|
| +++ b/media/base/silent_sink_suspender_unittest.cc
|
| @@ -0,0 +1,160 @@
|
| +// 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 "base/run_loop.h"
|
| +#include "base/test/test_message_loop.h"
|
| +#include "media/base/fake_audio_render_callback.h"
|
| +#include "media/base/mock_audio_renderer_sink.h"
|
| +#include "media/base/silent_sink_suspender.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace media {
|
| +
|
| +ACTION_P(RunClosure, closure) {
|
| + closure.Run();
|
| +}
|
| +
|
| +class SilentSinkSuspenderTest : public testing::Test {
|
| + public:
|
| + SilentSinkSuspenderTest()
|
| + : params_(AudioParameters::AUDIO_FAKE,
|
| + CHANNEL_LAYOUT_MONO,
|
| + 44100,
|
| + 8,
|
| + 128),
|
| + mock_sink_(new testing::StrictMock<MockAudioRendererSink>()),
|
| + fake_callback_(0.1),
|
| + temp_bus_(AudioBus::Create(params_)),
|
| + // Set a negative timeout so any silence will suspend immediately.
|
| + suspender_(&fake_callback_,
|
| + base::TimeDelta::FromSeconds(-1),
|
| + params_,
|
| + mock_sink_,
|
| + test_loop_.task_runner()) {}
|
| + ~SilentSinkSuspenderTest() override {}
|
| +
|
| + protected:
|
| + base::TestMessageLoop test_loop_;
|
| + const AudioParameters params_;
|
| + scoped_refptr<testing::StrictMock<MockAudioRendererSink>> mock_sink_;
|
| + FakeAudioRenderCallback fake_callback_;
|
| + std::unique_ptr<AudioBus> temp_bus_;
|
| + SilentSinkSuspender suspender_;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(SilentSinkSuspenderTest);
|
| +};
|
| +
|
| +TEST_F(SilentSinkSuspenderTest, BasicPassthough) {
|
| + temp_bus_->Zero();
|
| + EXPECT_EQ(temp_bus_->frames(), suspender_.Render(temp_bus_.get(), 0, 0));
|
| + EXPECT_FALSE(temp_bus_->AreFramesZero());
|
| +}
|
| +
|
| +TEST_F(SilentSinkSuspenderTest, SuspendResumeTriggered) {
|
| + // Verify a normal Render() doesn't invoke suspend.
|
| + EXPECT_FALSE(suspender_.is_using_fake_sink_for_testing());
|
| + temp_bus_->Zero();
|
| + EXPECT_EQ(temp_bus_->frames(), suspender_.Render(temp_bus_.get(), 0, 0));
|
| + EXPECT_FALSE(temp_bus_->AreFramesZero());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_FALSE(suspender_.is_using_fake_sink_for_testing());
|
| +
|
| + // Mute all audio generated by the callback, this should suspend immediately.
|
| + fake_callback_.set_volume(0);
|
| + temp_bus_->Zero();
|
| + EXPECT_EQ(temp_bus_->frames(), suspender_.Render(temp_bus_.get(), 0, 0));
|
| + EXPECT_TRUE(temp_bus_->AreFramesZero());
|
| + {
|
| + base::RunLoop run_loop;
|
| + EXPECT_CALL(*mock_sink_, Pause())
|
| + .WillOnce(RunClosure(run_loop.QuitClosure()));
|
| + run_loop.Run();
|
| + EXPECT_TRUE(suspender_.is_using_fake_sink_for_testing());
|
| + }
|
| +
|
| + // Unmute the audio, the FakeWorker inside |suspender_| should be running now,
|
| + // so we don't need to manually invoke Render().
|
| + fake_callback_.reset();
|
| + fake_callback_.set_volume(1);
|
| + {
|
| + base::RunLoop run_loop;
|
| + EXPECT_CALL(*mock_sink_, Play())
|
| + .WillOnce(RunClosure(run_loop.QuitClosure()));
|
| + run_loop.Run();
|
| + EXPECT_FALSE(suspender_.is_using_fake_sink_for_testing());
|
| + }
|
| +
|
| + // The first Render() after resume should return the first buffer which was
|
| + // not silent.
|
| + fake_callback_.reset();
|
| + std::unique_ptr<AudioBus> true_bus = AudioBus::Create(params_);
|
| + fake_callback_.Render(true_bus.get(), 0, 0);
|
| + EXPECT_FALSE(true_bus->AreFramesZero());
|
| + EXPECT_EQ(temp_bus_->frames(), suspender_.Render(temp_bus_.get(), 0, 0));
|
| + EXPECT_EQ(memcmp(temp_bus_->channel(0), true_bus->channel(0),
|
| + temp_bus_->frames() * sizeof(float)),
|
| + 0);
|
| +}
|
| +
|
| +TEST_F(SilentSinkSuspenderTest, MultipleSuspend) {
|
| + // Mute all audio generated by the callback, this should suspend immediately.
|
| + fake_callback_.set_volume(0);
|
| + temp_bus_->Zero();
|
| + EXPECT_EQ(temp_bus_->frames(), suspender_.Render(temp_bus_.get(), 0, 0));
|
| + EXPECT_TRUE(temp_bus_->AreFramesZero());
|
| +
|
| + // A second render should only result in a single Pause() call.
|
| + EXPECT_EQ(temp_bus_->frames(), suspender_.Render(temp_bus_.get(), 0, 0));
|
| +
|
| + EXPECT_CALL(*mock_sink_, Pause());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(suspender_.is_using_fake_sink_for_testing());
|
| +}
|
| +
|
| +TEST_F(SilentSinkSuspenderTest, MultipleResume) {
|
| + // Mute all audio generated by the callback, this should suspend immediately.
|
| + fake_callback_.set_volume(0);
|
| + temp_bus_->Zero();
|
| + EXPECT_EQ(temp_bus_->frames(), suspender_.Render(temp_bus_.get(), 0, 0));
|
| + EXPECT_TRUE(temp_bus_->AreFramesZero());
|
| + EXPECT_CALL(*mock_sink_, Pause());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(suspender_.is_using_fake_sink_for_testing());
|
| +
|
| + // Unmute the data.
|
| + fake_callback_.set_volume(1);
|
| +
|
| + // Prepare our equality testers.
|
| + fake_callback_.reset();
|
| + std::unique_ptr<AudioBus> true_bus1 = AudioBus::Create(params_);
|
| + fake_callback_.Render(true_bus1.get(), 0, 0);
|
| + std::unique_ptr<AudioBus> true_bus2 = AudioBus::Create(params_);
|
| + fake_callback_.Render(true_bus2.get(), 0, 0);
|
| + EXPECT_NE(memcmp(true_bus1->channel(0), true_bus2->channel(0),
|
| + true_bus1->frames() * sizeof(float)),
|
| + 0);
|
| +
|
| + // Reset the fake callback data generation and force two Render() calls before
|
| + // the sink can transition.
|
| + fake_callback_.reset();
|
| + EXPECT_EQ(temp_bus_->frames(), suspender_.Render(nullptr, 0, 0));
|
| + EXPECT_EQ(temp_bus_->frames(), suspender_.Render(nullptr, 0, 0));
|
| + EXPECT_CALL(*mock_sink_, Play());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_FALSE(suspender_.is_using_fake_sink_for_testing());
|
| +
|
| + // Each render after resuming should return one of the non-silent bus.
|
| + EXPECT_EQ(temp_bus_->frames(), suspender_.Render(temp_bus_.get(), 0, 0));
|
| + EXPECT_EQ(memcmp(temp_bus_->channel(0), true_bus1->channel(0),
|
| + temp_bus_->frames() * sizeof(float)),
|
| + 0);
|
| + EXPECT_EQ(temp_bus_->frames(), suspender_.Render(temp_bus_.get(), 0, 0));
|
| + EXPECT_EQ(memcmp(temp_bus_->channel(0), true_bus2->channel(0),
|
| + temp_bus_->frames() * sizeof(float)),
|
| + 0);
|
| +}
|
| +
|
| +} // namespace content
|
|
|