| Index: media/audio/audio_output_controller_unittest.cc
|
| diff --git a/media/audio/audio_output_controller_unittest.cc b/media/audio/audio_output_controller_unittest.cc
|
| index 9e713464d8e71da72179764faf7ea1753aa19086..851c6c23d03ac1e79ca8fa2e8909272ec034ec2a 100644
|
| --- a/media/audio/audio_output_controller_unittest.cc
|
| +++ b/media/audio/audio_output_controller_unittest.cc
|
| @@ -17,6 +17,7 @@
|
| #include "base/test/test_message_loop.h"
|
| #include "base/threading/thread_task_runner_handle.h"
|
| #include "media/audio/audio_device_description.h"
|
| +#include "media/audio/audio_source_diverter.h"
|
| #include "media/base/audio_bus.h"
|
| #include "media/base/audio_parameters.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| @@ -36,6 +37,7 @@ static const int kBitsPerSample = 16;
|
| static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
|
| static const int kSamplesPerPacket = kSampleRate / 100;
|
| static const double kTestVolume = 0.25;
|
| +static const float kBufferNonZeroData = 1.0f;
|
|
|
| class MockAudioOutputControllerEventHandler
|
| : public AudioOutputController::EventHandler {
|
| @@ -82,7 +84,17 @@ class MockAudioOutputStream : public AudioOutputStream {
|
| AudioSourceCallback* callback_;
|
| };
|
|
|
| -static const float kBufferNonZeroData = 1.0f;
|
| +class MockAudioPushSink : public AudioPushSink {
|
| + public:
|
| + MOCK_METHOD0(Close, void());
|
| + MOCK_METHOD1(OnDataCheck, void(float));
|
| +
|
| + void OnData(std::unique_ptr<AudioBus> source,
|
| + base::TimeTicks reference_time) override {
|
| + OnDataCheck(source->channel(0)[0]);
|
| + }
|
| +};
|
| +
|
| ACTION(PopulateBuffer) {
|
| arg0->Zero();
|
| // Note: To confirm the buffer will be populated in these tests, it's
|
| @@ -177,6 +189,11 @@ class AudioOutputControllerTest : public testing::Test {
|
| base::RunLoop().RunUntilIdle();
|
| }
|
|
|
| + void StartDuplicating(MockAudioPushSink* sink) {
|
| + controller_->StartDuplicating(sink);
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| void ReadDivertedAudioData() {
|
| std::unique_ptr<AudioBus> dest = AudioBus::Create(params_);
|
| ASSERT_TRUE(mock_stream_.callback());
|
| @@ -186,6 +203,22 @@ class AudioOutputControllerTest : public testing::Test {
|
| EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]);
|
| }
|
|
|
| + void ReadDuplicatedAudioData(const std::vector<MockAudioPushSink*>& sinks) {
|
| + for (size_t i = 0; i < sinks.size(); i++) {
|
| + EXPECT_CALL(*sinks[i], OnDataCheck(kBufferNonZeroData));
|
| + }
|
| +
|
| + std::unique_ptr<AudioBus> dest = AudioBus::Create(params_);
|
| +
|
| + // It is this OnMoreData() call that triggers |sink|'s OnData().
|
| + const int frames_read = controller_->OnMoreData(dest.get(), 0, 0);
|
| +
|
| + EXPECT_LT(0, frames_read);
|
| + EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]);
|
| +
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| void Revert(bool was_playing) {
|
| if (was_playing) {
|
| // Expect the handler to receive one OnPlaying() call as a result of the
|
| @@ -199,6 +232,12 @@ class AudioOutputControllerTest : public testing::Test {
|
| base::RunLoop().RunUntilIdle();
|
| }
|
|
|
| + void StopDuplicating(MockAudioPushSink* sink) {
|
| + EXPECT_CALL(*sink, Close());
|
| + controller_->StopDuplicating(sink);
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| void SwitchDevice(bool diverting) {
|
| if (!diverting) {
|
| // Expect the current stream to close and a new stream to start
|
| @@ -336,4 +375,59 @@ TEST_F(AudioOutputControllerTest, DivertRevertClose) {
|
| Close();
|
| }
|
|
|
| +TEST_F(AudioOutputControllerTest, PlayDuplicateStopClose) {
|
| + Create(kSamplesPerPacket);
|
| + MockAudioPushSink mock_sink;
|
| + Play();
|
| + StartDuplicating(&mock_sink);
|
| + ReadDuplicatedAudioData({&mock_sink});
|
| + StopDuplicating(&mock_sink);
|
| + Close();
|
| +}
|
| +
|
| +TEST_F(AudioOutputControllerTest, TwoDuplicates) {
|
| + Create(kSamplesPerPacket);
|
| + MockAudioPushSink mock_sink_1;
|
| + MockAudioPushSink mock_sink_2;
|
| + Play();
|
| + StartDuplicating(&mock_sink_1);
|
| + StartDuplicating(&mock_sink_2);
|
| + ReadDuplicatedAudioData({&mock_sink_1, &mock_sink_2});
|
| + StopDuplicating(&mock_sink_1);
|
| + StopDuplicating(&mock_sink_2);
|
| + Close();
|
| +}
|
| +
|
| +TEST_F(AudioOutputControllerTest, DuplicateDivertInteract) {
|
| + Create(kSamplesPerPacket);
|
| + MockAudioPushSink mock_sink;
|
| + Play();
|
| + StartDuplicating(&mock_sink);
|
| + DivertWhilePlaying();
|
| +
|
| + // When diverted stream pulls data, it would trigger a push to sink.
|
| + EXPECT_CALL(mock_sink, OnDataCheck(kBufferNonZeroData));
|
| + ReadDivertedAudioData();
|
| +
|
| + StopDuplicating(&mock_sink);
|
| + RevertWhilePlaying();
|
| + Close();
|
| +}
|
| +
|
| +TEST_F(AudioOutputControllerTest, DuplicateSwitchDeviceInteract) {
|
| + Create(kSamplesPerPacket);
|
| + MockAudioPushSink mock_sink;
|
| + Play();
|
| + StartDuplicating(&mock_sink);
|
| + ReadDuplicatedAudioData({&mock_sink});
|
| +
|
| + // Switching device would trigger a read, and in turn it would trigger a push
|
| + // to sink.
|
| + EXPECT_CALL(mock_sink, OnDataCheck(kBufferNonZeroData));
|
| + SwitchDevice(false);
|
| +
|
| + StopDuplicating(&mock_sink);
|
| + Close();
|
| +}
|
| +
|
| } // namespace media
|
|
|