Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / media / video_capture_manager_unittest.cc
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.
4
5 // Unit test for VideoCaptureManager.
6
7 #include <string>
8
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"
22
23 using ::testing::_;
24 using ::testing::AnyNumber;
25 using ::testing::InSequence;
26 using ::testing::Return;
27 using ::testing::SaveArg;
28
29 namespace content {
30
31 // Listener class used to track progress of VideoCaptureManager test.
32 class MockMediaStreamProviderListener : public MediaStreamProviderListener {
33  public:
34   MockMediaStreamProviderListener() {}
35   ~MockMediaStreamProviderListener() {}
36
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
43
44 // Needed as an input argument to StartCaptureForClient().
45 class MockFrameObserver : public VideoCaptureControllerEventHandler {
46  public:
47   MOCK_METHOD1(OnError, void(const VideoCaptureControllerID& id));
48
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 {}
64
65   void OnGotControllerCallback(VideoCaptureControllerID) {}
66 };
67
68 // Test class
69 class VideoCaptureManagerTest : public testing::Test {
70  public:
71   VideoCaptureManagerTest() : next_client_id_(1) {}
72   virtual ~VideoCaptureManagerTest() {}
73
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());
89   }
90
91   virtual void TearDown() OVERRIDE {}
92
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);
104     }
105     quit_closure.Run();
106   }
107
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);
112
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;
128   }
129
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);
135   }
136
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_;
145
146  private:
147   DISALLOW_COPY_AND_ASSIGN(VideoCaptureManagerTest);
148 };
149
150 // Test cases
151
152 // Try to open, start, stop and close a device.
153 TEST_F(VideoCaptureManagerTest, CreateAndClose) {
154   StreamDeviceInfoArray devices;
155
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, _));
161
162   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
163
164   // Wait to get device callback.
165   message_loop_->RunUntilIdle();
166
167   int video_session_id = vcm_->Open(devices.front());
168   VideoCaptureControllerID client_id = StartClient(video_session_id, true);
169
170   StopClient(client_id);
171   vcm_->Close(video_session_id);
172
173   // Wait to check callbacks before removing the listener.
174   message_loop_->RunUntilIdle();
175   vcm_->Unregister();
176 }
177
178 // Try to open, start, and abort a device.
179 TEST_F(VideoCaptureManagerTest, CreateAndAbort) {
180   StreamDeviceInfoArray devices;
181
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, _));
187
188   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
189
190   // Wait to get device callback.
191   message_loop_->RunUntilIdle();
192
193   int video_session_id = vcm_->Open(devices.front());
194   VideoCaptureControllerID client_id = StartClient(video_session_id, true);
195
196   // Wait for device opened.
197   message_loop_->RunUntilIdle();
198
199   vcm_->StopCaptureForClient(controllers_[client_id], client_id,
200                              frame_observer_.get(), true);
201
202   // Wait to check callbacks before removing the listener.
203   message_loop_->RunUntilIdle();
204   vcm_->Unregister();
205 }
206
207 // Open the same device twice.
208 TEST_F(VideoCaptureManagerTest, OpenTwice) {
209   StreamDeviceInfoArray devices;
210
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);
216
217   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
218
219   // Wait to get device callback.
220   message_loop_->RunUntilIdle();
221
222   int video_session_id_first = vcm_->Open(devices.front());
223
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);
228
229   vcm_->Close(video_session_id_first);
230   vcm_->Close(video_session_id_second);
231
232   // Wait to check callbacks before removing the listener.
233   message_loop_->RunUntilIdle();
234   vcm_->Unregister();
235 }
236
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();
242
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);
249
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);
257
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);
265
266   vcm_->Unregister();
267   video_capture_device_factory_->set_number_of_devices(number_of_devices_keep);
268 }
269
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;
275
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));
282
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);
289
290   EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
291   video_session_id = vcm_->Open(devices.front());
292   message_loop_->RunUntilIdle();
293
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);
305
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);
319
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);
332
333   vcm_->Close(video_session_id);
334   message_loop_->RunUntilIdle();
335   vcm_->Unregister();
336 }
337
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;
345
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);
352
353   EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
354   int video_session_id = vcm_->Open(devices.front());
355   message_loop_->RunUntilIdle();
356
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());
361
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);
373   }
374   formats_in_use.clear();
375
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());
382
383   vcm_->Close(video_session_id);
384   message_loop_->RunUntilIdle();
385   vcm_->Unregister();
386 }
387
388 // Open two different devices.
389 TEST_F(VideoCaptureManagerTest, OpenTwo) {
390   StreamDeviceInfoArray devices;
391
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);
397
398   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
399
400   // Wait to get device callback.
401   message_loop_->RunUntilIdle();
402
403   StreamDeviceInfoArray::iterator it = devices.begin();
404
405   int video_session_id_first = vcm_->Open(*it);
406   ++it;
407   int video_session_id_second = vcm_->Open(*it);
408
409   vcm_->Close(video_session_id_first);
410   vcm_->Close(video_session_id_second);
411
412   // Wait to check callbacks before removing the listener.
413   message_loop_->RunUntilIdle();
414   vcm_->Unregister();
415 }
416
417 // Try open a non-existing device.
418 TEST_F(VideoCaptureManagerTest, OpenNotExisting) {
419   StreamDeviceInfoArray devices;
420
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, _));
427
428   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
429
430   // Wait to get device callback.
431   message_loop_->RunUntilIdle();
432
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);
437
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();
442
443   StopClient(client_id);
444   vcm_->Close(session_id);
445   message_loop_->RunUntilIdle();
446
447   vcm_->Unregister();
448 }
449
450 // Start a device without calling Open, using a non-magic ID.
451 TEST_F(VideoCaptureManagerTest, StartInvalidSession) {
452   StartClient(22, false);
453
454   // Wait to check callbacks before removing the listener.
455   message_loop_->RunUntilIdle();
456   vcm_->Unregister();
457 }
458
459 // Open and start a device, close it before calling Stop.
460 TEST_F(VideoCaptureManagerTest, CloseWithoutStop) {
461   StreamDeviceInfoArray devices;
462
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, _));
468
469   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
470
471   // Wait to get device callback.
472   message_loop_->RunUntilIdle();
473
474   int video_session_id = vcm_->Open(devices.front());
475
476   VideoCaptureControllerID client_id = StartClient(video_session_id, true);
477
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);
482
483   // Wait to check callbacks before removing the listener
484   message_loop_->RunUntilIdle();
485   vcm_->Unregister();
486 }
487
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.
490
491 }  // namespace content