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 <map> | 5 #include <map> |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/process_util.h" | 12 #include "base/process_util.h" |
| 13 #include "base/run_loop.h" |
13 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
15 #include "content/browser/browser_thread_impl.h" | 16 #include "content/browser/browser_thread_impl.h" |
16 #include "content/browser/renderer_host/media/media_stream_manager.h" | 17 #include "content/browser/renderer_host/media/media_stream_manager.h" |
17 #include "content/browser/renderer_host/media/video_capture_host.h" | 18 #include "content/browser/renderer_host/media/video_capture_host.h" |
18 #include "content/browser/renderer_host/media/video_capture_manager.h" | 19 #include "content/browser/renderer_host/media/video_capture_manager.h" |
19 #include "content/common/media/video_capture_messages.h" | 20 #include "content/common/media/video_capture_messages.h" |
20 #include "content/public/test/mock_resource_context.h" | 21 #include "content/public/test/mock_resource_context.h" |
| 22 #include "content/public/test/test_browser_thread_bundle.h" |
21 #include "media/audio/audio_manager.h" | 23 #include "media/audio/audio_manager.h" |
22 #include "media/video/capture/video_capture_types.h" | 24 #include "media/video/capture/video_capture_types.h" |
23 #include "net/url_request/url_request_context.h" | 25 #include "net/url_request/url_request_context.h" |
24 #include "testing/gmock/include/gmock/gmock.h" | 26 #include "testing/gmock/include/gmock/gmock.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
26 | 28 |
27 using ::testing::_; | 29 using ::testing::_; |
28 using ::testing::AtLeast; | 30 using ::testing::AtLeast; |
29 using ::testing::AnyNumber; | 31 using ::testing::AnyNumber; |
30 using ::testing::DoAll; | 32 using ::testing::DoAll; |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 } | 179 } |
178 OnDeviceInfo(device_id); | 180 OnDeviceInfo(device_id); |
179 } | 181 } |
180 | 182 |
181 std::map<int, base::SharedMemory*> filled_dib_; | 183 std::map<int, base::SharedMemory*> filled_dib_; |
182 bool return_buffers_; | 184 bool return_buffers_; |
183 bool dump_video_; | 185 bool dump_video_; |
184 DumpVideo dumper_; | 186 DumpVideo dumper_; |
185 }; | 187 }; |
186 | 188 |
187 ACTION_P(ExitMessageLoop, message_loop) { | 189 ACTION_P2(ExitMessageLoop, message_loop, quit_closure) { |
188 message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); | 190 message_loop->PostTask(FROM_HERE, quit_closure); |
189 } | 191 } |
190 | 192 |
191 class VideoCaptureHostTest : public testing::Test { | 193 class VideoCaptureHostTest : public testing::Test { |
192 public: | 194 public: |
193 VideoCaptureHostTest() {} | 195 VideoCaptureHostTest() |
194 | 196 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), |
195 protected: | 197 message_loop_(base::MessageLoopProxy::current()) { |
196 virtual void SetUp() OVERRIDE { | |
197 // Create a message loop so VideoCaptureHostTest can use it. | |
198 message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO)); | |
199 | |
200 // MediaStreamManager must be created on the IO thread. | |
201 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO, | |
202 message_loop_.get())); | |
203 | |
204 // Create our own MediaStreamManager. | 198 // Create our own MediaStreamManager. |
205 audio_manager_.reset(media::AudioManager::Create()); | 199 audio_manager_.reset(media::AudioManager::Create()); |
206 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); | 200 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); |
207 #ifndef TEST_REAL_CAPTURE_DEVICE | 201 #ifndef TEST_REAL_CAPTURE_DEVICE |
208 media_stream_manager_->UseFakeDevice(); | 202 media_stream_manager_->UseFakeDevice(); |
209 #endif | 203 #endif |
210 | 204 |
211 host_ = new MockVideoCaptureHost(media_stream_manager_.get()); | 205 host_ = new MockVideoCaptureHost(media_stream_manager_.get()); |
212 | 206 |
213 // Simulate IPC channel connected. | 207 // Simulate IPC channel connected. |
214 host_->OnChannelConnected(base::GetCurrentProcId()); | 208 host_->OnChannelConnected(base::GetCurrentProcId()); |
215 } | 209 } |
216 | 210 |
217 virtual void TearDown() OVERRIDE { | 211 virtual ~VideoCaptureHostTest() { |
218 // Verifies and removes the expectations on host_ and | 212 // Verifies and removes the expectations on host_ and |
219 // returns true iff successful. | 213 // returns true iff successful. |
220 Mock::VerifyAndClearExpectations(host_.get()); | 214 Mock::VerifyAndClearExpectations(host_.get()); |
221 | 215 |
222 EXPECT_CALL(*host_.get(), | 216 EXPECT_CALL(*host_.get(), |
223 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) | 217 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) |
224 .Times(AnyNumber()); | 218 .Times(AnyNumber()); |
225 | 219 |
226 // Simulate closing the IPC channel. | 220 // Simulate closing the IPC channel. |
227 host_->OnChannelClosing(); | 221 host_->OnChannelClosing(); |
228 | 222 |
229 // Release the reference to the mock object. The object will be destructed | 223 // Release the reference to the mock object. The object will be destructed |
230 // on message_loop_. | 224 // on the current message loop. |
231 host_ = NULL; | 225 host_ = NULL; |
232 | |
233 // We need to continue running message_loop_ to complete all destructions. | |
234 message_loop_->RunUntilIdle(); | |
235 | |
236 // Delete the IO message loop. This will cause the MediaStreamManager to be | |
237 // notified so it will stop its device thread and device managers. | |
238 message_loop_.reset(); | |
239 } | 226 } |
240 | 227 |
| 228 protected: |
241 void StartCapture() { | 229 void StartCapture() { |
242 InSequence s; | 230 InSequence s; |
243 // 1. First - get info about the new resolution | 231 // 1. First - get info about the new resolution |
244 EXPECT_CALL(*host_.get(), OnDeviceInfo(kDeviceId)); | 232 EXPECT_CALL(*host_.get(), OnDeviceInfo(kDeviceId)); |
245 | 233 |
246 // 2. Change state to started | 234 // 2. Change state to started |
247 EXPECT_CALL(*host_.get(), | 235 EXPECT_CALL(*host_.get(), |
248 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); | 236 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); |
249 | 237 |
250 // 3. Newly created buffers will arrive. | 238 // 3. Newly created buffers will arrive. |
251 EXPECT_CALL(*host_.get(), OnNewBufferCreated(kDeviceId, _, _, _)) | 239 EXPECT_CALL(*host_.get(), OnNewBufferCreated(kDeviceId, _, _, _)) |
252 .Times(AnyNumber()).WillRepeatedly(Return()); | 240 .Times(AnyNumber()).WillRepeatedly(Return()); |
253 | 241 |
254 // 4. First filled buffer will arrive. | 242 // 4. First filled buffer will arrive. |
| 243 base::RunLoop run_loop; |
255 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId, _, _)) | 244 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId, _, _)) |
256 .Times(AnyNumber()).WillOnce(ExitMessageLoop(message_loop_.get())); | 245 .Times(AnyNumber()).WillOnce(ExitMessageLoop( |
| 246 message_loop_, run_loop.QuitClosure())); |
257 | 247 |
258 media::VideoCaptureParams params; | 248 media::VideoCaptureParams params; |
259 params.width = 352; | 249 params.width = 352; |
260 params.height = 288; | 250 params.height = 288; |
261 params.frame_per_second = 30; | 251 params.frame_per_second = 30; |
262 params.session_id = kTestFakeDeviceId; | 252 params.session_id = kTestFakeDeviceId; |
263 host_->OnStartCapture(kDeviceId, params); | 253 host_->OnStartCapture(kDeviceId, params); |
264 message_loop_->Run(); | 254 run_loop.Run(); |
265 } | 255 } |
266 | 256 |
267 #ifdef DUMP_VIDEO | 257 #ifdef DUMP_VIDEO |
268 void CaptureAndDumpVideo(int width, int heigt, int frame_rate) { | 258 void CaptureAndDumpVideo(int width, int heigt, int frame_rate) { |
269 InSequence s; | 259 InSequence s; |
270 // 1. First - get info about the new resolution | 260 // 1. First - get info about the new resolution |
271 EXPECT_CALL(*host_, OnDeviceInfo(kDeviceId)); | 261 EXPECT_CALL(*host_, OnDeviceInfo(kDeviceId)); |
272 | 262 |
273 // 2. Change state to started | 263 // 2. Change state to started |
274 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); | 264 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); |
275 | 265 |
276 // 3. First filled buffer will arrive. | 266 // 3. First filled buffer will arrive. |
| 267 base::RunLoop run_loop; |
277 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _)) | 268 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _)) |
278 .Times(AnyNumber()) | 269 .Times(AnyNumber()) |
279 .WillOnce(ExitMessageLoop(message_loop_.get())); | 270 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); |
280 | 271 |
281 media::VideoCaptureParams params; | 272 media::VideoCaptureParams params; |
282 params.width = width; | 273 params.width = width; |
283 params.height = heigt; | 274 params.height = heigt; |
284 params.frame_per_second = frame_rate; | 275 params.frame_per_second = frame_rate; |
285 params.session_id = kTestFakeDeviceId; | 276 params.session_id = kTestFakeDeviceId; |
286 host_->SetDumpVideo(true); | 277 host_->SetDumpVideo(true); |
287 host_->OnStartCapture(kDeviceId, params); | 278 host_->OnStartCapture(kDeviceId, params); |
288 message_loop_->Run(); | 279 run_loop.Run(); |
289 } | 280 } |
290 #endif | 281 #endif |
291 | 282 |
292 void StopCapture() { | 283 void StopCapture() { |
| 284 base::RunLoop run_loop; |
293 EXPECT_CALL(*host_.get(), | 285 EXPECT_CALL(*host_.get(), |
294 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) | 286 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) |
295 .WillOnce(ExitMessageLoop(message_loop_.get())); | 287 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); |
296 | 288 |
297 host_->OnStopCapture(kDeviceId); | 289 host_->OnStopCapture(kDeviceId); |
298 host_->SetReturnReceviedDibs(true); | 290 host_->SetReturnReceviedDibs(true); |
299 host_->ReturnReceivedDibs(kDeviceId); | 291 host_->ReturnReceivedDibs(kDeviceId); |
300 | 292 |
301 message_loop_->Run(); | 293 run_loop.Run(); |
302 | 294 |
303 host_->SetReturnReceviedDibs(false); | 295 host_->SetReturnReceviedDibs(false); |
304 // Expect the VideoCaptureDevice has been stopped | 296 // Expect the VideoCaptureDevice has been stopped |
305 EXPECT_EQ(0u, host_->entries_.size()); | 297 EXPECT_EQ(0u, host_->entries_.size()); |
306 } | 298 } |
307 | 299 |
308 void NotifyPacketReady() { | 300 void NotifyPacketReady() { |
| 301 base::RunLoop run_loop; |
309 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId, _, _)) | 302 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId, _, _)) |
310 .Times(AnyNumber()).WillOnce(ExitMessageLoop(message_loop_.get())) | 303 .Times(AnyNumber()).WillOnce(ExitMessageLoop( |
| 304 message_loop_, run_loop.QuitClosure())) |
311 .RetiresOnSaturation(); | 305 .RetiresOnSaturation(); |
312 message_loop_->Run(); | 306 run_loop.Run(); |
313 } | 307 } |
314 | 308 |
315 void ReturnReceivedPackets() { | 309 void ReturnReceivedPackets() { |
316 host_->ReturnReceivedDibs(kDeviceId); | 310 host_->ReturnReceivedDibs(kDeviceId); |
317 } | 311 } |
318 | 312 |
319 void SimulateError() { | 313 void SimulateError() { |
320 // Expect a change state to error state sent through IPC. | 314 // Expect a change state to error state sent through IPC. |
321 EXPECT_CALL(*host_.get(), | 315 EXPECT_CALL(*host_.get(), |
322 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_ERROR)).Times(1); | 316 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_ERROR)).Times(1); |
323 VideoCaptureControllerID id(kDeviceId); | 317 VideoCaptureControllerID id(kDeviceId); |
324 host_->OnError(id); | 318 host_->OnError(id); |
325 // Wait for the error callback. | 319 // Wait for the error callback. |
326 message_loop_->RunUntilIdle(); | 320 base::RunLoop().RunUntilIdle(); |
327 } | 321 } |
328 | 322 |
329 scoped_refptr<MockVideoCaptureHost> host_; | 323 scoped_refptr<MockVideoCaptureHost> host_; |
330 | 324 |
331 private: | 325 private: |
332 scoped_ptr<base::MessageLoop> message_loop_; | |
333 scoped_ptr<BrowserThreadImpl> io_thread_; | |
334 scoped_ptr<media::AudioManager> audio_manager_; | 326 scoped_ptr<media::AudioManager> audio_manager_; |
335 scoped_ptr<MediaStreamManager> media_stream_manager_; | 327 scoped_ptr<MediaStreamManager> media_stream_manager_; |
| 328 content::TestBrowserThreadBundle thread_bundle_; |
| 329 scoped_refptr<base::MessageLoopProxy> message_loop_; |
336 | 330 |
337 DISALLOW_COPY_AND_ASSIGN(VideoCaptureHostTest); | 331 DISALLOW_COPY_AND_ASSIGN(VideoCaptureHostTest); |
338 }; | 332 }; |
339 | 333 |
340 TEST_F(VideoCaptureHostTest, StartCapture) { | 334 TEST_F(VideoCaptureHostTest, StartCapture) { |
341 StartCapture(); | 335 StartCapture(); |
342 } | 336 } |
343 | 337 |
344 TEST_F(VideoCaptureHostTest, StartCapturePlayStop) { | 338 TEST_F(VideoCaptureHostTest, StartCapturePlayStop) { |
345 StartCapture(); | 339 StartCapture(); |
(...skipping 21 matching lines...) Expand all Loading... |
367 #ifdef DUMP_VIDEO | 361 #ifdef DUMP_VIDEO |
368 TEST_F(VideoCaptureHostTest, CaptureAndDumpVideoVga) { | 362 TEST_F(VideoCaptureHostTest, CaptureAndDumpVideoVga) { |
369 CaptureAndDumpVideo(640, 480, 30); | 363 CaptureAndDumpVideo(640, 480, 30); |
370 } | 364 } |
371 TEST_F(VideoCaptureHostTest, CaptureAndDump720P) { | 365 TEST_F(VideoCaptureHostTest, CaptureAndDump720P) { |
372 CaptureAndDumpVideo(1280, 720, 30); | 366 CaptureAndDumpVideo(1280, 720, 30); |
373 } | 367 } |
374 #endif | 368 #endif |
375 | 369 |
376 } // namespace content | 370 } // namespace content |
OLD | NEW |