Index: content/browser/renderer_host/media/audio_mirroring_manager_unittest.cc |
diff --git a/content/browser/renderer_host/media/audio_mirroring_manager_unittest.cc b/content/browser/renderer_host/media/audio_mirroring_manager_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9a586ce3eba16f65b095200e9e16858f942ffa3f |
--- /dev/null |
+++ b/content/browser/renderer_host/media/audio_mirroring_manager_unittest.cc |
@@ -0,0 +1,230 @@ |
+// Copyright (c) 2013 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/browser/renderer_host/media/audio_mirroring_manager.h" |
+ |
+#include <map> |
+ |
+#include "base/bind.h" |
+#include "base/bind_helpers.h" |
+#include "base/message_loop.h" |
+#include "base/synchronization/waitable_event.h" |
+#include "content/browser/browser_thread_impl.h" |
+#include "media/audio/audio_parameters.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using media::AudioOutputStream; |
+using media::AudioParameters; |
+using testing::_; |
+using testing::NotNull; |
+using testing::Ref; |
+using testing::Return; |
+using testing::ReturnRef; |
+ |
+namespace content { |
+ |
+class MockDiverter : public AudioMirroringManager::Diverter { |
darin (slow to review)
2013/01/09 05:06:53
nit: shouldn't these classes also be in the anonym
miu
2013/01/09 07:21:49
Done. Good call, since all these tests get linked
|
+ public: |
+ MOCK_METHOD0(GetAudioParameters, const AudioParameters&()); |
+ MOCK_METHOD1(StartDiverting, void(AudioOutputStream*)); |
+ MOCK_METHOD0(StopDiverting, void()); |
+}; |
+ |
+class MockMirroringDestination |
+ : public AudioMirroringManager::MirroringDestination { |
+ public: |
+ MOCK_METHOD1(AddInput, |
+ media::AudioOutputStream*(const media::AudioParameters& params)); |
+}; |
+ |
+class AudioMirroringManagerTest : public testing::Test { |
+ public: |
+ AudioMirroringManagerTest() |
+ : message_loop_(MessageLoop::TYPE_IO), |
+ io_thread_(BrowserThread::IO, &message_loop_), |
+ params_(AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, |
+ AudioParameters::kAudioCDSampleRate, 16, |
+ AudioParameters::kAudioCDSampleRate / 10) {} |
+ |
+ MockDiverter* CreateStream( |
+ int render_process_id, int render_view_id, int expected_times_diverted) { |
+ MockDiverter* const diverter = new MockDiverter(); |
+ if (expected_times_diverted > 0) { |
+ EXPECT_CALL(*diverter, GetAudioParameters()) |
+ .Times(expected_times_diverted) |
+ .WillRepeatedly(ReturnRef(params_)); |
+ EXPECT_CALL(*diverter, StartDiverting(NotNull())) |
+ .Times(expected_times_diverted); |
+ EXPECT_CALL(*diverter, StopDiverting()) |
+ .Times(expected_times_diverted); |
+ } |
+ |
+ mirroring_manager_.AddDiverter(render_process_id, render_view_id, diverter); |
+ |
+ return diverter; |
+ } |
+ |
+ void KillStream( |
+ int render_process_id, int render_view_id, MockDiverter* diverter) { |
+ mirroring_manager_.RemoveDiverter( |
+ render_process_id, render_view_id, diverter); |
+ |
+ delete diverter; |
+ } |
+ |
+ MockMirroringDestination* StartMirroringTo( |
+ int render_process_id, int render_view_id, int expected_inputs_added) { |
+ MockMirroringDestination* const dest = new MockMirroringDestination(); |
+ if (expected_inputs_added > 0) { |
+ static AudioOutputStream* const kNonNullPointer = |
+ reinterpret_cast<AudioOutputStream*>(0x11111110); |
+ EXPECT_CALL(*dest, AddInput(Ref(params_))) |
+ .Times(expected_inputs_added) |
+ .WillRepeatedly(Return(kNonNullPointer)); |
+ } |
+ |
+ mirroring_manager_.StartMirroring(render_process_id, render_view_id, dest); |
+ |
+ return dest; |
+ } |
+ |
+ void StopMirroringTo(int render_process_id, int render_view_id, |
+ MockMirroringDestination* dest) { |
+ mirroring_manager_.StopMirroring(render_process_id, render_view_id, dest); |
+ |
+ delete dest; |
+} |
+ |
+ private: |
+ MessageLoop message_loop_; |
+ BrowserThreadImpl io_thread_; |
+ AudioParameters params_; |
+ AudioMirroringManager mirroring_manager_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AudioMirroringManagerTest); |
+}; |
+ |
+namespace { |
+const int kRenderProcessId = 123; |
+const int kRenderViewId = 456; |
+const int kAnotherRenderProcessId = 789; |
+const int kAnotherRenderViewId = 1234; |
+const int kYetAnotherRenderProcessId = 4560; |
+const int kYetAnotherRenderViewId = 7890; |
+} |
+ |
+TEST_F(AudioMirroringManagerTest, MirroringSessionOfNothing) { |
+ MockMirroringDestination* const destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 0); |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, destination); |
+} |
+ |
+TEST_F(AudioMirroringManagerTest, TwoMirroringSessionsOfNothing) { |
+ MockMirroringDestination* const destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 0); |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, destination); |
+ |
+ MockMirroringDestination* const another_destination = |
+ StartMirroringTo(kAnotherRenderProcessId, kAnotherRenderViewId, 0); |
+ StopMirroringTo(kAnotherRenderProcessId, kAnotherRenderViewId, |
+ another_destination); |
+} |
+ |
+TEST_F(AudioMirroringManagerTest, SwitchMirroringDestinationNoStreams) { |
+ MockMirroringDestination* const destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 0); |
+ MockMirroringDestination* const new_destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 0); |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, destination); |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, new_destination); |
+} |
+ |
+TEST_F(AudioMirroringManagerTest, StreamLifetimeAroundMirroringSession) { |
+ MockDiverter* const stream = CreateStream(kRenderProcessId, kRenderViewId, 1); |
+ MockMirroringDestination* const destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 1); |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, destination); |
+ KillStream(kRenderProcessId, kRenderViewId, stream); |
+} |
+ |
+TEST_F(AudioMirroringManagerTest, StreamLifetimeWithinMirroringSession) { |
+ MockMirroringDestination* const destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 1); |
+ MockDiverter* const stream = CreateStream(kRenderProcessId, kRenderViewId, 1); |
+ KillStream(kRenderProcessId, kRenderViewId, stream); |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, destination); |
+} |
+ |
+TEST_F(AudioMirroringManagerTest, StreamLifetimeAroundTwoMirroringSessions) { |
+ MockDiverter* const stream = CreateStream(kRenderProcessId, kRenderViewId, 2); |
+ MockMirroringDestination* const destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 1); |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, destination); |
+ MockMirroringDestination* const new_destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 1); |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, new_destination); |
+ KillStream(kRenderProcessId, kRenderViewId, stream); |
+} |
+ |
+TEST_F(AudioMirroringManagerTest, StreamLifetimeWithinTwoMirroringSessions) { |
+ MockMirroringDestination* const destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 1); |
+ MockDiverter* const stream = CreateStream(kRenderProcessId, kRenderViewId, 2); |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, destination); |
+ MockMirroringDestination* const new_destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 1); |
+ KillStream(kRenderProcessId, kRenderViewId, stream); |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, new_destination); |
+} |
+ |
+TEST_F(AudioMirroringManagerTest, MultipleStreamsInOneMirroringSession) { |
+ MockDiverter* const stream1 = |
+ CreateStream(kRenderProcessId, kRenderViewId, 1); |
+ MockMirroringDestination* const destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 3); |
+ MockDiverter* const stream2 = |
+ CreateStream(kRenderProcessId, kRenderViewId, 1); |
+ MockDiverter* const stream3 = |
+ CreateStream(kRenderProcessId, kRenderViewId, 1); |
+ KillStream(kRenderProcessId, kRenderViewId, stream2); |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, destination); |
+ KillStream(kRenderProcessId, kRenderViewId, stream3); |
+ KillStream(kRenderProcessId, kRenderViewId, stream1); |
+} |
+ |
+// A random interleaving of operations for three separate targets, each of which |
+// has one stream mirrored to one destination. |
+TEST_F(AudioMirroringManagerTest, ThreeSeparateMirroringSessions) { |
+ MockDiverter* const stream = |
+ CreateStream(kRenderProcessId, kRenderViewId, 1); |
+ MockMirroringDestination* const destination = |
+ StartMirroringTo(kRenderProcessId, kRenderViewId, 1); |
+ |
+ MockMirroringDestination* const another_destination = |
+ StartMirroringTo(kAnotherRenderProcessId, kAnotherRenderViewId, 1); |
+ MockDiverter* const another_stream = |
+ CreateStream(kAnotherRenderProcessId, kAnotherRenderViewId, 1); |
+ |
+ KillStream(kRenderProcessId, kRenderViewId, stream); |
+ |
+ MockDiverter* const yet_another_stream = |
+ CreateStream(kYetAnotherRenderProcessId, kYetAnotherRenderViewId, 1); |
+ MockMirroringDestination* const yet_another_destination = |
+ StartMirroringTo(kYetAnotherRenderProcessId, kYetAnotherRenderViewId, 1); |
+ |
+ StopMirroringTo(kAnotherRenderProcessId, kAnotherRenderViewId, |
+ another_destination); |
+ |
+ StopMirroringTo(kYetAnotherRenderProcessId, kYetAnotherRenderViewId, |
+ yet_another_destination); |
+ |
+ StopMirroringTo(kRenderProcessId, kRenderViewId, destination); |
+ |
+ KillStream(kAnotherRenderProcessId, kAnotherRenderViewId, another_stream); |
+ KillStream(kYetAnotherRenderProcessId, kYetAnotherRenderViewId, |
+ yet_another_stream); |
+} |
+ |
+} // namespace content |