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 // Unit test for VideoCaptureManager.
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "content/browser/browser_thread_impl.h"
15 #include "content/browser/renderer_host/media/media_stream_provider.h"
16 #include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
17 #include "content/browser/renderer_host/media/video_capture_manager.h"
18 #include "content/common/media/media_stream_options.h"
19 #include "media/video/capture/fake_video_capture_device_factory.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
24 using ::testing::AnyNumber;
25 using ::testing::InSequence;
26 using ::testing::Return;
27 using ::testing::SaveArg;
31 // Listener class used to track progress of VideoCaptureManager test.
32 class MockMediaStreamProviderListener : public MediaStreamProviderListener {
34 MockMediaStreamProviderListener() {}
35 ~MockMediaStreamProviderListener() {}
37 MOCK_METHOD2(Opened, void(MediaStreamType, int));
38 MOCK_METHOD2(Closed, void(MediaStreamType, int));
39 MOCK_METHOD2(DevicesEnumerated, void(MediaStreamType,
40 const StreamDeviceInfoArray&));
41 MOCK_METHOD2(Aborted, void(MediaStreamType, int));
42 }; // class MockMediaStreamProviderListener
44 // Needed as an input argument to StartCaptureForClient().
45 class MockFrameObserver : public VideoCaptureControllerEventHandler {
47 MOCK_METHOD1(OnError, void(const VideoCaptureControllerID& id));
49 virtual void OnBufferCreated(const VideoCaptureControllerID& id,
50 base::SharedMemoryHandle handle,
51 int length, int buffer_id) override {}
52 virtual void OnBufferDestroyed(const VideoCaptureControllerID& id,
53 int buffer_id) override {}
54 virtual void OnBufferReady(const VideoCaptureControllerID& id,
56 const media::VideoCaptureFormat& format,
57 const gfx::Rect& visible_rect,
58 base::TimeTicks timestamp) override {}
59 virtual void OnMailboxBufferReady(const VideoCaptureControllerID& id,
61 const gpu::MailboxHolder& mailbox_holder,
62 const media::VideoCaptureFormat& format,
63 base::TimeTicks timestamp) override {}
64 virtual void OnEnded(const VideoCaptureControllerID& id) override {}
66 void OnGotControllerCallback(VideoCaptureControllerID) {}
70 class VideoCaptureManagerTest : public testing::Test {
72 VideoCaptureManagerTest() : next_client_id_(1) {}
73 ~VideoCaptureManagerTest() override {}
76 void SetUp() override {
77 listener_.reset(new MockMediaStreamProviderListener());
78 message_loop_.reset(new base::MessageLoopForIO);
79 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
80 message_loop_.get()));
81 vcm_ = new VideoCaptureManager(scoped_ptr<media::VideoCaptureDeviceFactory>(
82 new media::FakeVideoCaptureDeviceFactory()));
83 video_capture_device_factory_ =
84 static_cast<media::FakeVideoCaptureDeviceFactory*>(
85 vcm_->video_capture_device_factory());
86 const int32 kNumberOfFakeDevices = 2;
87 video_capture_device_factory_->set_number_of_devices(kNumberOfFakeDevices);
88 vcm_->Register(listener_.get(), message_loop_->message_loop_proxy().get());
89 frame_observer_.reset(new MockFrameObserver());
92 void TearDown() override {}
94 void OnGotControllerCallback(
95 VideoCaptureControllerID id,
96 base::Closure quit_closure,
98 const base::WeakPtr<VideoCaptureController>& controller) {
100 ASSERT_TRUE(controller);
101 ASSERT_TRUE(0 == controllers_.count(id));
102 controllers_[id] = controller.get();
104 ASSERT_TRUE(NULL == controller);
109 VideoCaptureControllerID StartClient(int session_id, bool expect_success) {
110 media::VideoCaptureParams params;
111 params.requested_format = media::VideoCaptureFormat(
112 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);
114 VideoCaptureControllerID client_id(next_client_id_++);
115 base::RunLoop run_loop;
116 vcm_->StartCaptureForClient(
119 base::kNullProcessHandle,
121 frame_observer_.get(),
122 base::Bind(&VideoCaptureManagerTest::OnGotControllerCallback,
123 base::Unretained(this),
125 run_loop.QuitClosure(),
131 void StopClient(VideoCaptureControllerID client_id) {
132 ASSERT_TRUE(1 == controllers_.count(client_id));
133 vcm_->StopCaptureForClient(controllers_[client_id], client_id,
134 frame_observer_.get(), false);
135 controllers_.erase(client_id);
139 std::map<VideoCaptureControllerID, VideoCaptureController*> controllers_;
140 scoped_refptr<VideoCaptureManager> vcm_;
141 scoped_ptr<MockMediaStreamProviderListener> listener_;
142 scoped_ptr<base::MessageLoop> message_loop_;
143 scoped_ptr<BrowserThreadImpl> io_thread_;
144 scoped_ptr<MockFrameObserver> frame_observer_;
145 media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
148 DISALLOW_COPY_AND_ASSIGN(VideoCaptureManagerTest);
153 // Try to open, start, stop and close a device.
154 TEST_F(VideoCaptureManagerTest, CreateAndClose) {
155 StreamDeviceInfoArray devices;
158 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
159 .WillOnce(SaveArg<1>(&devices));
160 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
161 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
163 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
165 // Wait to get device callback.
166 message_loop_->RunUntilIdle();
168 int video_session_id = vcm_->Open(devices.front());
169 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
171 StopClient(client_id);
172 vcm_->Close(video_session_id);
174 // Wait to check callbacks before removing the listener.
175 message_loop_->RunUntilIdle();
179 // Try to open, start, and abort a device.
180 TEST_F(VideoCaptureManagerTest, CreateAndAbort) {
181 StreamDeviceInfoArray devices;
184 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
185 .WillOnce(SaveArg<1>(&devices));
186 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
187 EXPECT_CALL(*listener_, Aborted(MEDIA_DEVICE_VIDEO_CAPTURE, _));
189 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
191 // Wait to get device callback.
192 message_loop_->RunUntilIdle();
194 int video_session_id = vcm_->Open(devices.front());
195 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
197 // Wait for device opened.
198 message_loop_->RunUntilIdle();
200 vcm_->StopCaptureForClient(controllers_[client_id], client_id,
201 frame_observer_.get(), true);
203 // Wait to check callbacks before removing the listener.
204 message_loop_->RunUntilIdle();
208 // Open the same device twice.
209 TEST_F(VideoCaptureManagerTest, OpenTwice) {
210 StreamDeviceInfoArray devices;
213 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
214 .WillOnce(SaveArg<1>(&devices));
215 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
216 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
218 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
220 // Wait to get device callback.
221 message_loop_->RunUntilIdle();
223 int video_session_id_first = vcm_->Open(devices.front());
225 // This should trigger an error callback with error code
226 // 'kDeviceAlreadyInUse'.
227 int video_session_id_second = vcm_->Open(devices.front());
228 EXPECT_NE(video_session_id_first, video_session_id_second);
230 vcm_->Close(video_session_id_first);
231 vcm_->Close(video_session_id_second);
233 // Wait to check callbacks before removing the listener.
234 message_loop_->RunUntilIdle();
238 // Connect and disconnect devices.
239 TEST_F(VideoCaptureManagerTest, ConnectAndDisconnectDevices) {
240 StreamDeviceInfoArray devices;
241 int number_of_devices_keep =
242 video_capture_device_factory_->number_of_devices();
245 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
246 .WillOnce(SaveArg<1>(&devices));
247 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
248 message_loop_->RunUntilIdle();
249 ASSERT_EQ(devices.size(), 2u);
251 // Simulate we remove 1 fake device.
252 video_capture_device_factory_->set_number_of_devices(1);
253 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
254 .WillOnce(SaveArg<1>(&devices));
255 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
256 message_loop_->RunUntilIdle();
257 ASSERT_EQ(devices.size(), 1u);
259 // Simulate we add 2 fake devices.
260 video_capture_device_factory_->set_number_of_devices(3);
261 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
262 .WillOnce(SaveArg<1>(&devices));
263 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
264 message_loop_->RunUntilIdle();
265 ASSERT_EQ(devices.size(), 3u);
268 video_capture_device_factory_->set_number_of_devices(number_of_devices_keep);
271 // Enumerate devices and open the first, then check the list of supported
272 // formats. Then start the opened device. The capability list should stay the
273 // same. Finally stop the device and check that the capabilities stay unchanged.
274 TEST_F(VideoCaptureManagerTest, ManipulateDeviceAndCheckCapabilities) {
275 StreamDeviceInfoArray devices;
277 // Before enumerating the devices, requesting formats should return false.
278 int video_session_id = 0;
279 media::VideoCaptureFormats supported_formats;
280 supported_formats.clear();
282 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
285 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
286 .WillOnce(SaveArg<1>(&devices));
287 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
288 message_loop_->RunUntilIdle();
289 ASSERT_GE(devices.size(), 2u);
291 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
292 video_session_id = vcm_->Open(devices.front());
293 message_loop_->RunUntilIdle();
295 // Right after opening the device, we should see all its formats.
296 supported_formats.clear();
298 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
299 ASSERT_GT(supported_formats.size(), 1u);
300 EXPECT_GT(supported_formats[0].frame_size.width(), 1);
301 EXPECT_GT(supported_formats[0].frame_size.height(), 1);
302 EXPECT_GT(supported_formats[0].frame_rate, 1);
303 EXPECT_GT(supported_formats[1].frame_size.width(), 1);
304 EXPECT_GT(supported_formats[1].frame_size.height(), 1);
305 EXPECT_GT(supported_formats[1].frame_rate, 1);
307 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
308 message_loop_->RunUntilIdle();
309 // After StartClient(), device's supported formats should stay the same.
310 supported_formats.clear();
312 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
313 ASSERT_GE(supported_formats.size(), 2u);
314 EXPECT_GT(supported_formats[0].frame_size.width(), 1);
315 EXPECT_GT(supported_formats[0].frame_size.height(), 1);
316 EXPECT_GT(supported_formats[0].frame_rate, 1);
317 EXPECT_GT(supported_formats[1].frame_size.width(), 1);
318 EXPECT_GT(supported_formats[1].frame_size.height(), 1);
319 EXPECT_GT(supported_formats[1].frame_rate, 1);
321 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
322 StopClient(client_id);
323 supported_formats.clear();
325 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
326 ASSERT_GE(supported_formats.size(), 2u);
327 EXPECT_GT(supported_formats[0].frame_size.width(), 1);
328 EXPECT_GT(supported_formats[0].frame_size.height(), 1);
329 EXPECT_GT(supported_formats[0].frame_rate, 1);
330 EXPECT_GT(supported_formats[1].frame_size.width(), 1);
331 EXPECT_GT(supported_formats[1].frame_size.height(), 1);
332 EXPECT_GT(supported_formats[1].frame_rate, 1);
334 vcm_->Close(video_session_id);
335 message_loop_->RunUntilIdle();
339 // Enumerate devices and open the first, then check the formats currently in
340 // use, which should be an empty vector. Then start the opened device. The
341 // format(s) in use should be just one format (the one used when configuring-
342 // starting the device). Finally stop the device and check that the formats in
343 // use is an empty vector.
344 TEST_F(VideoCaptureManagerTest, StartDeviceAndGetDeviceFormatInUse) {
345 StreamDeviceInfoArray devices;
348 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
349 .WillOnce(SaveArg<1>(&devices));
350 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
351 message_loop_->RunUntilIdle();
352 ASSERT_GE(devices.size(), 2u);
354 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
355 int video_session_id = vcm_->Open(devices.front());
356 message_loop_->RunUntilIdle();
358 // Right after opening the device, we should see no format in use.
359 media::VideoCaptureFormats formats_in_use;
360 EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
361 EXPECT_TRUE(formats_in_use.empty());
363 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
364 message_loop_->RunUntilIdle();
365 // After StartClient(), |formats_in_use| should contain one valid format.
366 EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
367 EXPECT_EQ(formats_in_use.size(), 1u);
368 if (formats_in_use.size()) {
369 media::VideoCaptureFormat& format_in_use = formats_in_use.front();
370 EXPECT_TRUE(format_in_use.IsValid());
371 EXPECT_GT(format_in_use.frame_size.width(), 1);
372 EXPECT_GT(format_in_use.frame_size.height(), 1);
373 EXPECT_GT(format_in_use.frame_rate, 1);
375 formats_in_use.clear();
377 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
378 StopClient(client_id);
379 message_loop_->RunUntilIdle();
380 // After StopClient(), the device's formats in use should be empty again.
381 EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
382 EXPECT_TRUE(formats_in_use.empty());
384 vcm_->Close(video_session_id);
385 message_loop_->RunUntilIdle();
389 // Open two different devices.
390 TEST_F(VideoCaptureManagerTest, OpenTwo) {
391 StreamDeviceInfoArray devices;
394 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
395 .WillOnce(SaveArg<1>(&devices));
396 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
397 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
399 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
401 // Wait to get device callback.
402 message_loop_->RunUntilIdle();
404 StreamDeviceInfoArray::iterator it = devices.begin();
406 int video_session_id_first = vcm_->Open(*it);
408 int video_session_id_second = vcm_->Open(*it);
410 vcm_->Close(video_session_id_first);
411 vcm_->Close(video_session_id_second);
413 // Wait to check callbacks before removing the listener.
414 message_loop_->RunUntilIdle();
418 // Try open a non-existing device.
419 TEST_F(VideoCaptureManagerTest, OpenNotExisting) {
420 StreamDeviceInfoArray devices;
423 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
424 .WillOnce(SaveArg<1>(&devices));
425 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
426 EXPECT_CALL(*frame_observer_, OnError(_));
427 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
429 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
431 // Wait to get device callback.
432 message_loop_->RunUntilIdle();
434 MediaStreamType stream_type = MEDIA_DEVICE_VIDEO_CAPTURE;
435 std::string device_name("device_doesnt_exist");
436 std::string device_id("id_doesnt_exist");
437 StreamDeviceInfo dummy_device(stream_type, device_name, device_id);
439 // This should fail with an error to the controller.
440 int session_id = vcm_->Open(dummy_device);
441 VideoCaptureControllerID client_id = StartClient(session_id, true);
442 message_loop_->RunUntilIdle();
444 StopClient(client_id);
445 vcm_->Close(session_id);
446 message_loop_->RunUntilIdle();
451 // Start a device without calling Open, using a non-magic ID.
452 TEST_F(VideoCaptureManagerTest, StartInvalidSession) {
453 StartClient(22, false);
455 // Wait to check callbacks before removing the listener.
456 message_loop_->RunUntilIdle();
460 // Open and start a device, close it before calling Stop.
461 TEST_F(VideoCaptureManagerTest, CloseWithoutStop) {
462 StreamDeviceInfoArray devices;
465 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
466 .WillOnce(SaveArg<1>(&devices));
467 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
468 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
470 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
472 // Wait to get device callback.
473 message_loop_->RunUntilIdle();
475 int video_session_id = vcm_->Open(devices.front());
477 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
479 // Close will stop the running device, an assert will be triggered in
480 // VideoCaptureManager destructor otherwise.
481 vcm_->Close(video_session_id);
482 StopClient(client_id);
484 // Wait to check callbacks before removing the listener
485 message_loop_->RunUntilIdle();
489 // TODO(mcasas): Add a test to check consolidation of the supported formats
490 // provided by the device when http://crbug.com/323913 is closed.
492 } // namespace content