Index: content/renderer/media/renderer_webaudiodevice_impl_unittest.cc |
diff --git a/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc b/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9927ef6aa7a125c88fa6d780334c6acbd7c88c4b |
--- /dev/null |
+++ b/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc |
@@ -0,0 +1,144 @@ |
+// 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 "content/renderer/media/renderer_webaudiodevice_impl.h" |
+ |
+#include "base/bind.h" |
+#include "content/renderer/media/audio_device_factory.h" |
+#include "media/base/audio_capturer_source.h" |
+#include "media/base/mock_audio_renderer_sink.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using testing::_; |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+const int kHardwareSampleRate = 44100; |
+const int kHardwareBufferSize = 128; |
+const int kRenderFrameId = 100; |
+ |
+int MockFrameIdFromCurrentContext() { |
+ return kRenderFrameId; |
+} |
+ |
+media::AudioParameters MockGetOutputDeviceParameters( |
+ int frame_id, |
+ int session_id, |
+ const std::string& device_id, |
+ const url::Origin& security_origin) { |
+ return media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
+ media::CHANNEL_LAYOUT_STEREO, |
+ kHardwareSampleRate, 16, kHardwareBufferSize); |
+} |
+ |
+class MockRendererWebAudioDeviceImpl : public RendererWebAudioDeviceImpl { |
o1ka
2016/12/07 20:56:01
Nit: such class is usually called FooUnderTest. (
Andrew MacPherson
2016/12/08 10:06:12
Done, fixed the class name. Re: virtual methods I
o1ka
2016/12/08 10:57:19
Sounds good.
|
+ public: |
+ MockRendererWebAudioDeviceImpl( |
+ media::ChannelLayout layout, |
+ const blink::WebAudioLatencyHint& latency_hint, |
+ blink::WebAudioDevice::RenderCallback* callback, |
+ int session_id, |
+ const url::Origin& security_origin) |
+ : RendererWebAudioDeviceImpl(layout, |
+ latency_hint, |
+ callback, |
+ session_id, |
+ security_origin, |
+ base::Bind(&MockGetOutputDeviceParameters), |
+ base::Bind(&MockFrameIdFromCurrentContext)) { |
+ } |
+}; |
+ |
+} // namespace |
+ |
+class RendererWebAudioDeviceImplTest |
+ : public blink::WebAudioDevice::RenderCallback, |
+ public AudioDeviceFactory, |
+ public testing::Test { |
+ public: |
+ MOCK_METHOD3(render, |
+ void(const blink::WebVector<float*>& sourceData, |
+ const blink::WebVector<float*>& destinationData, |
+ size_t numberOfFrames)); |
+ |
+ protected: |
+ RendererWebAudioDeviceImplTest() {} |
+ |
+ void SetupDevice(blink::WebAudioLatencyHint latencyHint) { |
+ webaudio_device_.reset(new MockRendererWebAudioDeviceImpl( |
+ media::CHANNEL_LAYOUT_MONO, latencyHint, this, 0, url::Origin())); |
+ } |
+ |
+ MOCK_METHOD1(CreateAudioCapturerSource, |
+ scoped_refptr<media::AudioCapturerSource>(int)); |
+ MOCK_METHOD4(CreateFinalAudioRendererSink, |
+ scoped_refptr<media::AudioRendererSink>(int, |
+ int, |
+ const std::string&, |
+ const url::Origin&)); |
+ MOCK_METHOD5( |
+ CreateSwitchableAudioRendererSink, |
+ scoped_refptr<media::SwitchableAudioRendererSink>(SourceType, |
+ int, |
+ int, |
+ const std::string&, |
+ const url::Origin&)); |
+ |
+ scoped_refptr<media::AudioRendererSink> CreateAudioRendererSink( |
+ SourceType source_type, |
+ int render_frame_id, |
+ int session_id, |
+ const std::string& device_id, |
+ const url::Origin& security_origin) { |
+ scoped_refptr<media::MockAudioRendererSink> fake_sink( |
o1ka
2016/12/07 20:56:01
Is this local needed?
Andrew MacPherson
2016/12/08 10:06:12
Done.
|
+ new media::MockAudioRendererSink( |
+ device_id, media::OUTPUT_DEVICE_STATUS_OK, |
+ MockGetOutputDeviceParameters(render_frame_id, session_id, |
+ device_id, security_origin))); |
+ mock_sink_ = fake_sink; |
+ |
+ EXPECT_CALL(*mock_sink_.get(), Start()); |
o1ka
2016/12/07 20:56:01
Do you start WebAudioDeviceImpl in each test? Will
Andrew MacPherson
2016/12/08 10:06:12
The CreateAudioRendererSink method is only invoked
o1ka
2016/12/08 10:57:19
Acknowledged.
|
+ EXPECT_CALL(*mock_sink_.get(), Play()); |
+ |
o1ka
2016/12/07 20:56:01
We should ensure the sink gets stopped - this is a
Andrew MacPherson
2016/12/08 10:06:12
Done, I've moved the EXPECT_CALL for Stop up to wh
|
+ return fake_sink; |
+ } |
+ |
+ void TearDown() override { |
+ webaudio_device_.reset(); |
+ mock_sink_ = nullptr; |
+ } |
+ |
+ std::unique_ptr<RendererWebAudioDeviceImpl> webaudio_device_; |
+ scoped_refptr<media::MockAudioRendererSink> mock_sink_; |
+}; |
+ |
+TEST_F(RendererWebAudioDeviceImplTest, TestLatencyHint) { |
+ SetupDevice(blink::WebAudioLatencyHint( |
+ blink::WebAudioLatencyHint::CategoryInteractive)); |
+ int interactive_frames = webaudio_device_->framesPerBuffer(); |
+ |
+ SetupDevice( |
+ blink::WebAudioLatencyHint(blink::WebAudioLatencyHint::CategoryBalanced)); |
+ int balanced_frames = webaudio_device_->framesPerBuffer(); |
+ |
+ SetupDevice( |
+ blink::WebAudioLatencyHint(blink::WebAudioLatencyHint::CategoryPlayback)); |
+ int playback_frames = webaudio_device_->framesPerBuffer(); |
+ |
+ EXPECT_GT(playback_frames, balanced_frames); |
+ EXPECT_GT(balanced_frames, interactive_frames); |
o1ka
2016/12/07 20:56:01
Have you considered comparing with media::AudioLat
Andrew MacPherson
2016/12/08 10:06:12
I've added a latencyType() method to the WebAudioD
o1ka
2016/12/08 10:57:19
Sorry, I was unclear. latencyType() method is not
Andrew MacPherson
2016/12/08 12:22:54
Ah, sorry, I think I read too quickly and misunder
o1ka
2016/12/08 13:10:15
Great, thanks!
|
+} |
+ |
+TEST_F(RendererWebAudioDeviceImplTest, TestStartStop) { |
+ SetupDevice(blink::WebAudioLatencyHint( |
+ blink::WebAudioLatencyHint::CategoryInteractive)); |
+ webaudio_device_->start(); |
+ EXPECT_CALL(*mock_sink_.get(), Stop()); |
+ webaudio_device_->stop(); |
+} |
+ |
o1ka
2016/12/07 20:56:01
Could you add testing that sampleRate() and frames
Andrew MacPherson
2016/12/08 10:06:12
Done, I just modified the very simple StartStop te
|
+} // namespace content |