1 // Copyright (c) 2011 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 "base/message_loop.h"
6 #include "base/threading/platform_thread.h"
7 #include "media/audio/audio_output_dispatcher.h"
8 #include "media/audio/audio_output_proxy.h"
9 #include "media/audio/audio_manager.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
14 using ::testing::Mock
;
15 using ::testing::Return
;
17 static const int kTestCloseDelayMs
= 100;
19 // Used in the test where we don't want a stream to be closed unexpectedly.
20 static const int kTestBigCloseDelayMs
= 1000 * 1000;
22 class MockAudioOutputStream
: public AudioOutputStream
{
24 MockAudioOutputStream() {}
26 MOCK_METHOD0(Open
, bool());
27 MOCK_METHOD1(Start
, void(AudioSourceCallback
* callback
));
28 MOCK_METHOD0(Stop
, void());
29 MOCK_METHOD1(SetVolume
, void(double volume
));
30 MOCK_METHOD1(GetVolume
, void(double* volume
));
31 MOCK_METHOD0(Close
, void());
34 class MockAudioManager
: public AudioManager
{
38 MOCK_METHOD0(Init
, void());
39 MOCK_METHOD0(Cleanup
, void());
40 MOCK_METHOD0(HasAudioOutputDevices
, bool());
41 MOCK_METHOD0(HasAudioInputDevices
, bool());
42 MOCK_METHOD0(GetAudioInputDeviceModel
, string16());
43 MOCK_METHOD1(MakeAudioOutputStream
, AudioOutputStream
*(
44 const AudioParameters
& params
));
45 MOCK_METHOD1(MakeAudioOutputStreamProxy
, AudioOutputStream
*(
46 const AudioParameters
& params
));
47 MOCK_METHOD1(MakeAudioInputStream
, AudioInputStream
*(
48 const AudioParameters
& params
));
49 MOCK_METHOD0(MuteAll
, void());
50 MOCK_METHOD0(UnMuteAll
, void());
51 MOCK_METHOD0(CanShowAudioInputSettings
, bool());
52 MOCK_METHOD0(ShowAudioInputSettings
, void());
53 MOCK_METHOD0(GetMessageLoop
, MessageLoop
*());
54 MOCK_METHOD1(GetAudioInputDeviceNames
, void(
55 media::AudioDeviceNames
* device_name
));
56 MOCK_METHOD0(IsRecordingInProcess
, bool());
59 class MockAudioSourceCallback
: public AudioOutputStream::AudioSourceCallback
{
61 MOCK_METHOD4(OnMoreData
, uint32(AudioOutputStream
* stream
,
62 uint8
* dest
, uint32 max_size
,
63 AudioBuffersState buffers_state
));
64 MOCK_METHOD2(OnError
, void(AudioOutputStream
* stream
, int code
));
67 class AudioOutputProxyTest
: public testing::Test
{
69 virtual void SetUp() {
70 EXPECT_CALL(manager_
, GetMessageLoop())
71 .WillRepeatedly(Return(&message_loop_
));
72 InitDispatcher(kTestCloseDelayMs
);
75 virtual void TearDown() {
76 // All paused proxies should have been closed at this point.
77 EXPECT_EQ(0u, dispatcher_
->paused_proxies_
);
79 // This is necessary to free all proxy objects that have been
80 // closed by the test.
81 message_loop_
.RunAllPending();
84 void InitDispatcher(int close_delay_ms
) {
85 AudioParameters
params(AudioParameters::AUDIO_PCM_LINEAR
,
86 CHANNEL_LAYOUT_STEREO
, 44100, 16, 1024);
87 dispatcher_
= new AudioOutputDispatcher(&manager_
, params
, close_delay_ms
);
90 MessageLoop message_loop_
;
91 scoped_refptr
<AudioOutputDispatcher
> dispatcher_
;
92 MockAudioManager manager_
;
93 MockAudioSourceCallback callback_
;
96 TEST_F(AudioOutputProxyTest
, CreateAndClose
) {
97 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
101 TEST_F(AudioOutputProxyTest
, OpenAndClose
) {
102 MockAudioOutputStream stream
;
104 EXPECT_CALL(manager_
, MakeAudioOutputStream(_
))
105 .WillOnce(Return(&stream
));
106 EXPECT_CALL(stream
, Open())
107 .WillOnce(Return(true));
108 EXPECT_CALL(stream
, Close())
111 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
112 EXPECT_TRUE(proxy
->Open());
116 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
117 // if it doesn't start playing.
118 TEST_F(AudioOutputProxyTest
, CreateAndWait
) {
119 MockAudioOutputStream stream
;
121 EXPECT_CALL(manager_
, MakeAudioOutputStream(_
))
122 .WillOnce(Return(&stream
));
123 EXPECT_CALL(stream
, Open())
124 .WillOnce(Return(true));
125 EXPECT_CALL(stream
, Close())
128 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
129 EXPECT_TRUE(proxy
->Open());
132 base::PlatformThread::Sleep(kTestCloseDelayMs
* 2);
133 message_loop_
.RunAllPending();
135 // Verify expectation before calling Close().
136 Mock::VerifyAndClear(&stream
);
141 // Create a stream, and then calls Start() and Stop().
142 TEST_F(AudioOutputProxyTest
, StartAndStop
) {
143 MockAudioOutputStream stream
;
145 EXPECT_CALL(manager_
, MakeAudioOutputStream(_
))
146 .WillOnce(Return(&stream
));
147 EXPECT_CALL(stream
, Open())
148 .WillOnce(Return(true));
149 EXPECT_CALL(stream
, Start(_
))
151 EXPECT_CALL(stream
, SetVolume(_
))
153 EXPECT_CALL(stream
, Stop())
155 EXPECT_CALL(stream
, Close())
158 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
159 EXPECT_TRUE(proxy
->Open());
161 proxy
->Start(&callback_
);
167 // Verify that the stream is closed after Stop is called.
168 TEST_F(AudioOutputProxyTest
, CloseAfterStop
) {
169 MockAudioOutputStream stream
;
171 EXPECT_CALL(manager_
, MakeAudioOutputStream(_
))
172 .WillOnce(Return(&stream
));
173 EXPECT_CALL(stream
, Open())
174 .WillOnce(Return(true));
175 EXPECT_CALL(stream
, Start(_
))
177 EXPECT_CALL(stream
, SetVolume(_
))
179 EXPECT_CALL(stream
, Stop())
181 EXPECT_CALL(stream
, Close())
184 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
185 EXPECT_TRUE(proxy
->Open());
187 proxy
->Start(&callback_
);
191 message_loop_
.RunAllPending();
192 base::PlatformThread::Sleep(kTestCloseDelayMs
* 10);
193 message_loop_
.RunAllPending();
195 // Verify expectation before calling Close().
196 Mock::VerifyAndClear(&stream
);
201 // Create two streams, but don't start them. Only one device must be open.
202 TEST_F(AudioOutputProxyTest
, TwoStreams
) {
203 MockAudioOutputStream stream
;
205 EXPECT_CALL(manager_
, MakeAudioOutputStream(_
))
206 .WillOnce(Return(&stream
));
207 EXPECT_CALL(stream
, Open())
208 .WillOnce(Return(true));
209 EXPECT_CALL(stream
, Close())
212 AudioOutputProxy
* proxy1
= new AudioOutputProxy(dispatcher_
);
213 AudioOutputProxy
* proxy2
= new AudioOutputProxy(dispatcher_
);
214 EXPECT_TRUE(proxy1
->Open());
215 EXPECT_TRUE(proxy2
->Open());
220 // Two streams: verify that second stream is allocated when the first
222 TEST_F(AudioOutputProxyTest
, TwoStreams_OnePlaying
) {
223 MockAudioOutputStream stream1
;
224 MockAudioOutputStream stream2
;
226 InitDispatcher(kTestBigCloseDelayMs
);
228 EXPECT_CALL(manager_
, MakeAudioOutputStream(_
))
229 .WillOnce(Return(&stream1
))
230 .WillOnce(Return(&stream2
));
232 EXPECT_CALL(stream1
, Open())
233 .WillOnce(Return(true));
234 EXPECT_CALL(stream1
, Start(_
))
236 EXPECT_CALL(stream1
, SetVolume(_
))
238 EXPECT_CALL(stream1
, Stop())
240 EXPECT_CALL(stream1
, Close())
243 EXPECT_CALL(stream2
, Open())
244 .WillOnce(Return(true));
245 EXPECT_CALL(stream2
, Close())
248 AudioOutputProxy
* proxy1
= new AudioOutputProxy(dispatcher_
);
249 AudioOutputProxy
* proxy2
= new AudioOutputProxy(dispatcher_
);
250 EXPECT_TRUE(proxy1
->Open());
251 EXPECT_TRUE(proxy2
->Open());
253 proxy1
->Start(&callback_
);
254 message_loop_
.RunAllPending();
261 // Two streams, both are playing. Dispatcher should not open a third stream.
262 TEST_F(AudioOutputProxyTest
, TwoStreams_BothPlaying
) {
263 MockAudioOutputStream stream1
;
264 MockAudioOutputStream stream2
;
266 InitDispatcher(kTestBigCloseDelayMs
);
268 EXPECT_CALL(manager_
, MakeAudioOutputStream(_
))
269 .WillOnce(Return(&stream1
))
270 .WillOnce(Return(&stream2
));
272 EXPECT_CALL(stream1
, Open())
273 .WillOnce(Return(true));
274 EXPECT_CALL(stream1
, Start(_
))
276 EXPECT_CALL(stream1
, SetVolume(_
))
278 EXPECT_CALL(stream1
, Stop())
280 EXPECT_CALL(stream1
, Close())
283 EXPECT_CALL(stream2
, Open())
284 .WillOnce(Return(true));
285 EXPECT_CALL(stream2
, Start(_
))
287 EXPECT_CALL(stream2
, SetVolume(_
))
289 EXPECT_CALL(stream2
, Stop())
291 EXPECT_CALL(stream2
, Close())
294 AudioOutputProxy
* proxy1
= new AudioOutputProxy(dispatcher_
);
295 AudioOutputProxy
* proxy2
= new AudioOutputProxy(dispatcher_
);
296 EXPECT_TRUE(proxy1
->Open());
297 EXPECT_TRUE(proxy2
->Open());
299 proxy1
->Start(&callback_
);
300 proxy2
->Start(&callback_
);
308 // Open() method failed.
309 TEST_F(AudioOutputProxyTest
, OpenFailed
) {
310 MockAudioOutputStream stream
;
312 EXPECT_CALL(manager_
, MakeAudioOutputStream(_
))
313 .WillOnce(Return(&stream
));
314 EXPECT_CALL(stream
, Open())
315 .WillOnce(Return(false));
316 EXPECT_CALL(stream
, Close())
319 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
320 EXPECT_FALSE(proxy
->Open());
324 // Start() method failed.
325 TEST_F(AudioOutputProxyTest
, StartFailed
) {
326 MockAudioOutputStream stream
;
328 EXPECT_CALL(manager_
, MakeAudioOutputStream(_
))
329 .WillOnce(Return(&stream
));
330 EXPECT_CALL(stream
, Open())
331 .WillOnce(Return(true));
332 EXPECT_CALL(stream
, Close())
335 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
336 EXPECT_TRUE(proxy
->Open());
339 base::PlatformThread::Sleep(kTestCloseDelayMs
);
340 message_loop_
.RunAllPending();
342 // Verify expectation before calling Close().
343 Mock::VerifyAndClear(&stream
);
345 // |stream| is closed at this point. Start() should reopen it again.
346 EXPECT_CALL(manager_
, MakeAudioOutputStream(_
))
347 .WillOnce(Return(reinterpret_cast<AudioOutputStream
*>(NULL
)));
349 EXPECT_CALL(callback_
, OnError(_
, _
))
352 proxy
->Start(&callback_
);
354 Mock::VerifyAndClear(&callback_
);