Index: content/renderer/media/html_audio_element_capturer_source_unittest.cc |
diff --git a/content/renderer/media/html_audio_element_capturer_source_unittest.cc b/content/renderer/media/html_audio_element_capturer_source_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e5dd1a75fda918a929602d77f8d26637556dead1 |
--- /dev/null |
+++ b/content/renderer/media/html_audio_element_capturer_source_unittest.cc |
@@ -0,0 +1,134 @@ |
+// 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/memory/weak_ptr.h" |
+#include "base/run_loop.h" |
+#include "base/threading/thread_task_runner_handle.h" |
+#include "content/renderer/media/html_audio_element_capturer_source.h" |
+#include "media/audio/null_audio_sink.h" |
+#include "media/base/audio_parameters.h" |
+#include "media/blink/webaudiosourceprovider_impl.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using ::testing::_; |
+using ::testing::AllOf; |
+using ::testing::InSequence; |
+using ::testing::Mock; |
+using ::testing::Property; |
+ |
+namespace content { |
+ |
+// These constants represent the sampling rates and samples per buffer for input |
+// and output as seen by HTMLAudioElementCapturerSource. For the purpose of the |
+// test, both are chunks of 10ms, which happens to be the preferred one of |
+// MediaStream Audio Tracks. |
+static const int kNumChannelsForTest = 1; |
+static const int kBufferDurationMs = 10; |
+ |
+// This value mimics what is provided by WebAudioSourceProviderImpl. |
+static const int kPlaybackAudioTrackSamplesPerBuffer = 1024; |
+ |
+static const int kMediaStreamAudioTrackSampleRate = 48000; |
+static const int kMediaStreamAudioTrackSamplesPerBuffer = |
+ kMediaStreamAudioTrackSampleRate * kBufferDurationMs / 1000; |
+ |
+ACTION_P(RunClosure, closure) { |
+ closure.Run(); |
+} |
+ |
+class MockWebAudioSourceProvider : public media::WebAudioSourceProviderImpl { |
+ public: |
+ MockWebAudioSourceProvider() |
+ : WebAudioSourceProviderImpl( |
+ new media::NullAudioSink(base::ThreadTaskRunnerHandle::Get())) {} |
+ |
+ void SetCopyAudioCallback(const CopyAudioCB& callback) override { |
+ DVLOG(1) << __FUNCTION__; |
+ callback_ = callback; |
+ |
+ // We're super eager and send an AudioBus right after Start(). |
+ callback_.Run(media::AudioBus::Create(kNumChannelsForTest, |
+ kPlaybackAudioTrackSamplesPerBuffer), |
+ 0 /* delay_milliseconds */, 44100 /* sample_rate */); |
+ } |
+ void ClearCopyAudioCallback() override { |
+ callback_.Reset(); |
+ } |
+ |
+ protected: |
+ ~MockWebAudioSourceProvider() override = default; |
+ |
+ private: |
+ CopyAudioCB callback_; |
+}; |
+ |
+class HTMLAudioElementCapturerSourceTest |
+ : public testing::Test, |
+ public media::AudioCapturerSource::CaptureCallback { |
+ public: |
+ HTMLAudioElementCapturerSourceTest() |
+ : audio_source_(new MockWebAudioSourceProvider()), |
+ html_audio_capturer_( |
+ new HtmlAudioElementCapturerSource(audio_source_->AsWeakPtr())) {} |
+ |
+ // media::AudioCapturerSource::CaptureCallback implementation |
+ MOCK_METHOD4(Capture, |
+ void(const media::AudioBus* audio_source, |
+ int audio_delay_milliseconds, |
+ double volume, |
+ bool key_pressed)); |
+ MOCK_METHOD1(OnCaptureError, void(const std::string& message)); |
+ |
+ protected: |
+ // We need some kind of message loop to allow |html_audio_capturer_| to |
+ // schedule capture events. |
+ const base::MessageLoopForUI message_loop_; |
+ |
+ scoped_refptr<MockWebAudioSourceProvider> audio_source_; |
+ scoped_refptr<HtmlAudioElementCapturerSource> html_audio_capturer_; |
+}; |
+ |
+// Constructs and destructs all objects, in particular |html_audio_capturer_| |
+// and its inner object(s). This is a non trivial sequence. |
+TEST_F(HTMLAudioElementCapturerSourceTest, ConstructAndDestruct) {} |
+ |
+TEST_F(HTMLAudioElementCapturerSourceTest, InitializeStartAndStop) { |
+ InSequence s; |
+ |
+ base::RunLoop run_loop; |
+ base::Closure quit_closure = run_loop.QuitClosure(); |
+ |
+ // Similar to what WebRtcAudioCapturer::SetCapturerSourceInternal() does. |
+ const media::AudioParameters params( |
+ media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
+ media::GuessChannelLayout(kNumChannelsForTest), |
+ kMediaStreamAudioTrackSampleRate /* sample_rate */, |
+ 16 /* bits_per_sample */, |
+ kMediaStreamAudioTrackSamplesPerBuffer /* frames_per_buffer */); |
+ html_audio_capturer_->Initialize(params, this, 0 /* session_id */); |
+ |
+ EXPECT_CALL( |
+ *this, |
+ Capture(AllOf(Property(&media::AudioBus::channels, kNumChannelsForTest), |
+ Property(&media::AudioBus::frames, |
+ kMediaStreamAudioTrackSamplesPerBuffer)), |
+ _, 1.0, false)) |
+ .Times(1); |
+ EXPECT_CALL( |
+ *this, |
+ Capture(AllOf(Property(&media::AudioBus::channels, kNumChannelsForTest), |
+ Property(&media::AudioBus::frames, |
+ kMediaStreamAudioTrackSamplesPerBuffer)), |
+ _, 1.0, false)) |
+ .Times(1) |
+ .WillOnce(RunClosure(quit_closure)); |
+ html_audio_capturer_->Start(); |
+ run_loop.Run(); |
+ |
+ html_audio_capturer_->Stop(); |
+ Mock::VerifyAndClearExpectations(this); |
+} |
+ |
+} // namespace content |