1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/media/capture/audio_mirroring_manager.h"
10 #include "base/bind_helpers.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "content/browser/browser_thread_impl.h"
14 #include "media/audio/audio_parameters.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 using media::AudioOutputStream
;
19 using media::AudioParameters
;
21 using testing::NotNull
;
23 using testing::Return
;
24 using testing::ReturnRef
;
30 class MockDiverter
: public AudioMirroringManager::Diverter
{
32 MOCK_METHOD0(GetAudioParameters
, const AudioParameters
&());
33 MOCK_METHOD1(StartDiverting
, void(AudioOutputStream
*));
34 MOCK_METHOD0(StopDiverting
, void());
37 class MockMirroringDestination
38 : public AudioMirroringManager::MirroringDestination
{
40 MOCK_METHOD1(AddInput
,
41 media::AudioOutputStream
*(const media::AudioParameters
& params
));
46 class AudioMirroringManagerTest
: public testing::Test
{
48 AudioMirroringManagerTest()
49 : io_thread_(BrowserThread::IO
, &message_loop_
),
50 params_(AudioParameters::AUDIO_FAKE
, media::CHANNEL_LAYOUT_STEREO
,
51 AudioParameters::kAudioCDSampleRate
, 16,
52 AudioParameters::kAudioCDSampleRate
/ 10) {}
54 MockDiverter
* CreateStream(
55 int render_process_id
, int render_view_id
, int expected_times_diverted
) {
56 MockDiverter
* const diverter
= new MockDiverter();
57 if (expected_times_diverted
> 0) {
58 EXPECT_CALL(*diverter
, GetAudioParameters())
59 .Times(expected_times_diverted
)
60 .WillRepeatedly(ReturnRef(params_
));
61 EXPECT_CALL(*diverter
, StartDiverting(NotNull()))
62 .Times(expected_times_diverted
);
63 EXPECT_CALL(*diverter
, StopDiverting())
64 .Times(expected_times_diverted
);
67 mirroring_manager_
.AddDiverter(render_process_id
, render_view_id
, diverter
);
73 int render_process_id
, int render_view_id
, MockDiverter
* diverter
) {
74 mirroring_manager_
.RemoveDiverter(
75 render_process_id
, render_view_id
, diverter
);
80 MockMirroringDestination
* StartMirroringTo(
81 int render_process_id
, int render_view_id
, int expected_inputs_added
) {
82 MockMirroringDestination
* const dest
= new MockMirroringDestination();
83 if (expected_inputs_added
> 0) {
84 static AudioOutputStream
* const kNonNullPointer
=
85 reinterpret_cast<AudioOutputStream
*>(0x11111110);
86 EXPECT_CALL(*dest
, AddInput(Ref(params_
)))
87 .Times(expected_inputs_added
)
88 .WillRepeatedly(Return(kNonNullPointer
));
91 mirroring_manager_
.StartMirroring(render_process_id
, render_view_id
, dest
);
96 void StopMirroringTo(int render_process_id
, int render_view_id
,
97 MockMirroringDestination
* dest
) {
98 mirroring_manager_
.StopMirroring(render_process_id
, render_view_id
, dest
);
104 base::MessageLoopForIO message_loop_
;
105 BrowserThreadImpl io_thread_
;
106 AudioParameters params_
;
107 AudioMirroringManager mirroring_manager_
;
109 DISALLOW_COPY_AND_ASSIGN(AudioMirroringManagerTest
);
113 const int kRenderProcessId
= 123;
114 const int kRenderViewId
= 456;
115 const int kAnotherRenderProcessId
= 789;
116 const int kAnotherRenderViewId
= 1234;
117 const int kYetAnotherRenderProcessId
= 4560;
118 const int kYetAnotherRenderViewId
= 7890;
121 TEST_F(AudioMirroringManagerTest
, MirroringSessionOfNothing
) {
122 MockMirroringDestination
* const destination
=
123 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 0);
124 StopMirroringTo(kRenderProcessId
, kRenderViewId
, destination
);
127 TEST_F(AudioMirroringManagerTest
, TwoMirroringSessionsOfNothing
) {
128 MockMirroringDestination
* const destination
=
129 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 0);
130 StopMirroringTo(kRenderProcessId
, kRenderViewId
, destination
);
132 MockMirroringDestination
* const another_destination
=
133 StartMirroringTo(kAnotherRenderProcessId
, kAnotherRenderViewId
, 0);
134 StopMirroringTo(kAnotherRenderProcessId
, kAnotherRenderViewId
,
135 another_destination
);
138 TEST_F(AudioMirroringManagerTest
, SwitchMirroringDestinationNoStreams
) {
139 MockMirroringDestination
* const destination
=
140 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 0);
141 MockMirroringDestination
* const new_destination
=
142 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 0);
143 StopMirroringTo(kRenderProcessId
, kRenderViewId
, destination
);
144 StopMirroringTo(kRenderProcessId
, kRenderViewId
, new_destination
);
147 TEST_F(AudioMirroringManagerTest
, StreamLifetimeAroundMirroringSession
) {
148 MockDiverter
* const stream
= CreateStream(kRenderProcessId
, kRenderViewId
, 1);
149 MockMirroringDestination
* const destination
=
150 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 1);
151 StopMirroringTo(kRenderProcessId
, kRenderViewId
, destination
);
152 KillStream(kRenderProcessId
, kRenderViewId
, stream
);
155 TEST_F(AudioMirroringManagerTest
, StreamLifetimeWithinMirroringSession
) {
156 MockMirroringDestination
* const destination
=
157 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 1);
158 MockDiverter
* const stream
= CreateStream(kRenderProcessId
, kRenderViewId
, 1);
159 KillStream(kRenderProcessId
, kRenderViewId
, stream
);
160 StopMirroringTo(kRenderProcessId
, kRenderViewId
, destination
);
163 TEST_F(AudioMirroringManagerTest
, StreamLifetimeAroundTwoMirroringSessions
) {
164 MockDiverter
* const stream
= CreateStream(kRenderProcessId
, kRenderViewId
, 2);
165 MockMirroringDestination
* const destination
=
166 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 1);
167 StopMirroringTo(kRenderProcessId
, kRenderViewId
, destination
);
168 MockMirroringDestination
* const new_destination
=
169 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 1);
170 StopMirroringTo(kRenderProcessId
, kRenderViewId
, new_destination
);
171 KillStream(kRenderProcessId
, kRenderViewId
, stream
);
174 TEST_F(AudioMirroringManagerTest
, StreamLifetimeWithinTwoMirroringSessions
) {
175 MockMirroringDestination
* const destination
=
176 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 1);
177 MockDiverter
* const stream
= CreateStream(kRenderProcessId
, kRenderViewId
, 2);
178 StopMirroringTo(kRenderProcessId
, kRenderViewId
, destination
);
179 MockMirroringDestination
* const new_destination
=
180 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 1);
181 KillStream(kRenderProcessId
, kRenderViewId
, stream
);
182 StopMirroringTo(kRenderProcessId
, kRenderViewId
, new_destination
);
185 TEST_F(AudioMirroringManagerTest
, MultipleStreamsInOneMirroringSession
) {
186 MockDiverter
* const stream1
=
187 CreateStream(kRenderProcessId
, kRenderViewId
, 1);
188 MockMirroringDestination
* const destination
=
189 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 3);
190 MockDiverter
* const stream2
=
191 CreateStream(kRenderProcessId
, kRenderViewId
, 1);
192 MockDiverter
* const stream3
=
193 CreateStream(kRenderProcessId
, kRenderViewId
, 1);
194 KillStream(kRenderProcessId
, kRenderViewId
, stream2
);
195 StopMirroringTo(kRenderProcessId
, kRenderViewId
, destination
);
196 KillStream(kRenderProcessId
, kRenderViewId
, stream3
);
197 KillStream(kRenderProcessId
, kRenderViewId
, stream1
);
200 // A random interleaving of operations for three separate targets, each of which
201 // has one stream mirrored to one destination.
202 TEST_F(AudioMirroringManagerTest
, ThreeSeparateMirroringSessions
) {
203 MockDiverter
* const stream
=
204 CreateStream(kRenderProcessId
, kRenderViewId
, 1);
205 MockMirroringDestination
* const destination
=
206 StartMirroringTo(kRenderProcessId
, kRenderViewId
, 1);
208 MockMirroringDestination
* const another_destination
=
209 StartMirroringTo(kAnotherRenderProcessId
, kAnotherRenderViewId
, 1);
210 MockDiverter
* const another_stream
=
211 CreateStream(kAnotherRenderProcessId
, kAnotherRenderViewId
, 1);
213 KillStream(kRenderProcessId
, kRenderViewId
, stream
);
215 MockDiverter
* const yet_another_stream
=
216 CreateStream(kYetAnotherRenderProcessId
, kYetAnotherRenderViewId
, 1);
217 MockMirroringDestination
* const yet_another_destination
=
218 StartMirroringTo(kYetAnotherRenderProcessId
, kYetAnotherRenderViewId
, 1);
220 StopMirroringTo(kAnotherRenderProcessId
, kAnotherRenderViewId
,
221 another_destination
);
223 StopMirroringTo(kYetAnotherRenderProcessId
, kYetAnotherRenderViewId
,
224 yet_another_destination
);
226 StopMirroringTo(kRenderProcessId
, kRenderViewId
, destination
);
228 KillStream(kAnotherRenderProcessId
, kAnotherRenderViewId
, another_stream
);
229 KillStream(kYetAnotherRenderProcessId
, kYetAnotherRenderViewId
,
233 } // namespace content