Update To 11.40.268.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                              const gfx::Rect& visible_rect,
58                              base::TimeTicks timestamp) override {}
59   virtual void OnMailboxBufferReady(const VideoCaptureControllerID& id,
60                                     int buffer_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 {}
65
66   void OnGotControllerCallback(VideoCaptureControllerID) {}
67 };
68
69 // Test class
70 class VideoCaptureManagerTest : public testing::Test {
71  public:
72   VideoCaptureManagerTest() : next_client_id_(1) {}
73   ~VideoCaptureManagerTest() override {}
74
75  protected:
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());
90   }
91
92   void TearDown() override {}
93
94   void OnGotControllerCallback(
95       VideoCaptureControllerID id,
96       base::Closure quit_closure,
97       bool expect_success,
98       const base::WeakPtr<VideoCaptureController>& controller) {
99     if (expect_success) {
100       ASSERT_TRUE(controller);
101       ASSERT_TRUE(0 == controllers_.count(id));
102       controllers_[id] = controller.get();
103     } else {
104       ASSERT_TRUE(NULL == controller);
105     }
106     quit_closure.Run();
107   }
108
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);
113
114     VideoCaptureControllerID client_id(next_client_id_++);
115     base::RunLoop run_loop;
116     vcm_->StartCaptureForClient(
117         session_id,
118         params,
119         base::kNullProcessHandle,
120         client_id,
121         frame_observer_.get(),
122         base::Bind(&VideoCaptureManagerTest::OnGotControllerCallback,
123                    base::Unretained(this),
124                    client_id,
125                    run_loop.QuitClosure(),
126                    expect_success));
127     run_loop.Run();
128     return client_id;
129   }
130
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);
136   }
137
138   int next_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_;
146
147  private:
148   DISALLOW_COPY_AND_ASSIGN(VideoCaptureManagerTest);
149 };
150
151 // Test cases
152
153 // Try to open, start, stop and close a device.
154 TEST_F(VideoCaptureManagerTest, CreateAndClose) {
155   StreamDeviceInfoArray devices;
156
157   InSequence s;
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, _));
162
163   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
164
165   // Wait to get device callback.
166   message_loop_->RunUntilIdle();
167
168   int video_session_id = vcm_->Open(devices.front());
169   VideoCaptureControllerID client_id = StartClient(video_session_id, true);
170
171   StopClient(client_id);
172   vcm_->Close(video_session_id);
173
174   // Wait to check callbacks before removing the listener.
175   message_loop_->RunUntilIdle();
176   vcm_->Unregister();
177 }
178
179 // Try to open, start, and abort a device.
180 TEST_F(VideoCaptureManagerTest, CreateAndAbort) {
181   StreamDeviceInfoArray devices;
182
183   InSequence s;
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, _));
188
189   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
190
191   // Wait to get device callback.
192   message_loop_->RunUntilIdle();
193
194   int video_session_id = vcm_->Open(devices.front());
195   VideoCaptureControllerID client_id = StartClient(video_session_id, true);
196
197   // Wait for device opened.
198   message_loop_->RunUntilIdle();
199
200   vcm_->StopCaptureForClient(controllers_[client_id], client_id,
201                              frame_observer_.get(), true);
202
203   // Wait to check callbacks before removing the listener.
204   message_loop_->RunUntilIdle();
205   vcm_->Unregister();
206 }
207
208 // Open the same device twice.
209 TEST_F(VideoCaptureManagerTest, OpenTwice) {
210   StreamDeviceInfoArray devices;
211
212   InSequence s;
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);
217
218   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
219
220   // Wait to get device callback.
221   message_loop_->RunUntilIdle();
222
223   int video_session_id_first = vcm_->Open(devices.front());
224
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);
229
230   vcm_->Close(video_session_id_first);
231   vcm_->Close(video_session_id_second);
232
233   // Wait to check callbacks before removing the listener.
234   message_loop_->RunUntilIdle();
235   vcm_->Unregister();
236 }
237
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();
243
244   InSequence s;
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);
250
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);
258
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);
266
267   vcm_->Unregister();
268   video_capture_device_factory_->set_number_of_devices(number_of_devices_keep);
269 }
270
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;
276
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();
281   EXPECT_FALSE(
282       vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
283
284   InSequence s;
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);
290
291   EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
292   video_session_id = vcm_->Open(devices.front());
293   message_loop_->RunUntilIdle();
294
295   // Right after opening the device, we should see all its formats.
296   supported_formats.clear();
297   EXPECT_TRUE(
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);
306
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();
311   EXPECT_TRUE(
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);
320
321   EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
322   StopClient(client_id);
323   supported_formats.clear();
324   EXPECT_TRUE(
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);
333
334   vcm_->Close(video_session_id);
335   message_loop_->RunUntilIdle();
336   vcm_->Unregister();
337 }
338
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;
346
347   InSequence s;
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);
353
354   EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
355   int video_session_id = vcm_->Open(devices.front());
356   message_loop_->RunUntilIdle();
357
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());
362
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);
374   }
375   formats_in_use.clear();
376
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());
383
384   vcm_->Close(video_session_id);
385   message_loop_->RunUntilIdle();
386   vcm_->Unregister();
387 }
388
389 // Open two different devices.
390 TEST_F(VideoCaptureManagerTest, OpenTwo) {
391   StreamDeviceInfoArray devices;
392
393   InSequence s;
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);
398
399   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
400
401   // Wait to get device callback.
402   message_loop_->RunUntilIdle();
403
404   StreamDeviceInfoArray::iterator it = devices.begin();
405
406   int video_session_id_first = vcm_->Open(*it);
407   ++it;
408   int video_session_id_second = vcm_->Open(*it);
409
410   vcm_->Close(video_session_id_first);
411   vcm_->Close(video_session_id_second);
412
413   // Wait to check callbacks before removing the listener.
414   message_loop_->RunUntilIdle();
415   vcm_->Unregister();
416 }
417
418 // Try open a non-existing device.
419 TEST_F(VideoCaptureManagerTest, OpenNotExisting) {
420   StreamDeviceInfoArray devices;
421
422   InSequence s;
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, _));
428
429   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
430
431   // Wait to get device callback.
432   message_loop_->RunUntilIdle();
433
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);
438
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();
443
444   StopClient(client_id);
445   vcm_->Close(session_id);
446   message_loop_->RunUntilIdle();
447
448   vcm_->Unregister();
449 }
450
451 // Start a device without calling Open, using a non-magic ID.
452 TEST_F(VideoCaptureManagerTest, StartInvalidSession) {
453   StartClient(22, false);
454
455   // Wait to check callbacks before removing the listener.
456   message_loop_->RunUntilIdle();
457   vcm_->Unregister();
458 }
459
460 // Open and start a device, close it before calling Stop.
461 TEST_F(VideoCaptureManagerTest, CloseWithoutStop) {
462   StreamDeviceInfoArray devices;
463
464   InSequence s;
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, _));
469
470   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
471
472   // Wait to get device callback.
473   message_loop_->RunUntilIdle();
474
475   int video_session_id = vcm_->Open(devices.front());
476
477   VideoCaptureControllerID client_id = StartClient(video_session_id, true);
478
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);
483
484   // Wait to check callbacks before removing the listener
485   message_loop_->RunUntilIdle();
486   vcm_->Unregister();
487 }
488
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.
491
492 }  // namespace content