OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2010 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. | |
4 | |
5 #include "base/message_loop.h" | |
6 #include "base/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" | |
12 | |
13 using ::testing::_; | |
14 using ::testing::Mock; | |
15 using ::testing::Return; | |
16 | |
17 namespace { | |
18 const int kTestCloseDelayMs = 100; | |
19 | |
20 // Used in the test where we don't want a stream to be closed unexpectedly. | |
21 const int kTestBigCloseDelayMs = 100 * 1000; | |
22 } // namespace | |
23 | |
24 class MockAudioOutputStream : public AudioOutputStream { | |
25 public: | |
26 MockAudioOutputStream() {} | |
27 | |
28 MOCK_METHOD0(Open, bool()); | |
29 MOCK_METHOD1(Start, void(AudioSourceCallback* callback)); | |
30 MOCK_METHOD0(Stop, void()); | |
31 MOCK_METHOD1(SetVolume, void(double volume)); | |
32 MOCK_METHOD1(GetVolume, void(double* volume)); | |
33 MOCK_METHOD0(Close, void()); | |
34 }; | |
35 | |
36 class MockAudioManager : public AudioManager { | |
37 public: | |
38 MockAudioManager() { }; | |
39 | |
40 MOCK_METHOD0(Init, void()); | |
41 MOCK_METHOD0(HasAudioOutputDevices, bool()); | |
42 MOCK_METHOD0(HasAudioInputDevices, bool()); | |
43 MOCK_METHOD1(MakeAudioOutputStream, AudioOutputStream*( | |
44 AudioParameters params)); | |
45 MOCK_METHOD1(MakeAudioInputStream, AudioInputStream*( | |
46 AudioParameters params)); | |
47 MOCK_METHOD0(MuteAll, void()); | |
48 MOCK_METHOD0(UnMuteAll, void()); | |
49 MOCK_METHOD1(MakeAudioOutputStreamProxy, AudioOutputStream*( | |
50 AudioParameters params)); | |
51 MOCK_METHOD0(GetMessageLoop, MessageLoop*()); | |
52 }; | |
53 | |
54 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { | |
55 public: | |
56 MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream, | |
57 uint8* dest, uint32 max_size, | |
58 AudioBuffersState buffers_state)); | |
59 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); | |
60 }; | |
61 | |
62 class AudioOutputProxyTest : public testing::Test { | |
63 protected: | |
64 virtual void SetUp() { | |
65 EXPECT_CALL(manager_, GetMessageLoop()) | |
66 .WillRepeatedly(Return(&message_loop_)); | |
67 AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, 2, 44100, | |
68 16, 1024); | |
69 dispatcher_ = new AudioOutputDispatcher(&manager_, params); | |
70 dispatcher_->set_close_delay( | |
71 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs)); | |
72 } | |
73 | |
74 virtual void TearDown() { | |
75 // All paused proxies should have been destroyed at this point. | |
76 EXPECT_EQ(0, dispatcher_->paused_proxies_); | |
77 } | |
78 | |
79 MessageLoop message_loop_; | |
80 scoped_refptr<AudioOutputDispatcher> dispatcher_; | |
81 MockAudioManager manager_; | |
82 MockAudioSourceCallback callback_; | |
83 }; | |
84 | |
85 TEST_F(AudioOutputProxyTest, CreateAndClose) { | |
86 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
87 proxy->Close(); | |
88 } | |
89 | |
90 TEST_F(AudioOutputProxyTest, OpenAndClose) { | |
91 MockAudioOutputStream stream; | |
92 | |
93 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
94 .WillOnce(Return(&stream)); | |
95 EXPECT_CALL(stream, Open()) | |
96 .WillOnce(Return(true)); | |
97 EXPECT_CALL(stream, Close()) | |
98 .Times(1); | |
99 | |
100 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
101 EXPECT_TRUE(proxy->Open()); | |
102 proxy->Close(); | |
103 } | |
104 | |
105 // Create a stream, and verify that it is closed after kTestCloseDelayMs. | |
106 // if it doesn't start playing. | |
107 TEST_F(AudioOutputProxyTest, CreateAndWait) { | |
108 MockAudioOutputStream stream; | |
109 | |
110 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
111 .WillOnce(Return(&stream)); | |
112 EXPECT_CALL(stream, Open()) | |
113 .WillOnce(Return(true)); | |
114 EXPECT_CALL(stream, Close()) | |
115 .Times(1); | |
116 | |
117 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
118 EXPECT_TRUE(proxy->Open()); | |
119 | |
120 // Wait until it is closed. | |
121 PlatformThread::Sleep(kTestCloseDelayMs); | |
Paweł Hajdan Jr.
2010/11/18 10:28:43
1. Why is this a Sleep and not a real wait?
2. If
Sergey Ulanov
2010/11/19 00:56:36
Not sure what you mean by "real wait" Are you sugg
| |
122 message_loop_.RunAllPending(); | |
123 | |
124 // Verify expectation before calling Close(). | |
125 Mock::VerifyAndClear(&stream); | |
126 | |
127 proxy->Close(); | |
128 } | |
129 | |
130 // Create a stream, and then calls Start() and Stop(). | |
131 TEST_F(AudioOutputProxyTest, StartAndStop) { | |
132 MockAudioOutputStream stream; | |
133 | |
134 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
135 .WillOnce(Return(&stream)); | |
136 EXPECT_CALL(stream, Open()) | |
137 .WillOnce(Return(true)); | |
138 EXPECT_CALL(stream, Start(_)) | |
139 .Times(1); | |
140 EXPECT_CALL(stream, SetVolume(_)) | |
141 .Times(1); | |
142 EXPECT_CALL(stream, Stop()) | |
143 .Times(1); | |
144 EXPECT_CALL(stream, Close()) | |
145 .Times(1); | |
146 | |
147 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
148 EXPECT_TRUE(proxy->Open()); | |
149 | |
150 proxy->Start(&callback_); | |
151 proxy->Stop(); | |
152 | |
153 proxy->Close(); | |
154 } | |
155 | |
156 // Verify that the stream is closed after Stop is called. | |
157 TEST_F(AudioOutputProxyTest, CloseAfterStop) { | |
158 MockAudioOutputStream stream; | |
159 | |
160 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
161 .WillOnce(Return(&stream)); | |
162 EXPECT_CALL(stream, Open()) | |
163 .WillOnce(Return(true)); | |
164 EXPECT_CALL(stream, Start(_)) | |
165 .Times(1); | |
166 EXPECT_CALL(stream, SetVolume(_)) | |
167 .Times(1); | |
168 EXPECT_CALL(stream, Stop()) | |
169 .Times(1); | |
170 EXPECT_CALL(stream, Close()) | |
171 .Times(1); | |
172 | |
173 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
174 EXPECT_TRUE(proxy->Open()); | |
175 | |
176 proxy->Start(&callback_); | |
177 proxy->Stop(); | |
178 | |
179 // Wait until it is closed. | |
180 PlatformThread::Sleep(kTestCloseDelayMs); | |
181 message_loop_.RunAllPending(); | |
182 | |
183 // Verify expectation before calling Close(). | |
184 Mock::VerifyAndClear(&stream); | |
185 | |
186 proxy->Close(); | |
187 } | |
188 | |
189 // Create two streams, but don't start them. Only one device must be open. | |
190 TEST_F(AudioOutputProxyTest, TwoStreams) { | |
191 MockAudioOutputStream stream; | |
192 | |
193 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
194 .WillOnce(Return(&stream)); | |
195 EXPECT_CALL(stream, Open()) | |
196 .WillOnce(Return(true)); | |
197 EXPECT_CALL(stream, Close()) | |
198 .Times(1); | |
199 | |
200 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_); | |
201 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_); | |
202 EXPECT_TRUE(proxy1->Open()); | |
203 EXPECT_TRUE(proxy2->Open()); | |
204 proxy1->Close(); | |
205 proxy2->Close(); | |
206 } | |
207 | |
208 // Two streams: verify that second stream is allocated when the first | |
209 // starts playing. | |
210 TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) { | |
211 MockAudioOutputStream stream1; | |
212 MockAudioOutputStream stream2; | |
213 | |
214 dispatcher_->set_close_delay( | |
215 base::TimeDelta::FromMilliseconds(kTestBigCloseDelayMs)); | |
216 | |
217 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
218 .WillOnce(Return(&stream1)) | |
219 .WillOnce(Return(&stream2)); | |
220 | |
221 EXPECT_CALL(stream1, Open()) | |
222 .WillOnce(Return(true)); | |
223 EXPECT_CALL(stream1, Start(_)) | |
224 .Times(1); | |
225 EXPECT_CALL(stream1, SetVolume(_)) | |
226 .Times(1); | |
227 EXPECT_CALL(stream1, Stop()) | |
228 .Times(1); | |
229 EXPECT_CALL(stream1, Close()) | |
230 .Times(1); | |
231 | |
232 EXPECT_CALL(stream2, Open()) | |
233 .WillOnce(Return(true)); | |
234 EXPECT_CALL(stream2, Close()) | |
235 .Times(1); | |
236 | |
237 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_); | |
238 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_); | |
239 EXPECT_TRUE(proxy1->Open()); | |
240 EXPECT_TRUE(proxy2->Open()); | |
241 | |
242 proxy1->Start(&callback_); | |
243 message_loop_.RunAllPending(); | |
244 proxy1->Stop(); | |
245 | |
246 proxy1->Close(); | |
247 proxy2->Close(); | |
248 } | |
249 | |
250 // Two streams, both are playing. Dispatcher should not open a third stream. | |
251 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) { | |
252 MockAudioOutputStream stream1; | |
253 MockAudioOutputStream stream2; | |
254 | |
255 dispatcher_->set_close_delay( | |
256 base::TimeDelta::FromMilliseconds(kTestBigCloseDelayMs)); | |
257 | |
258 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
259 .WillOnce(Return(&stream1)) | |
260 .WillOnce(Return(&stream2)); | |
261 | |
262 EXPECT_CALL(stream1, Open()) | |
263 .WillOnce(Return(true)); | |
264 EXPECT_CALL(stream1, Start(_)) | |
265 .Times(1); | |
266 EXPECT_CALL(stream1, SetVolume(_)) | |
267 .Times(1); | |
268 EXPECT_CALL(stream1, Stop()) | |
269 .Times(1); | |
270 EXPECT_CALL(stream1, Close()) | |
271 .Times(1); | |
272 | |
273 EXPECT_CALL(stream2, Open()) | |
274 .WillOnce(Return(true)); | |
275 EXPECT_CALL(stream2, Start(_)) | |
276 .Times(1); | |
277 EXPECT_CALL(stream2, SetVolume(_)) | |
278 .Times(1); | |
279 EXPECT_CALL(stream2, Stop()) | |
280 .Times(1); | |
281 EXPECT_CALL(stream2, Close()) | |
282 .Times(1); | |
283 | |
284 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_); | |
285 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_); | |
286 EXPECT_TRUE(proxy1->Open()); | |
287 EXPECT_TRUE(proxy2->Open()); | |
288 | |
289 proxy1->Start(&callback_); | |
290 proxy2->Start(&callback_); | |
291 proxy1->Stop(); | |
292 proxy2->Stop(); | |
293 | |
294 proxy1->Close(); | |
295 proxy2->Close(); | |
296 } | |
297 | |
298 // Open() method failed. | |
299 TEST_F(AudioOutputProxyTest, OpenFailed) { | |
300 MockAudioOutputStream stream; | |
301 | |
302 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
303 .WillOnce(Return(&stream)); | |
304 EXPECT_CALL(stream, Open()) | |
305 .WillOnce(Return(false)); | |
306 EXPECT_CALL(stream, Close()) | |
307 .Times(1); | |
308 | |
309 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
310 EXPECT_FALSE(proxy->Open()); | |
311 proxy->Close(); | |
312 } | |
313 | |
314 // Start() method failed. | |
315 TEST_F(AudioOutputProxyTest, StartFailed) { | |
316 MockAudioOutputStream stream; | |
317 | |
318 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
319 .WillOnce(Return(&stream)); | |
320 EXPECT_CALL(stream, Open()) | |
321 .WillOnce(Return(true)); | |
322 EXPECT_CALL(stream, Close()) | |
323 .Times(1); | |
324 | |
325 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); | |
326 EXPECT_TRUE(proxy->Open()); | |
327 | |
328 // Wait until it is closed. | |
329 PlatformThread::Sleep(kTestCloseDelayMs); | |
330 message_loop_.RunAllPending(); | |
331 | |
332 // Verify expectation before calling Close(). | |
333 Mock::VerifyAndClear(&stream); | |
334 | |
335 // |stream| is closed at this point. Start() should reopen it again. | |
336 EXPECT_CALL(manager_, MakeAudioOutputStream(_)) | |
337 .WillOnce(Return(reinterpret_cast<AudioOutputStream*>(NULL))); | |
338 | |
339 EXPECT_CALL(callback_, OnError(_, _)) | |
340 .Times(1); | |
341 | |
342 proxy->Start(&callback_); | |
343 | |
344 Mock::VerifyAndClear(&callback_); | |
345 | |
346 proxy->Close(); | |
347 } | |
OLD | NEW |