Add ICU message format support
[chromium-blink-merge.git] / content / browser / renderer_host / media / video_capture_manager_unittest.cc
blobdcd252fcc0d0ec37bfaf5e307bc895b2b60bd660
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.
7 #include <string>
9 #include "base/bind.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/run_loop.h"
13 #include "content/browser/browser_thread_impl.h"
14 #include "content/browser/renderer_host/media/media_stream_provider.h"
15 #include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
16 #include "content/browser/renderer_host/media/video_capture_manager.h"
17 #include "content/common/media/media_stream_options.h"
18 #include "media/capture/video/fake_video_capture_device_factory.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using ::testing::_;
23 using ::testing::AnyNumber;
24 using ::testing::InSequence;
25 using ::testing::Return;
26 using ::testing::SaveArg;
28 namespace content {
30 // Listener class used to track progress of VideoCaptureManager test.
31 class MockMediaStreamProviderListener : public MediaStreamProviderListener {
32 public:
33 MockMediaStreamProviderListener() {}
34 ~MockMediaStreamProviderListener() {}
36 MOCK_METHOD2(Opened, void(MediaStreamType, int));
37 MOCK_METHOD2(Closed, void(MediaStreamType, int));
38 MOCK_METHOD2(DevicesEnumerated, void(MediaStreamType,
39 const StreamDeviceInfoArray&));
40 MOCK_METHOD2(Aborted, void(MediaStreamType, int));
41 }; // class MockMediaStreamProviderListener
43 // Needed as an input argument to StartCaptureForClient().
44 class MockFrameObserver : public VideoCaptureControllerEventHandler {
45 public:
46 MOCK_METHOD1(OnError, void(VideoCaptureControllerID id));
48 void OnBufferCreated(VideoCaptureControllerID id,
49 base::SharedMemoryHandle handle,
50 int length, int buffer_id) override {}
51 void OnBufferDestroyed(VideoCaptureControllerID id, int buffer_id) override {}
52 void OnBufferReady(VideoCaptureControllerID id,
53 int buffer_id,
54 const scoped_refptr<media::VideoFrame>& frame,
55 const base::TimeTicks& timestamp) override {}
56 void OnEnded(VideoCaptureControllerID id) override {}
58 void OnGotControllerCallback(VideoCaptureControllerID) {}
61 // Test class
62 class VideoCaptureManagerTest : public testing::Test {
63 public:
64 VideoCaptureManagerTest() : next_client_id_(1) {}
65 ~VideoCaptureManagerTest() override {}
67 protected:
68 void SetUp() override {
69 listener_.reset(new MockMediaStreamProviderListener());
70 message_loop_.reset(new base::MessageLoopForIO);
71 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
72 message_loop_.get()));
73 vcm_ = new VideoCaptureManager(scoped_ptr<media::VideoCaptureDeviceFactory>(
74 new media::FakeVideoCaptureDeviceFactory()));
75 video_capture_device_factory_ =
76 static_cast<media::FakeVideoCaptureDeviceFactory*>(
77 vcm_->video_capture_device_factory());
78 const int32 kNumberOfFakeDevices = 2;
79 video_capture_device_factory_->set_number_of_devices(kNumberOfFakeDevices);
80 vcm_->Register(listener_.get(), message_loop_->task_runner().get());
81 frame_observer_.reset(new MockFrameObserver());
84 void TearDown() override {}
86 void OnGotControllerCallback(
87 VideoCaptureControllerID id,
88 base::Closure quit_closure,
89 bool expect_success,
90 const base::WeakPtr<VideoCaptureController>& controller) {
91 if (expect_success) {
92 ASSERT_TRUE(controller);
93 ASSERT_TRUE(0 == controllers_.count(id));
94 controllers_[id] = controller.get();
95 } else {
96 ASSERT_TRUE(NULL == controller);
98 quit_closure.Run();
101 VideoCaptureControllerID StartClient(int session_id, bool expect_success) {
102 media::VideoCaptureParams params;
103 params.requested_format = media::VideoCaptureFormat(
104 gfx::Size(320, 240), 30, media::VIDEO_CAPTURE_PIXEL_FORMAT_I420);
106 VideoCaptureControllerID client_id(next_client_id_++);
107 base::RunLoop run_loop;
108 vcm_->StartCaptureForClient(
109 session_id,
110 params,
111 base::kNullProcessHandle,
112 client_id,
113 frame_observer_.get(),
114 base::Bind(&VideoCaptureManagerTest::OnGotControllerCallback,
115 base::Unretained(this),
116 client_id,
117 run_loop.QuitClosure(),
118 expect_success));
119 run_loop.Run();
120 return client_id;
123 void StopClient(VideoCaptureControllerID client_id) {
124 ASSERT_TRUE(1 == controllers_.count(client_id));
125 vcm_->StopCaptureForClient(controllers_[client_id], client_id,
126 frame_observer_.get(), false);
127 controllers_.erase(client_id);
130 int next_client_id_;
131 std::map<VideoCaptureControllerID, VideoCaptureController*> controllers_;
132 scoped_refptr<VideoCaptureManager> vcm_;
133 scoped_ptr<MockMediaStreamProviderListener> listener_;
134 scoped_ptr<base::MessageLoop> message_loop_;
135 scoped_ptr<BrowserThreadImpl> io_thread_;
136 scoped_ptr<MockFrameObserver> frame_observer_;
137 media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
139 private:
140 DISALLOW_COPY_AND_ASSIGN(VideoCaptureManagerTest);
143 // Test cases
145 // Try to open, start, stop and close a device.
146 TEST_F(VideoCaptureManagerTest, CreateAndClose) {
147 StreamDeviceInfoArray devices;
149 InSequence s;
150 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
151 .WillOnce(SaveArg<1>(&devices));
152 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
153 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
155 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
157 // Wait to get device callback.
158 message_loop_->RunUntilIdle();
160 int video_session_id = vcm_->Open(devices.front());
161 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
163 StopClient(client_id);
164 vcm_->Close(video_session_id);
166 // Wait to check callbacks before removing the listener.
167 message_loop_->RunUntilIdle();
168 vcm_->Unregister();
171 TEST_F(VideoCaptureManagerTest, CreateAndCloseMultipleTimes) {
172 StreamDeviceInfoArray devices;
174 InSequence s;
175 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
176 .WillOnce(SaveArg<1>(&devices));
178 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
180 // Wait to get device callback.
181 message_loop_->RunUntilIdle();
183 for (int i = 1 ; i < 3 ; ++i) {
184 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, i));
185 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, i));
186 int video_session_id = vcm_->Open(devices.front());
187 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
189 StopClient(client_id);
190 vcm_->Close(video_session_id);
193 // Wait to check callbacks before removing the listener.
194 message_loop_->RunUntilIdle();
195 vcm_->Unregister();
198 // Try to open, start, and abort a device.
199 TEST_F(VideoCaptureManagerTest, CreateAndAbort) {
200 StreamDeviceInfoArray devices;
202 InSequence s;
203 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
204 .WillOnce(SaveArg<1>(&devices));
205 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
206 EXPECT_CALL(*listener_, Aborted(MEDIA_DEVICE_VIDEO_CAPTURE, _));
208 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
210 // Wait to get device callback.
211 message_loop_->RunUntilIdle();
213 int video_session_id = vcm_->Open(devices.front());
214 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
216 // Wait for device opened.
217 message_loop_->RunUntilIdle();
219 vcm_->StopCaptureForClient(controllers_[client_id], client_id,
220 frame_observer_.get(), true);
222 // Wait to check callbacks before removing the listener.
223 message_loop_->RunUntilIdle();
224 vcm_->Unregister();
227 // Open the same device twice.
228 TEST_F(VideoCaptureManagerTest, OpenTwice) {
229 StreamDeviceInfoArray devices;
231 InSequence s;
232 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
233 .WillOnce(SaveArg<1>(&devices));
234 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
235 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
237 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
239 // Wait to get device callback.
240 message_loop_->RunUntilIdle();
242 int video_session_id_first = vcm_->Open(devices.front());
244 // This should trigger an error callback with error code
245 // 'kDeviceAlreadyInUse'.
246 int video_session_id_second = vcm_->Open(devices.front());
247 EXPECT_NE(video_session_id_first, video_session_id_second);
249 vcm_->Close(video_session_id_first);
250 vcm_->Close(video_session_id_second);
252 // Wait to check callbacks before removing the listener.
253 message_loop_->RunUntilIdle();
254 vcm_->Unregister();
257 // Connect and disconnect devices.
258 TEST_F(VideoCaptureManagerTest, ConnectAndDisconnectDevices) {
259 StreamDeviceInfoArray devices;
260 int number_of_devices_keep =
261 video_capture_device_factory_->number_of_devices();
263 InSequence s;
264 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
265 .WillOnce(SaveArg<1>(&devices));
266 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
267 message_loop_->RunUntilIdle();
268 ASSERT_EQ(devices.size(), 2u);
270 // Simulate we remove 1 fake device.
271 video_capture_device_factory_->set_number_of_devices(1);
272 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
273 .WillOnce(SaveArg<1>(&devices));
274 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
275 message_loop_->RunUntilIdle();
276 ASSERT_EQ(devices.size(), 1u);
278 // Simulate we add 2 fake devices.
279 video_capture_device_factory_->set_number_of_devices(3);
280 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
281 .WillOnce(SaveArg<1>(&devices));
282 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
283 message_loop_->RunUntilIdle();
284 ASSERT_EQ(devices.size(), 3u);
286 vcm_->Unregister();
287 video_capture_device_factory_->set_number_of_devices(number_of_devices_keep);
290 // Enumerate devices and open the first, then check the list of supported
291 // formats. Then start the opened device. The capability list should stay the
292 // same. Finally stop the device and check that the capabilities stay unchanged.
293 TEST_F(VideoCaptureManagerTest, ManipulateDeviceAndCheckCapabilities) {
294 StreamDeviceInfoArray devices;
296 // Before enumerating the devices, requesting formats should return false.
297 int video_session_id = 0;
298 media::VideoCaptureFormats supported_formats;
299 supported_formats.clear();
300 EXPECT_FALSE(
301 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
303 InSequence s;
304 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
305 .WillOnce(SaveArg<1>(&devices));
306 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
307 message_loop_->RunUntilIdle();
308 ASSERT_GE(devices.size(), 2u);
310 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
311 video_session_id = vcm_->Open(devices.front());
312 message_loop_->RunUntilIdle();
314 // Right after opening the device, we should see all its formats.
315 supported_formats.clear();
316 EXPECT_TRUE(
317 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
318 ASSERT_GT(supported_formats.size(), 1u);
319 EXPECT_GT(supported_formats[0].frame_size.width(), 1);
320 EXPECT_GT(supported_formats[0].frame_size.height(), 1);
321 EXPECT_GT(supported_formats[0].frame_rate, 1);
322 EXPECT_GT(supported_formats[1].frame_size.width(), 1);
323 EXPECT_GT(supported_formats[1].frame_size.height(), 1);
324 EXPECT_GT(supported_formats[1].frame_rate, 1);
326 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
327 message_loop_->RunUntilIdle();
328 // After StartClient(), device's supported formats should stay the same.
329 supported_formats.clear();
330 EXPECT_TRUE(
331 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
332 ASSERT_GE(supported_formats.size(), 2u);
333 EXPECT_GT(supported_formats[0].frame_size.width(), 1);
334 EXPECT_GT(supported_formats[0].frame_size.height(), 1);
335 EXPECT_GT(supported_formats[0].frame_rate, 1);
336 EXPECT_GT(supported_formats[1].frame_size.width(), 1);
337 EXPECT_GT(supported_formats[1].frame_size.height(), 1);
338 EXPECT_GT(supported_formats[1].frame_rate, 1);
340 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
341 StopClient(client_id);
342 supported_formats.clear();
343 EXPECT_TRUE(
344 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
345 ASSERT_GE(supported_formats.size(), 2u);
346 EXPECT_GT(supported_formats[0].frame_size.width(), 1);
347 EXPECT_GT(supported_formats[0].frame_size.height(), 1);
348 EXPECT_GT(supported_formats[0].frame_rate, 1);
349 EXPECT_GT(supported_formats[1].frame_size.width(), 1);
350 EXPECT_GT(supported_formats[1].frame_size.height(), 1);
351 EXPECT_GT(supported_formats[1].frame_rate, 1);
353 vcm_->Close(video_session_id);
354 message_loop_->RunUntilIdle();
355 vcm_->Unregister();
358 // Enumerate devices and open the first, then check the formats currently in
359 // use, which should be an empty vector. Then start the opened device. The
360 // format(s) in use should be just one format (the one used when configuring-
361 // starting the device). Finally stop the device and check that the formats in
362 // use is an empty vector.
363 TEST_F(VideoCaptureManagerTest, StartDeviceAndGetDeviceFormatInUse) {
364 StreamDeviceInfoArray devices;
366 InSequence s;
367 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
368 .WillOnce(SaveArg<1>(&devices));
369 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
370 message_loop_->RunUntilIdle();
371 ASSERT_GE(devices.size(), 2u);
373 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
374 int video_session_id = vcm_->Open(devices.front());
375 message_loop_->RunUntilIdle();
377 // Right after opening the device, we should see no format in use.
378 media::VideoCaptureFormats formats_in_use;
379 EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
380 EXPECT_TRUE(formats_in_use.empty());
382 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
383 message_loop_->RunUntilIdle();
384 // After StartClient(), |formats_in_use| should contain one valid format.
385 EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
386 EXPECT_EQ(formats_in_use.size(), 1u);
387 if (formats_in_use.size()) {
388 media::VideoCaptureFormat& format_in_use = formats_in_use.front();
389 EXPECT_TRUE(format_in_use.IsValid());
390 EXPECT_GT(format_in_use.frame_size.width(), 1);
391 EXPECT_GT(format_in_use.frame_size.height(), 1);
392 EXPECT_GT(format_in_use.frame_rate, 1);
394 formats_in_use.clear();
396 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
397 StopClient(client_id);
398 message_loop_->RunUntilIdle();
399 // After StopClient(), the device's formats in use should be empty again.
400 EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
401 EXPECT_TRUE(formats_in_use.empty());
403 vcm_->Close(video_session_id);
404 message_loop_->RunUntilIdle();
405 vcm_->Unregister();
408 // Open two different devices.
409 TEST_F(VideoCaptureManagerTest, OpenTwo) {
410 StreamDeviceInfoArray devices;
412 InSequence s;
413 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
414 .WillOnce(SaveArg<1>(&devices));
415 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
416 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
418 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
420 // Wait to get device callback.
421 message_loop_->RunUntilIdle();
423 StreamDeviceInfoArray::iterator it = devices.begin();
425 int video_session_id_first = vcm_->Open(*it);
426 ++it;
427 int video_session_id_second = vcm_->Open(*it);
429 vcm_->Close(video_session_id_first);
430 vcm_->Close(video_session_id_second);
432 // Wait to check callbacks before removing the listener.
433 message_loop_->RunUntilIdle();
434 vcm_->Unregister();
437 // Try open a non-existing device.
438 TEST_F(VideoCaptureManagerTest, OpenNotExisting) {
439 StreamDeviceInfoArray devices;
441 InSequence s;
442 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
443 .WillOnce(SaveArg<1>(&devices));
444 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
445 EXPECT_CALL(*frame_observer_, OnError(_));
446 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
448 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
450 // Wait to get device callback.
451 message_loop_->RunUntilIdle();
453 MediaStreamType stream_type = MEDIA_DEVICE_VIDEO_CAPTURE;
454 std::string device_name("device_doesnt_exist");
455 std::string device_id("id_doesnt_exist");
456 StreamDeviceInfo dummy_device(stream_type, device_name, device_id);
458 // This should fail with an error to the controller.
459 int session_id = vcm_->Open(dummy_device);
460 VideoCaptureControllerID client_id = StartClient(session_id, true);
461 message_loop_->RunUntilIdle();
463 StopClient(client_id);
464 vcm_->Close(session_id);
465 message_loop_->RunUntilIdle();
467 vcm_->Unregister();
470 // Start a device without calling Open, using a non-magic ID.
471 TEST_F(VideoCaptureManagerTest, StartInvalidSession) {
472 StartClient(22, false);
474 // Wait to check callbacks before removing the listener.
475 message_loop_->RunUntilIdle();
476 vcm_->Unregister();
479 // Open and start a device, close it before calling Stop.
480 TEST_F(VideoCaptureManagerTest, CloseWithoutStop) {
481 StreamDeviceInfoArray devices;
483 InSequence s;
484 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
485 .WillOnce(SaveArg<1>(&devices));
486 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
487 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
489 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
491 // Wait to get device callback.
492 message_loop_->RunUntilIdle();
494 int video_session_id = vcm_->Open(devices.front());
496 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
498 // Close will stop the running device, an assert will be triggered in
499 // VideoCaptureManager destructor otherwise.
500 vcm_->Close(video_session_id);
501 StopClient(client_id);
503 // Wait to check callbacks before removing the listener
504 message_loop_->RunUntilIdle();
505 vcm_->Unregister();
508 // TODO(mcasas): Add a test to check consolidation of the supported formats
509 // provided by the device when http://crbug.com/323913 is closed.
511 } // namespace content