OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <list> | 5 #include <list> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 } | 90 } |
91 | 91 |
92 private: | 92 private: |
93 base::WaitableEvent data_pulled_; | 93 base::WaitableEvent data_pulled_; |
94 | 94 |
95 DISALLOW_COPY_AND_ASSIGN(TestAudioSource); | 95 DISALLOW_COPY_AND_ASSIGN(TestAudioSource); |
96 }; | 96 }; |
97 | 97 |
98 } // namespace | 98 } // namespace |
99 | 99 |
100 class VirtualAudioInputStreamTest : public testing::Test { | 100 class VirtualAudioInputStreamTest : public testing::TestWithParam<bool> { |
101 public: | 101 public: |
102 VirtualAudioInputStreamTest() | 102 VirtualAudioInputStreamTest() |
103 : audio_thread_(new base::Thread("AudioThread")), | 103 : audio_thread_(new base::Thread("AudioThread")), |
| 104 worker_thread_(new base::Thread("AudioWorkerThread")), |
104 stream_(NULL), | 105 stream_(NULL), |
105 closed_stream_(false, false) { | 106 closed_stream_(false, false) { |
106 audio_thread_->Start(); | 107 audio_thread_->Start(); |
107 audio_message_loop_ = audio_thread_->message_loop_proxy(); | 108 audio_message_loop_ = audio_thread_->message_loop_proxy(); |
108 } | 109 } |
109 | 110 |
110 virtual ~VirtualAudioInputStreamTest() { | 111 virtual ~VirtualAudioInputStreamTest() { |
111 SyncWithAudioThread(); | 112 SyncWithAudioThread(); |
112 | 113 |
113 DCHECK(output_streams_.empty()); | 114 DCHECK(output_streams_.empty()); |
114 DCHECK(stopped_output_streams_.empty()); | 115 DCHECK(stopped_output_streams_.empty()); |
115 } | 116 } |
116 | 117 |
117 void Create() { | 118 void Create() { |
| 119 const bool worker_is_separate_thread = GetParam(); |
118 stream_ = new VirtualAudioInputStream( | 120 stream_ = new VirtualAudioInputStream( |
119 kParams, audio_message_loop_, | 121 kParams, GetWorkerLoop(worker_is_separate_thread), |
120 base::Bind(&base::DeletePointer<VirtualAudioInputStream>)); | 122 base::Bind(&base::DeletePointer<VirtualAudioInputStream>)); |
121 stream_->Open(); | 123 stream_->Open(); |
122 } | 124 } |
123 | 125 |
124 void Start() { | 126 void Start() { |
125 EXPECT_CALL(input_callback_, OnClose(_)); | 127 EXPECT_CALL(input_callback_, OnClose(_)); |
126 EXPECT_CALL(input_callback_, OnData(_, NotNull(), _, _, _)) | 128 EXPECT_CALL(input_callback_, OnData(_, NotNull(), _, _, _)) |
127 .Times(AtLeast(1)); | 129 .Times(AtLeast(1)); |
128 | 130 |
129 ASSERT_TRUE(!!stream_); | 131 ASSERT_TRUE(!!stream_); |
130 stream_->Start(&input_callback_); | 132 stream_->Start(&input_callback_); |
131 } | 133 } |
132 | 134 |
133 void CreateAndStartOneOutputStream() { | 135 void CreateAndStartOneOutputStream() { |
134 ASSERT_TRUE(!!stream_); | 136 ASSERT_TRUE(!!stream_); |
135 AudioOutputStream* const output_stream = new VirtualAudioOutputStream( | 137 AudioOutputStream* const output_stream = new VirtualAudioOutputStream( |
136 kParams, | 138 kParams, |
137 audio_message_loop_.get(), | |
138 stream_, | 139 stream_, |
139 base::Bind(&base::DeletePointer<VirtualAudioOutputStream>)); | 140 base::Bind(&base::DeletePointer<VirtualAudioOutputStream>)); |
140 output_streams_.push_back(output_stream); | 141 output_streams_.push_back(output_stream); |
141 | 142 |
142 output_stream->Open(); | 143 output_stream->Open(); |
143 output_stream->Start(&source_); | 144 output_stream->Start(&source_); |
144 } | 145 } |
145 | 146 |
146 void Stop() { | 147 void Stop() { |
147 ASSERT_TRUE(!!stream_); | 148 ASSERT_TRUE(!!stream_); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 (*it)->Start(&source_); | 206 (*it)->Start(&source_); |
206 output_streams_.push_back(*it); | 207 output_streams_.push_back(*it); |
207 } | 208 } |
208 stopped_output_streams_.clear(); | 209 stopped_output_streams_.clear(); |
209 } | 210 } |
210 | 211 |
211 const scoped_refptr<base::MessageLoopProxy>& audio_message_loop() const { | 212 const scoped_refptr<base::MessageLoopProxy>& audio_message_loop() const { |
212 return audio_message_loop_; | 213 return audio_message_loop_; |
213 } | 214 } |
214 | 215 |
| 216 const scoped_refptr<base::MessageLoopProxy>& GetWorkerLoop( |
| 217 bool worker_is_separate_thread) { |
| 218 if (worker_is_separate_thread) { |
| 219 if (!worker_thread_->IsRunning()) { |
| 220 worker_thread_->Start(); |
| 221 worker_message_loop_ = worker_thread_->message_loop_proxy(); |
| 222 } |
| 223 return worker_message_loop_; |
| 224 } else { |
| 225 return audio_message_loop_; |
| 226 } |
| 227 } |
| 228 |
215 private: | 229 private: |
216 void SyncWithAudioThread() { | 230 void SyncWithAudioThread() { |
217 base::WaitableEvent done(false, false); | 231 base::WaitableEvent done(false, false); |
218 audio_message_loop_->PostTask( | 232 audio_message_loop_->PostTask( |
219 FROM_HERE, | 233 FROM_HERE, |
220 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done))); | 234 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done))); |
221 done.Wait(); | 235 done.Wait(); |
222 } | 236 } |
223 | 237 |
224 scoped_ptr<base::Thread> audio_thread_; | 238 scoped_ptr<base::Thread> audio_thread_; |
225 scoped_refptr<base::MessageLoopProxy> audio_message_loop_; | 239 scoped_refptr<base::MessageLoopProxy> audio_message_loop_; |
| 240 scoped_ptr<base::Thread> worker_thread_; |
| 241 scoped_refptr<base::MessageLoopProxy> worker_message_loop_; |
226 | 242 |
227 VirtualAudioInputStream* stream_; | 243 VirtualAudioInputStream* stream_; |
228 MockInputCallback input_callback_; | 244 MockInputCallback input_callback_; |
229 base::WaitableEvent closed_stream_; | 245 base::WaitableEvent closed_stream_; |
230 | 246 |
231 std::list<AudioOutputStream*> output_streams_; | 247 std::list<AudioOutputStream*> output_streams_; |
232 std::list<AudioOutputStream*> stopped_output_streams_; | 248 std::list<AudioOutputStream*> stopped_output_streams_; |
233 TestAudioSource source_; | 249 TestAudioSource source_; |
234 | 250 |
235 DISALLOW_COPY_AND_ASSIGN(VirtualAudioInputStreamTest); | 251 DISALLOW_COPY_AND_ASSIGN(VirtualAudioInputStreamTest); |
236 }; | 252 }; |
237 | 253 |
238 #define RUN_ON_AUDIO_THREAD(method) \ | 254 #define RUN_ON_AUDIO_THREAD(method) \ |
239 audio_message_loop()->PostTask( \ | 255 audio_message_loop()->PostTask( \ |
240 FROM_HERE, base::Bind(&VirtualAudioInputStreamTest::method, \ | 256 FROM_HERE, base::Bind(&VirtualAudioInputStreamTest::method, \ |
241 base::Unretained(this))) | 257 base::Unretained(this))) |
242 | 258 |
243 TEST_F(VirtualAudioInputStreamTest, CreateAndClose) { | 259 TEST_P(VirtualAudioInputStreamTest, CreateAndClose) { |
244 RUN_ON_AUDIO_THREAD(Create); | 260 RUN_ON_AUDIO_THREAD(Create); |
245 RUN_ON_AUDIO_THREAD(Close); | 261 RUN_ON_AUDIO_THREAD(Close); |
246 WaitUntilClosed(); | 262 WaitUntilClosed(); |
247 } | 263 } |
248 | 264 |
249 TEST_F(VirtualAudioInputStreamTest, NoOutputs) { | 265 TEST_P(VirtualAudioInputStreamTest, NoOutputs) { |
250 RUN_ON_AUDIO_THREAD(Create); | 266 RUN_ON_AUDIO_THREAD(Create); |
251 RUN_ON_AUDIO_THREAD(Start); | 267 RUN_ON_AUDIO_THREAD(Start); |
252 WaitForDataToFlow(); | 268 WaitForDataToFlow(); |
253 RUN_ON_AUDIO_THREAD(Stop); | 269 RUN_ON_AUDIO_THREAD(Stop); |
254 RUN_ON_AUDIO_THREAD(Close); | 270 RUN_ON_AUDIO_THREAD(Close); |
255 WaitUntilClosed(); | 271 WaitUntilClosed(); |
256 } | 272 } |
257 | 273 |
258 TEST_F(VirtualAudioInputStreamTest, SingleOutput) { | 274 TEST_P(VirtualAudioInputStreamTest, SingleOutput) { |
259 RUN_ON_AUDIO_THREAD(Create); | 275 RUN_ON_AUDIO_THREAD(Create); |
260 RUN_ON_AUDIO_THREAD(Start); | 276 RUN_ON_AUDIO_THREAD(Start); |
261 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 277 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |
262 WaitForDataToFlow(); | 278 WaitForDataToFlow(); |
263 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 279 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |
264 RUN_ON_AUDIO_THREAD(Stop); | 280 RUN_ON_AUDIO_THREAD(Stop); |
265 RUN_ON_AUDIO_THREAD(Close); | 281 RUN_ON_AUDIO_THREAD(Close); |
266 WaitUntilClosed(); | 282 WaitUntilClosed(); |
267 } | 283 } |
268 | 284 |
269 TEST_F(VirtualAudioInputStreamTest, SingleOutputPausedAndRestarted) { | 285 TEST_P(VirtualAudioInputStreamTest, SingleOutputPausedAndRestarted) { |
270 RUN_ON_AUDIO_THREAD(Create); | 286 RUN_ON_AUDIO_THREAD(Create); |
271 RUN_ON_AUDIO_THREAD(Start); | 287 RUN_ON_AUDIO_THREAD(Start); |
272 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 288 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |
273 WaitForDataToFlow(); | 289 WaitForDataToFlow(); |
274 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); | 290 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); |
275 RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams); | 291 RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams); |
276 WaitForDataToFlow(); | 292 WaitForDataToFlow(); |
277 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 293 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |
278 RUN_ON_AUDIO_THREAD(Stop); | 294 RUN_ON_AUDIO_THREAD(Stop); |
279 RUN_ON_AUDIO_THREAD(Close); | 295 RUN_ON_AUDIO_THREAD(Close); |
280 WaitUntilClosed(); | 296 WaitUntilClosed(); |
281 } | 297 } |
282 | 298 |
283 TEST_F(VirtualAudioInputStreamTest, MultipleOutputs) { | 299 TEST_P(VirtualAudioInputStreamTest, MultipleOutputs) { |
284 RUN_ON_AUDIO_THREAD(Create); | 300 RUN_ON_AUDIO_THREAD(Create); |
285 RUN_ON_AUDIO_THREAD(Start); | 301 RUN_ON_AUDIO_THREAD(Start); |
286 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 302 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |
287 WaitForDataToFlow(); | 303 WaitForDataToFlow(); |
288 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 304 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |
289 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 305 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |
290 WaitForDataToFlow(); | 306 WaitForDataToFlow(); |
291 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); | 307 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); |
292 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); | 308 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); |
293 WaitForDataToFlow(); | 309 WaitForDataToFlow(); |
294 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); | 310 RUN_ON_AUDIO_THREAD(StopFirstOutputStream); |
295 RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams); | 311 RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams); |
296 WaitForDataToFlow(); | 312 WaitForDataToFlow(); |
297 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 313 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |
298 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 314 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |
299 RUN_ON_AUDIO_THREAD(Stop); | 315 RUN_ON_AUDIO_THREAD(Stop); |
300 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 316 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |
301 RUN_ON_AUDIO_THREAD(Close); | 317 RUN_ON_AUDIO_THREAD(Close); |
302 WaitUntilClosed(); | 318 WaitUntilClosed(); |
303 } | 319 } |
304 | 320 |
305 // A combination of all of the above tests with many output streams. | 321 // A combination of all of the above tests with many output streams. |
306 TEST_F(VirtualAudioInputStreamTest, ComprehensiveTest) { | 322 TEST_P(VirtualAudioInputStreamTest, ComprehensiveTest) { |
307 static const int kNumOutputs = 8; | 323 static const int kNumOutputs = 8; |
308 static const int kHalfNumOutputs = kNumOutputs / 2; | 324 static const int kHalfNumOutputs = kNumOutputs / 2; |
309 static const int kPauseIterations = 5; | 325 static const int kPauseIterations = 5; |
310 | 326 |
311 RUN_ON_AUDIO_THREAD(Create); | 327 RUN_ON_AUDIO_THREAD(Create); |
312 for (int i = 0; i < kHalfNumOutputs; ++i) { | 328 for (int i = 0; i < kHalfNumOutputs; ++i) { |
313 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); | 329 RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream); |
314 } | 330 } |
315 RUN_ON_AUDIO_THREAD(Start); | 331 RUN_ON_AUDIO_THREAD(Start); |
316 WaitForDataToFlow(); | 332 WaitForDataToFlow(); |
(...skipping 11 matching lines...) Expand all Loading... |
328 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 344 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |
329 } | 345 } |
330 RUN_ON_AUDIO_THREAD(Stop); | 346 RUN_ON_AUDIO_THREAD(Stop); |
331 for (int i = 0; i < kHalfNumOutputs; ++i) { | 347 for (int i = 0; i < kHalfNumOutputs; ++i) { |
332 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); | 348 RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream); |
333 } | 349 } |
334 RUN_ON_AUDIO_THREAD(Close); | 350 RUN_ON_AUDIO_THREAD(Close); |
335 WaitUntilClosed(); | 351 WaitUntilClosed(); |
336 } | 352 } |
337 | 353 |
| 354 INSTANTIATE_TEST_CASE_P(SingleVersusMultithreaded, |
| 355 VirtualAudioInputStreamTest, |
| 356 ::testing::Values(false, true)); |
| 357 |
338 } // namespace media | 358 } // namespace media |
OLD | NEW |