1 // Copyright (c) 2012 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/message_loop_proxy.h"
7 #include "base/threading/platform_thread.h"
8 #include "media/audio/audio_output_dispatcher.h"
9 #include "media/audio/audio_output_proxy.h"
10 #include "media/audio/audio_manager.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
15 using ::testing::Mock
;
16 using ::testing::Return
;
17 using media::AudioBuffersState
;
18 using media::AudioInputStream
;
19 using media::AudioManager
;
20 using media::AudioOutputDispatcher
;
21 using media::AudioOutputProxy
;
22 using media::AudioOutputStream
;
23 using media::AudioParameters
;
27 static const int kTestCloseDelayMs
= 100;
29 // Used in the test where we don't want a stream to be closed unexpectedly.
30 static const int kTestBigCloseDelaySeconds
= 1000;
32 class MockAudioOutputStream
: public AudioOutputStream
{
34 MockAudioOutputStream() {}
36 MOCK_METHOD0(Open
, bool());
37 MOCK_METHOD1(Start
, void(AudioSourceCallback
* callback
));
38 MOCK_METHOD0(Stop
, void());
39 MOCK_METHOD1(SetVolume
, void(double volume
));
40 MOCK_METHOD1(GetVolume
, void(double* volume
));
41 MOCK_METHOD0(Close
, void());
44 class MockAudioManager
: public AudioManager
{
48 MOCK_METHOD0(Init
, void());
49 MOCK_METHOD0(Cleanup
, void());
50 MOCK_METHOD0(HasAudioOutputDevices
, bool());
51 MOCK_METHOD0(HasAudioInputDevices
, bool());
52 MOCK_METHOD0(GetAudioInputDeviceModel
, string16());
53 MOCK_METHOD1(MakeAudioOutputStream
, AudioOutputStream
*(
54 const AudioParameters
& params
));
55 MOCK_METHOD1(MakeAudioOutputStreamProxy
, AudioOutputStream
*(
56 const AudioParameters
& params
));
57 MOCK_METHOD2(MakeAudioInputStream
, AudioInputStream
*(
58 const AudioParameters
& params
, const std::string
& device_id
));
59 MOCK_METHOD0(MuteAll
, void());
60 MOCK_METHOD0(UnMuteAll
, void());
61 MOCK_METHOD0(CanShowAudioInputSettings
, bool());
62 MOCK_METHOD0(ShowAudioInputSettings
, void());
63 MOCK_METHOD0(GetMessageLoop
, scoped_refptr
<base::MessageLoopProxy
>());
64 MOCK_METHOD1(GetAudioInputDeviceNames
, void(
65 media::AudioDeviceNames
* device_name
));
66 MOCK_METHOD0(IsRecordingInProcess
, bool());
69 class MockAudioSourceCallback
: public AudioOutputStream::AudioSourceCallback
{
71 MOCK_METHOD4(OnMoreData
, uint32(AudioOutputStream
* stream
,
72 uint8
* dest
, uint32 max_size
,
73 AudioBuffersState buffers_state
));
74 MOCK_METHOD2(OnError
, void(AudioOutputStream
* stream
, int code
));
81 class AudioOutputProxyTest
: public testing::Test
{
83 virtual void SetUp() {
84 EXPECT_CALL(manager_
, GetMessageLoop())
85 .WillRepeatedly(Return(message_loop_
.message_loop_proxy()));
86 InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs
));
89 virtual void TearDown() {
90 // All paused proxies should have been closed at this point.
91 EXPECT_EQ(0u, dispatcher_
->paused_proxies_
);
93 // This is necessary to free all proxy objects that have been
94 // closed by the test.
95 message_loop_
.RunAllPending();
98 void InitDispatcher(base::TimeDelta close_delay
) {
99 AudioParameters
params(AudioParameters::AUDIO_PCM_LINEAR
,
100 CHANNEL_LAYOUT_STEREO
, 44100, 16, 1024);
101 dispatcher_
= new AudioOutputDispatcher(&manager(), params
, close_delay
);
103 // Necessary to know how long the dispatcher will wait before posting
105 pause_delay_
= dispatcher_
->pause_delay_
;
108 MockAudioManager
& manager() {
112 MessageLoop message_loop_
;
113 scoped_refptr
<AudioOutputDispatcher
> dispatcher_
;
114 base::TimeDelta pause_delay_
;
115 MockAudioManager manager_
;
116 MockAudioSourceCallback callback_
;
119 TEST_F(AudioOutputProxyTest
, CreateAndClose
) {
120 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
124 TEST_F(AudioOutputProxyTest
, OpenAndClose
) {
125 MockAudioOutputStream stream
;
127 EXPECT_CALL(manager(), MakeAudioOutputStream(_
))
128 .WillOnce(Return(&stream
));
129 EXPECT_CALL(stream
, Open())
130 .WillOnce(Return(true));
131 EXPECT_CALL(stream
, Close())
134 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
135 EXPECT_TRUE(proxy
->Open());
139 // Create a stream, and verify that it is closed after kTestCloseDelayMs.
140 // if it doesn't start playing.
141 TEST_F(AudioOutputProxyTest
, CreateAndWait
) {
142 MockAudioOutputStream stream
;
144 EXPECT_CALL(manager(), MakeAudioOutputStream(_
))
145 .WillOnce(Return(&stream
));
146 EXPECT_CALL(stream
, Open())
147 .WillOnce(Return(true));
148 EXPECT_CALL(stream
, Close())
151 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
152 EXPECT_TRUE(proxy
->Open());
155 base::PlatformThread::Sleep(
156 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs
) * 2);
157 message_loop_
.RunAllPending();
159 // Verify expectation before calling Close().
160 Mock::VerifyAndClear(&stream
);
165 // Create a stream, and then calls Start() and Stop().
166 TEST_F(AudioOutputProxyTest
, StartAndStop
) {
167 MockAudioOutputStream stream
;
169 EXPECT_CALL(manager(), MakeAudioOutputStream(_
))
170 .WillOnce(Return(&stream
));
171 EXPECT_CALL(stream
, Open())
172 .WillOnce(Return(true));
173 EXPECT_CALL(stream
, Start(_
))
175 EXPECT_CALL(stream
, SetVolume(_
))
177 EXPECT_CALL(stream
, Stop())
179 EXPECT_CALL(stream
, Close())
182 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
183 EXPECT_TRUE(proxy
->Open());
185 proxy
->Start(&callback_
);
191 // Verify that the stream is closed after Stop is called.
192 TEST_F(AudioOutputProxyTest
, CloseAfterStop
) {
193 MockAudioOutputStream stream
;
195 EXPECT_CALL(manager(), MakeAudioOutputStream(_
))
196 .WillOnce(Return(&stream
));
197 EXPECT_CALL(stream
, Open())
198 .WillOnce(Return(true));
199 EXPECT_CALL(stream
, Start(_
))
201 EXPECT_CALL(stream
, SetVolume(_
))
203 EXPECT_CALL(stream
, Stop())
205 EXPECT_CALL(stream
, Close())
208 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
209 EXPECT_TRUE(proxy
->Open());
211 proxy
->Start(&callback_
);
214 // Wait for StreamStopped() to post StopStreamTask().
215 base::PlatformThread::Sleep(pause_delay_
* 2);
216 message_loop_
.RunAllPending();
218 // Wait for the close timer to fire.
219 base::PlatformThread::Sleep(
220 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs
) * 2);
221 message_loop_
.RunAllPending();
223 // Verify expectation before calling Close().
224 Mock::VerifyAndClear(&stream
);
229 // Create two streams, but don't start them. Only one device must be open.
230 TEST_F(AudioOutputProxyTest
, TwoStreams
) {
231 MockAudioOutputStream stream
;
233 EXPECT_CALL(manager(), MakeAudioOutputStream(_
))
234 .WillOnce(Return(&stream
));
235 EXPECT_CALL(stream
, Open())
236 .WillOnce(Return(true));
237 EXPECT_CALL(stream
, Close())
240 AudioOutputProxy
* proxy1
= new AudioOutputProxy(dispatcher_
);
241 AudioOutputProxy
* proxy2
= new AudioOutputProxy(dispatcher_
);
242 EXPECT_TRUE(proxy1
->Open());
243 EXPECT_TRUE(proxy2
->Open());
248 // Two streams: verify that second stream is allocated when the first
250 TEST_F(AudioOutputProxyTest
, TwoStreams_OnePlaying
) {
251 MockAudioOutputStream stream1
;
252 MockAudioOutputStream stream2
;
254 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds
));
256 EXPECT_CALL(manager(), MakeAudioOutputStream(_
))
257 .WillOnce(Return(&stream1
))
258 .WillOnce(Return(&stream2
));
260 EXPECT_CALL(stream1
, Open())
261 .WillOnce(Return(true));
262 EXPECT_CALL(stream1
, Start(_
))
264 EXPECT_CALL(stream1
, SetVolume(_
))
266 EXPECT_CALL(stream1
, Stop())
268 EXPECT_CALL(stream1
, Close())
271 EXPECT_CALL(stream2
, Open())
272 .WillOnce(Return(true));
273 EXPECT_CALL(stream2
, Close())
276 AudioOutputProxy
* proxy1
= new AudioOutputProxy(dispatcher_
);
277 AudioOutputProxy
* proxy2
= new AudioOutputProxy(dispatcher_
);
278 EXPECT_TRUE(proxy1
->Open());
279 EXPECT_TRUE(proxy2
->Open());
281 proxy1
->Start(&callback_
);
282 message_loop_
.RunAllPending();
289 // Two streams, both are playing. Dispatcher should not open a third stream.
290 TEST_F(AudioOutputProxyTest
, TwoStreams_BothPlaying
) {
291 MockAudioOutputStream stream1
;
292 MockAudioOutputStream stream2
;
294 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds
));
296 EXPECT_CALL(manager(), MakeAudioOutputStream(_
))
297 .WillOnce(Return(&stream1
))
298 .WillOnce(Return(&stream2
));
300 EXPECT_CALL(stream1
, Open())
301 .WillOnce(Return(true));
302 EXPECT_CALL(stream1
, Start(_
))
304 EXPECT_CALL(stream1
, SetVolume(_
))
306 EXPECT_CALL(stream1
, Stop())
308 EXPECT_CALL(stream1
, Close())
311 EXPECT_CALL(stream2
, Open())
312 .WillOnce(Return(true));
313 EXPECT_CALL(stream2
, Start(_
))
315 EXPECT_CALL(stream2
, SetVolume(_
))
317 EXPECT_CALL(stream2
, Stop())
319 EXPECT_CALL(stream2
, Close())
322 AudioOutputProxy
* proxy1
= new AudioOutputProxy(dispatcher_
);
323 AudioOutputProxy
* proxy2
= new AudioOutputProxy(dispatcher_
);
324 EXPECT_TRUE(proxy1
->Open());
325 EXPECT_TRUE(proxy2
->Open());
327 proxy1
->Start(&callback_
);
328 proxy2
->Start(&callback_
);
336 // Open() method failed.
337 TEST_F(AudioOutputProxyTest
, OpenFailed
) {
338 MockAudioOutputStream stream
;
340 EXPECT_CALL(manager(), MakeAudioOutputStream(_
))
341 .WillOnce(Return(&stream
));
342 EXPECT_CALL(stream
, Open())
343 .WillOnce(Return(false));
344 EXPECT_CALL(stream
, Close())
347 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
348 EXPECT_FALSE(proxy
->Open());
352 // Start() method failed.
353 TEST_F(AudioOutputProxyTest
, StartFailed
) {
354 MockAudioOutputStream stream
;
356 EXPECT_CALL(manager(), MakeAudioOutputStream(_
))
357 .WillOnce(Return(&stream
));
358 EXPECT_CALL(stream
, Open())
359 .WillOnce(Return(true));
360 EXPECT_CALL(stream
, Close())
363 AudioOutputProxy
* proxy
= new AudioOutputProxy(dispatcher_
);
364 EXPECT_TRUE(proxy
->Open());
367 base::PlatformThread::Sleep(
368 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs
) * 2);
369 message_loop_
.RunAllPending();
371 // Verify expectation before calling Close().
372 Mock::VerifyAndClear(&stream
);
374 // |stream| is closed at this point. Start() should reopen it again.
375 EXPECT_CALL(manager(), MakeAudioOutputStream(_
))
376 .WillOnce(Return(reinterpret_cast<AudioOutputStream
*>(NULL
)));
378 EXPECT_CALL(callback_
, OnError(_
, _
))
381 proxy
->Start(&callback_
);
383 Mock::VerifyAndClear(&callback_
);