Chromium Code Reviews| 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 898af7e2e71dde10167b6d3621d0622fd63eb1fc..1849008e0f00e40b55e0e1b6538563612efa04f1 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/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,16 @@ 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(const 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 +188,11 @@ class AudioOutputControllerTest : public testing::Test { |
| base::RunLoop().RunUntilIdle(); |
| } |
| + void Duplicate(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 +202,20 @@ class AudioOutputControllerTest : public testing::Test { |
| EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]); |
| } |
| + void ReadDuplicatedAudioData(std::vector<MockAudioPushSink*> sinks) { |
|
miu
2016/05/06 22:29:50
The argument type should be: const std::vector<...
qiangchen
2016/05/10 22:36:53
Done.
|
| + 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]); |
| + } |
| + |
| void Revert(bool was_playing) { |
| if (was_playing) { |
| // Expect the handler to receive one OnPlaying() call as a result of the |
| @@ -199,6 +229,12 @@ class AudioOutputControllerTest : public testing::Test { |
| base::RunLoop().RunUntilIdle(); |
| } |
| + void StopDuplicate(MockAudioPushSink* sink) { |
|
miu
2016/05/06 22:29:50
naming nit: StopDuplicating
qiangchen
2016/05/10 22:36:53
Done.
|
| + 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 +372,59 @@ TEST_F(AudioOutputControllerTest, DivertRevertClose) { |
| Close(); |
| } |
| +TEST_F(AudioOutputControllerTest, PlayDuplicateStopClose) { |
|
miu
2016/05/06 22:29:50
Nice tests here too! :)
qiangchen
2016/05/10 22:36:53
Acknowledged.
|
| + Create(kSamplesPerPacket); |
| + MockAudioPushSink mock_sink; |
| + Play(); |
| + Duplicate(&mock_sink); |
| + ReadDuplicatedAudioData({&mock_sink}); |
| + StopDuplicate(&mock_sink); |
| + Close(); |
| +} |
| + |
| +TEST_F(AudioOutputControllerTest, TwoDuplicates) { |
| + Create(kSamplesPerPacket); |
| + MockAudioPushSink mock_sink_1; |
| + MockAudioPushSink mock_sink_2; |
| + Play(); |
| + Duplicate(&mock_sink_1); |
| + Duplicate(&mock_sink_2); |
| + ReadDuplicatedAudioData({&mock_sink_1, &mock_sink_2}); |
| + StopDuplicate(&mock_sink_1); |
| + StopDuplicate(&mock_sink_2); |
| + Close(); |
| +} |
| + |
| +TEST_F(AudioOutputControllerTest, DuplicateDivertInteract) { |
| + Create(kSamplesPerPacket); |
| + MockAudioPushSink mock_sink; |
| + Play(); |
| + Duplicate(&mock_sink); |
| + DivertWhilePlaying(); |
| + |
| + // When diverted stream pulls data, it would trigger a push to sink. |
| + EXPECT_CALL(mock_sink, OnDataCheck(kBufferNonZeroData)); |
| + ReadDivertedAudioData(); |
| + |
| + StopDuplicate(&mock_sink); |
| + RevertWhilePlaying(); |
| + Close(); |
| +} |
| + |
| +TEST_F(AudioOutputControllerTest, DuplicateSwitchDeviceInteract) { |
| + Create(kSamplesPerPacket); |
| + MockAudioPushSink mock_sink; |
| + Play(); |
| + Duplicate(&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); |
| + |
| + StopDuplicate(&mock_sink); |
| + Close(); |
| +} |
| + |
| } // namespace media |