Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / renderer_host / media / video_capture_manager_unittest.cc
blob8599924b0522b212fe5abe6b525122a28d11a433
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/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"
23 using ::testing::_;
24 using ::testing::AnyNumber;
25 using ::testing::InSequence;
26 using ::testing::Return;
27 using ::testing::SaveArg;
29 namespace content {
31 // Listener class used to track progress of VideoCaptureManager test.
32 class MockMediaStreamProviderListener : public MediaStreamProviderListener {
33 public:
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 {
46 public:
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,
55 int buffer_id,
56 const media::VideoCaptureFormat& format,
57 base::TimeTicks timestamp) OVERRIDE {}
58 virtual void OnMailboxBufferReady(const VideoCaptureControllerID& id,
59 int buffer_id,
60 const gpu::MailboxHolder& mailbox_holder,
61 const media::VideoCaptureFormat& format,
62 base::TimeTicks timestamp) OVERRIDE {}
63 virtual void OnEnded(const VideoCaptureControllerID& id) OVERRIDE {}
65 void OnGotControllerCallback(VideoCaptureControllerID) {}
68 // Test class
69 class VideoCaptureManagerTest : public testing::Test {
70 public:
71 VideoCaptureManagerTest() : next_client_id_(1) {}
72 virtual ~VideoCaptureManagerTest() {}
74 protected:
75 virtual void SetUp() OVERRIDE {
76 listener_.reset(new MockMediaStreamProviderListener());
77 message_loop_.reset(new base::MessageLoopForIO);
78 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
79 message_loop_.get()));
80 vcm_ = new VideoCaptureManager(scoped_ptr<media::VideoCaptureDeviceFactory>(
81 new media::FakeVideoCaptureDeviceFactory()));
82 video_capture_device_factory_ =
83 static_cast<media::FakeVideoCaptureDeviceFactory*>(
84 vcm_->video_capture_device_factory());
85 const int32 kNumberOfFakeDevices = 2;
86 video_capture_device_factory_->set_number_of_devices(kNumberOfFakeDevices);
87 vcm_->Register(listener_.get(), message_loop_->message_loop_proxy().get());
88 frame_observer_.reset(new MockFrameObserver());
91 virtual void TearDown() OVERRIDE {}
93 void OnGotControllerCallback(
94 VideoCaptureControllerID id,
95 base::Closure quit_closure,
96 bool expect_success,
97 const base::WeakPtr<VideoCaptureController>& controller) {
98 if (expect_success) {
99 ASSERT_TRUE(controller);
100 ASSERT_TRUE(0 == controllers_.count(id));
101 controllers_[id] = controller.get();
102 } else {
103 ASSERT_TRUE(NULL == controller);
105 quit_closure.Run();
108 VideoCaptureControllerID StartClient(int session_id, bool expect_success) {
109 media::VideoCaptureParams params;
110 params.requested_format = media::VideoCaptureFormat(
111 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);
113 VideoCaptureControllerID client_id(next_client_id_++);
114 base::RunLoop run_loop;
115 vcm_->StartCaptureForClient(
116 session_id,
117 params,
118 base::kNullProcessHandle,
119 client_id,
120 frame_observer_.get(),
121 base::Bind(&VideoCaptureManagerTest::OnGotControllerCallback,
122 base::Unretained(this),
123 client_id,
124 run_loop.QuitClosure(),
125 expect_success));
126 run_loop.Run();
127 return client_id;
130 void StopClient(VideoCaptureControllerID client_id) {
131 ASSERT_TRUE(1 == controllers_.count(client_id));
132 vcm_->StopCaptureForClient(controllers_[client_id], client_id,
133 frame_observer_.get(), false);
134 controllers_.erase(client_id);
137 int next_client_id_;
138 std::map<VideoCaptureControllerID, VideoCaptureController*> controllers_;
139 scoped_refptr<VideoCaptureManager> vcm_;
140 scoped_ptr<MockMediaStreamProviderListener> listener_;
141 scoped_ptr<base::MessageLoop> message_loop_;
142 scoped_ptr<BrowserThreadImpl> io_thread_;
143 scoped_ptr<MockFrameObserver> frame_observer_;
144 media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
146 private:
147 DISALLOW_COPY_AND_ASSIGN(VideoCaptureManagerTest);
150 // Test cases
152 // Try to open, start, stop and close a device.
153 TEST_F(VideoCaptureManagerTest, CreateAndClose) {
154 StreamDeviceInfoArray devices;
156 InSequence s;
157 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
158 .WillOnce(SaveArg<1>(&devices));
159 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
160 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
162 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
164 // Wait to get device callback.
165 message_loop_->RunUntilIdle();
167 int video_session_id = vcm_->Open(devices.front());
168 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
170 StopClient(client_id);
171 vcm_->Close(video_session_id);
173 // Wait to check callbacks before removing the listener.
174 message_loop_->RunUntilIdle();
175 vcm_->Unregister();
178 // Try to open, start, and abort a device.
179 TEST_F(VideoCaptureManagerTest, CreateAndAbort) {
180 StreamDeviceInfoArray devices;
182 InSequence s;
183 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
184 .WillOnce(SaveArg<1>(&devices));
185 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
186 EXPECT_CALL(*listener_, Aborted(MEDIA_DEVICE_VIDEO_CAPTURE, _));
188 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
190 // Wait to get device callback.
191 message_loop_->RunUntilIdle();
193 int video_session_id = vcm_->Open(devices.front());
194 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
196 // Wait for device opened.
197 message_loop_->RunUntilIdle();
199 vcm_->StopCaptureForClient(controllers_[client_id], client_id,
200 frame_observer_.get(), true);
202 // Wait to check callbacks before removing the listener.
203 message_loop_->RunUntilIdle();
204 vcm_->Unregister();
207 // Open the same device twice.
208 TEST_F(VideoCaptureManagerTest, OpenTwice) {
209 StreamDeviceInfoArray devices;
211 InSequence s;
212 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
213 .WillOnce(SaveArg<1>(&devices));
214 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
215 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
217 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
219 // Wait to get device callback.
220 message_loop_->RunUntilIdle();
222 int video_session_id_first = vcm_->Open(devices.front());
224 // This should trigger an error callback with error code
225 // 'kDeviceAlreadyInUse'.
226 int video_session_id_second = vcm_->Open(devices.front());
227 EXPECT_NE(video_session_id_first, video_session_id_second);
229 vcm_->Close(video_session_id_first);
230 vcm_->Close(video_session_id_second);
232 // Wait to check callbacks before removing the listener.
233 message_loop_->RunUntilIdle();
234 vcm_->Unregister();
237 // Connect and disconnect devices.
238 TEST_F(VideoCaptureManagerTest, ConnectAndDisconnectDevices) {
239 StreamDeviceInfoArray devices;
240 int number_of_devices_keep =
241 video_capture_device_factory_->number_of_devices();
243 InSequence s;
244 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
245 .WillOnce(SaveArg<1>(&devices));
246 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
247 message_loop_->RunUntilIdle();
248 ASSERT_EQ(devices.size(), 2u);
250 // Simulate we remove 1 fake device.
251 video_capture_device_factory_->set_number_of_devices(1);
252 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
253 .WillOnce(SaveArg<1>(&devices));
254 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
255 message_loop_->RunUntilIdle();
256 ASSERT_EQ(devices.size(), 1u);
258 // Simulate we add 2 fake devices.
259 video_capture_device_factory_->set_number_of_devices(3);
260 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
261 .WillOnce(SaveArg<1>(&devices));
262 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
263 message_loop_->RunUntilIdle();
264 ASSERT_EQ(devices.size(), 3u);
266 vcm_->Unregister();
267 video_capture_device_factory_->set_number_of_devices(number_of_devices_keep);
270 // Enumerate devices and open the first, then check the list of supported
271 // formats. Then start the opened device. The capability list should stay the
272 // same. Finally stop the device and check that the capabilities stay unchanged.
273 TEST_F(VideoCaptureManagerTest, ManipulateDeviceAndCheckCapabilities) {
274 StreamDeviceInfoArray devices;
276 // Before enumerating the devices, requesting formats should return false.
277 int video_session_id = 0;
278 media::VideoCaptureFormats supported_formats;
279 supported_formats.clear();
280 EXPECT_FALSE(
281 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
283 InSequence s;
284 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
285 .WillOnce(SaveArg<1>(&devices));
286 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
287 message_loop_->RunUntilIdle();
288 ASSERT_GE(devices.size(), 2u);
290 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
291 video_session_id = vcm_->Open(devices.front());
292 message_loop_->RunUntilIdle();
294 // Right after opening the device, we should see all its formats.
295 supported_formats.clear();
296 EXPECT_TRUE(
297 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
298 ASSERT_GT(supported_formats.size(), 1u);
299 EXPECT_GT(supported_formats[0].frame_size.width(), 1);
300 EXPECT_GT(supported_formats[0].frame_size.height(), 1);
301 EXPECT_GT(supported_formats[0].frame_rate, 1);
302 EXPECT_GT(supported_formats[1].frame_size.width(), 1);
303 EXPECT_GT(supported_formats[1].frame_size.height(), 1);
304 EXPECT_GT(supported_formats[1].frame_rate, 1);
306 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
307 message_loop_->RunUntilIdle();
308 // After StartClient(), device's supported formats should stay the same.
309 supported_formats.clear();
310 EXPECT_TRUE(
311 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
312 ASSERT_GE(supported_formats.size(), 2u);
313 EXPECT_GT(supported_formats[0].frame_size.width(), 1);
314 EXPECT_GT(supported_formats[0].frame_size.height(), 1);
315 EXPECT_GT(supported_formats[0].frame_rate, 1);
316 EXPECT_GT(supported_formats[1].frame_size.width(), 1);
317 EXPECT_GT(supported_formats[1].frame_size.height(), 1);
318 EXPECT_GT(supported_formats[1].frame_rate, 1);
320 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
321 StopClient(client_id);
322 supported_formats.clear();
323 EXPECT_TRUE(
324 vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
325 ASSERT_GE(supported_formats.size(), 2u);
326 EXPECT_GT(supported_formats[0].frame_size.width(), 1);
327 EXPECT_GT(supported_formats[0].frame_size.height(), 1);
328 EXPECT_GT(supported_formats[0].frame_rate, 1);
329 EXPECT_GT(supported_formats[1].frame_size.width(), 1);
330 EXPECT_GT(supported_formats[1].frame_size.height(), 1);
331 EXPECT_GT(supported_formats[1].frame_rate, 1);
333 vcm_->Close(video_session_id);
334 message_loop_->RunUntilIdle();
335 vcm_->Unregister();
338 // Enumerate devices and open the first, then check the formats currently in
339 // use, which should be an empty vector. Then start the opened device. The
340 // format(s) in use should be just one format (the one used when configuring-
341 // starting the device). Finally stop the device and check that the formats in
342 // use is an empty vector.
343 TEST_F(VideoCaptureManagerTest, StartDeviceAndGetDeviceFormatInUse) {
344 StreamDeviceInfoArray devices;
346 InSequence s;
347 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
348 .WillOnce(SaveArg<1>(&devices));
349 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
350 message_loop_->RunUntilIdle();
351 ASSERT_GE(devices.size(), 2u);
353 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
354 int video_session_id = vcm_->Open(devices.front());
355 message_loop_->RunUntilIdle();
357 // Right after opening the device, we should see no format in use.
358 media::VideoCaptureFormats formats_in_use;
359 EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
360 EXPECT_TRUE(formats_in_use.empty());
362 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
363 message_loop_->RunUntilIdle();
364 // After StartClient(), |formats_in_use| should contain one valid format.
365 EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
366 EXPECT_EQ(formats_in_use.size(), 1u);
367 if (formats_in_use.size()) {
368 media::VideoCaptureFormat& format_in_use = formats_in_use.front();
369 EXPECT_TRUE(format_in_use.IsValid());
370 EXPECT_GT(format_in_use.frame_size.width(), 1);
371 EXPECT_GT(format_in_use.frame_size.height(), 1);
372 EXPECT_GT(format_in_use.frame_rate, 1);
374 formats_in_use.clear();
376 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
377 StopClient(client_id);
378 message_loop_->RunUntilIdle();
379 // After StopClient(), the device's formats in use should be empty again.
380 EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
381 EXPECT_TRUE(formats_in_use.empty());
383 vcm_->Close(video_session_id);
384 message_loop_->RunUntilIdle();
385 vcm_->Unregister();
388 // Open two different devices.
389 TEST_F(VideoCaptureManagerTest, OpenTwo) {
390 StreamDeviceInfoArray devices;
392 InSequence s;
393 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
394 .WillOnce(SaveArg<1>(&devices));
395 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
396 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
398 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
400 // Wait to get device callback.
401 message_loop_->RunUntilIdle();
403 StreamDeviceInfoArray::iterator it = devices.begin();
405 int video_session_id_first = vcm_->Open(*it);
406 ++it;
407 int video_session_id_second = vcm_->Open(*it);
409 vcm_->Close(video_session_id_first);
410 vcm_->Close(video_session_id_second);
412 // Wait to check callbacks before removing the listener.
413 message_loop_->RunUntilIdle();
414 vcm_->Unregister();
417 // Try open a non-existing device.
418 TEST_F(VideoCaptureManagerTest, OpenNotExisting) {
419 StreamDeviceInfoArray devices;
421 InSequence s;
422 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
423 .WillOnce(SaveArg<1>(&devices));
424 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
425 EXPECT_CALL(*frame_observer_, OnError(_));
426 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
428 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
430 // Wait to get device callback.
431 message_loop_->RunUntilIdle();
433 MediaStreamType stream_type = MEDIA_DEVICE_VIDEO_CAPTURE;
434 std::string device_name("device_doesnt_exist");
435 std::string device_id("id_doesnt_exist");
436 StreamDeviceInfo dummy_device(stream_type, device_name, device_id);
438 // This should fail with an error to the controller.
439 int session_id = vcm_->Open(dummy_device);
440 VideoCaptureControllerID client_id = StartClient(session_id, true);
441 message_loop_->RunUntilIdle();
443 StopClient(client_id);
444 vcm_->Close(session_id);
445 message_loop_->RunUntilIdle();
447 vcm_->Unregister();
450 // Start a device without calling Open, using a non-magic ID.
451 TEST_F(VideoCaptureManagerTest, StartInvalidSession) {
452 StartClient(22, false);
454 // Wait to check callbacks before removing the listener.
455 message_loop_->RunUntilIdle();
456 vcm_->Unregister();
459 // Open and start a device, close it before calling Stop.
460 TEST_F(VideoCaptureManagerTest, CloseWithoutStop) {
461 StreamDeviceInfoArray devices;
463 InSequence s;
464 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
465 .WillOnce(SaveArg<1>(&devices));
466 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
467 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
469 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
471 // Wait to get device callback.
472 message_loop_->RunUntilIdle();
474 int video_session_id = vcm_->Open(devices.front());
476 VideoCaptureControllerID client_id = StartClient(video_session_id, true);
478 // Close will stop the running device, an assert will be triggered in
479 // VideoCaptureManager destructor otherwise.
480 vcm_->Close(video_session_id);
481 StopClient(client_id);
483 // Wait to check callbacks before removing the listener
484 message_loop_->RunUntilIdle();
485 vcm_->Unregister();
488 // TODO(mcasas): Add a test to check consolidation of the supported formats
489 // provided by the device when http://crbug.com/323913 is closed.
491 } // namespace content