Upstream version 5.34.104.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.h"
20 #include "media/video/capture/video_capture_device.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 using ::testing::_;
25 using ::testing::AnyNumber;
26 using ::testing::InSequence;
27 using ::testing::Return;
28 using ::testing::SaveArg;
29
30 namespace content {
31
32 // Listener class used to track progress of VideoCaptureManager test.
33 class MockMediaStreamProviderListener : public MediaStreamProviderListener {
34  public:
35   MockMediaStreamProviderListener() {}
36   ~MockMediaStreamProviderListener() {}
37
38   MOCK_METHOD2(Opened, void(MediaStreamType, int));
39   MOCK_METHOD2(Closed, void(MediaStreamType, int));
40   MOCK_METHOD2(DevicesEnumerated, void(MediaStreamType,
41                                        const StreamDeviceInfoArray&));
42   MOCK_METHOD3(Error, void(MediaStreamType, int,
43                            MediaStreamProviderError));
44 };  // class MockMediaStreamProviderListener
45
46 // Needed as an input argument to StartCaptureForClient().
47 class MockFrameObserver : public VideoCaptureControllerEventHandler {
48  public:
49   MOCK_METHOD1(OnError, void(const VideoCaptureControllerID& id));
50
51   virtual void OnBufferCreated(const VideoCaptureControllerID& id,
52                                base::SharedMemoryHandle handle,
53                                int length, int buffer_id) OVERRIDE {}
54   virtual void OnBufferDestroyed(const VideoCaptureControllerID& id,
55                                int buffer_id) OVERRIDE {}
56   virtual void OnBufferReady(
57       const VideoCaptureControllerID& id,
58       int buffer_id,
59       base::TimeTicks timestamp,
60       const media::VideoCaptureFormat& format) OVERRIDE {}
61   virtual void OnEnded(const VideoCaptureControllerID& id) OVERRIDE {}
62
63   void OnGotControllerCallback(VideoCaptureControllerID) {}
64 };
65
66 // Test class
67 class VideoCaptureManagerTest : public testing::Test {
68  public:
69   VideoCaptureManagerTest() : next_client_id_(1) {}
70   virtual ~VideoCaptureManagerTest() {}
71
72  protected:
73   virtual void SetUp() OVERRIDE {
74     listener_.reset(new MockMediaStreamProviderListener());
75     message_loop_.reset(new base::MessageLoopForIO);
76     io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
77                                            message_loop_.get()));
78     vcm_ = new VideoCaptureManager();
79     vcm_->UseFakeDevice();
80     vcm_->Register(listener_.get(), message_loop_->message_loop_proxy().get());
81     frame_observer_.reset(new MockFrameObserver());
82   }
83
84   virtual void TearDown() OVERRIDE {}
85
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);
97     }
98     quit_closure.Run();
99   }
100
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::PIXEL_FORMAT_I420);
105
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;
121   }
122
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());
127     controllers_.erase(client_id);
128   }
129
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
138  private:
139   DISALLOW_COPY_AND_ASSIGN(VideoCaptureManagerTest);
140 };
141
142 // Test cases
143
144 // Try to open, start, stop and close a device.
145 TEST_F(VideoCaptureManagerTest, CreateAndClose) {
146   StreamDeviceInfoArray devices;
147
148   InSequence s;
149   EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
150       .Times(1).WillOnce(SaveArg<1>(&devices));
151   EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
152   EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
153
154   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
155
156   // Wait to get device callback.
157   message_loop_->RunUntilIdle();
158
159   int video_session_id = vcm_->Open(devices.front());
160   VideoCaptureControllerID client_id = StartClient(video_session_id, true);
161
162   StopClient(client_id);
163   vcm_->Close(video_session_id);
164
165   // Wait to check callbacks before removing the listener.
166   message_loop_->RunUntilIdle();
167   vcm_->Unregister();
168 }
169
170 // Open the same device twice.
171 TEST_F(VideoCaptureManagerTest, OpenTwice) {
172   StreamDeviceInfoArray devices;
173
174   InSequence s;
175   EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
176       .Times(1).WillOnce(SaveArg<1>(&devices));
177   EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
178   EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
179
180   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
181
182   // Wait to get device callback.
183   message_loop_->RunUntilIdle();
184
185   int video_session_id_first = vcm_->Open(devices.front());
186
187   // This should trigger an error callback with error code
188   // 'kDeviceAlreadyInUse'.
189   int video_session_id_second = vcm_->Open(devices.front());
190   EXPECT_NE(video_session_id_first, video_session_id_second);
191
192   vcm_->Close(video_session_id_first);
193   vcm_->Close(video_session_id_second);
194
195   // Wait to check callbacks before removing the listener.
196   message_loop_->RunUntilIdle();
197   vcm_->Unregister();
198 }
199
200 // Connect and disconnect devices.
201 TEST_F(VideoCaptureManagerTest, ConnectAndDisconnectDevices) {
202   StreamDeviceInfoArray devices;
203   int number_of_devices_keep =
204       media::FakeVideoCaptureDevice::NumberOfFakeDevices();
205
206   InSequence s;
207   EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
208       .Times(1).WillOnce(SaveArg<1>(&devices));
209   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
210   message_loop_->RunUntilIdle();
211   ASSERT_EQ(devices.size(), 2u);
212
213   // Simulate we remove 1 fake device.
214   media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(1);
215   EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
216       .Times(1).WillOnce(SaveArg<1>(&devices));
217   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
218   message_loop_->RunUntilIdle();
219   ASSERT_EQ(devices.size(), 1u);
220
221   // Simulate we add 2 fake devices.
222   media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(3);
223   EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
224       .Times(1).WillOnce(SaveArg<1>(&devices));
225   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
226   message_loop_->RunUntilIdle();
227   ASSERT_EQ(devices.size(), 3u);
228
229   vcm_->Unregister();
230   media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(number_of_devices_keep);
231 }
232
233 // Enumerate devices and open the first, then check the list of supported
234 // formats. Then start the opened device. The capability list should stay the
235 // same. Finally stop the device and check that the capabilities stay unchanged.
236 TEST_F(VideoCaptureManagerTest, ManipulateDeviceAndCheckCapabilities) {
237   StreamDeviceInfoArray devices;
238
239   // Before enumerating the devices, requesting formats should return false.
240   int video_session_id = 0;
241   media::VideoCaptureFormats supported_formats;
242   supported_formats.clear();
243   EXPECT_FALSE(
244       vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
245
246   InSequence s;
247   EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
248       .Times(1).WillOnce(SaveArg<1>(&devices));
249   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
250   message_loop_->RunUntilIdle();
251   ASSERT_GE(devices.size(), 2u);
252
253   EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
254   video_session_id = vcm_->Open(devices.front());
255   message_loop_->RunUntilIdle();
256
257   // Right after opening the device, we should see all its formats.
258   supported_formats.clear();
259   EXPECT_TRUE(
260       vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
261   ASSERT_GT(supported_formats.size(), 1u);
262   EXPECT_GT(supported_formats[0].frame_size.width(), 1);
263   EXPECT_GT(supported_formats[0].frame_size.height(), 1);
264   EXPECT_GT(supported_formats[0].frame_rate, 1);
265   EXPECT_GT(supported_formats[1].frame_size.width(), 1);
266   EXPECT_GT(supported_formats[1].frame_size.height(), 1);
267   EXPECT_GT(supported_formats[1].frame_rate, 1);
268
269   VideoCaptureControllerID client_id = StartClient(video_session_id, true);
270   message_loop_->RunUntilIdle();
271   // After StartClient(), device's supported formats should stay the same.
272   supported_formats.clear();
273   EXPECT_TRUE(
274       vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
275   ASSERT_GE(supported_formats.size(), 2u);
276   EXPECT_GT(supported_formats[0].frame_size.width(), 1);
277   EXPECT_GT(supported_formats[0].frame_size.height(), 1);
278   EXPECT_GT(supported_formats[0].frame_rate, 1);
279   EXPECT_GT(supported_formats[1].frame_size.width(), 1);
280   EXPECT_GT(supported_formats[1].frame_size.height(), 1);
281   EXPECT_GT(supported_formats[1].frame_rate, 1);
282
283   EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
284   StopClient(client_id);
285   supported_formats.clear();
286   EXPECT_TRUE(
287       vcm_->GetDeviceSupportedFormats(video_session_id, &supported_formats));
288   ASSERT_GE(supported_formats.size(), 2u);
289   EXPECT_GT(supported_formats[0].frame_size.width(), 1);
290   EXPECT_GT(supported_formats[0].frame_size.height(), 1);
291   EXPECT_GT(supported_formats[0].frame_rate, 1);
292   EXPECT_GT(supported_formats[1].frame_size.width(), 1);
293   EXPECT_GT(supported_formats[1].frame_size.height(), 1);
294   EXPECT_GT(supported_formats[1].frame_rate, 1);
295
296   vcm_->Close(video_session_id);
297   message_loop_->RunUntilIdle();
298   vcm_->Unregister();
299 }
300
301 // Enumerate devices and open the first, then check the formats currently in
302 // use, which should be an empty vector. Then start the opened device. The
303 // format(s) in use should be just one format (the one used when configuring-
304 // starting the device). Finally stop the device and check that the formats in
305 // use is an empty vector.
306 TEST_F(VideoCaptureManagerTest, StartDeviceAndGetDeviceFormatInUse) {
307   StreamDeviceInfoArray devices;
308
309   InSequence s;
310   EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
311       .Times(1).WillOnce(SaveArg<1>(&devices));
312   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
313   message_loop_->RunUntilIdle();
314   ASSERT_GE(devices.size(), 2u);
315
316   EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
317   int video_session_id = vcm_->Open(devices.front());
318   message_loop_->RunUntilIdle();
319
320   // Right after opening the device, we should see no format in use.
321   media::VideoCaptureFormats formats_in_use;
322   EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
323   EXPECT_TRUE(formats_in_use.empty());
324
325   VideoCaptureControllerID client_id = StartClient(video_session_id, true);
326   message_loop_->RunUntilIdle();
327   // After StartClient(), |formats_in_use| should contain one valid format.
328   EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
329   EXPECT_EQ(formats_in_use.size(), 1u);
330   if (formats_in_use.size()) {
331     media::VideoCaptureFormat& format_in_use = formats_in_use.front();
332     EXPECT_TRUE(format_in_use.IsValid());
333     EXPECT_GT(format_in_use.frame_size.width(), 1);
334     EXPECT_GT(format_in_use.frame_size.height(), 1);
335     EXPECT_GT(format_in_use.frame_rate, 1);
336   }
337   formats_in_use.clear();
338
339   EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
340   StopClient(client_id);
341   message_loop_->RunUntilIdle();
342   // After StopClient(), the device's formats in use should be empty again.
343   EXPECT_TRUE(vcm_->GetDeviceFormatsInUse(video_session_id, &formats_in_use));
344   EXPECT_TRUE(formats_in_use.empty());
345
346   vcm_->Close(video_session_id);
347   message_loop_->RunUntilIdle();
348   vcm_->Unregister();
349 }
350
351 // Open two different devices.
352 TEST_F(VideoCaptureManagerTest, OpenTwo) {
353   StreamDeviceInfoArray devices;
354
355   InSequence s;
356   EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
357       .Times(1).WillOnce(SaveArg<1>(&devices));
358   EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
359   EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
360
361   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
362
363   // Wait to get device callback.
364   message_loop_->RunUntilIdle();
365
366   StreamDeviceInfoArray::iterator it = devices.begin();
367
368   int video_session_id_first = vcm_->Open(*it);
369   ++it;
370   int video_session_id_second = vcm_->Open(*it);
371
372   vcm_->Close(video_session_id_first);
373   vcm_->Close(video_session_id_second);
374
375   // Wait to check callbacks before removing the listener.
376   message_loop_->RunUntilIdle();
377   vcm_->Unregister();
378 }
379
380 // Try open a non-existing device.
381 TEST_F(VideoCaptureManagerTest, OpenNotExisting) {
382   StreamDeviceInfoArray devices;
383
384   InSequence s;
385   EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
386       .Times(1).WillOnce(SaveArg<1>(&devices));
387   EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
388   EXPECT_CALL(*frame_observer_, OnError(_)).Times(1);
389   EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
390
391   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
392
393   // Wait to get device callback.
394   message_loop_->RunUntilIdle();
395
396   MediaStreamType stream_type = MEDIA_DEVICE_VIDEO_CAPTURE;
397   std::string device_name("device_doesnt_exist");
398   std::string device_id("id_doesnt_exist");
399   StreamDeviceInfo dummy_device(stream_type, device_name, device_id);
400
401   // This should fail with an error to the controller.
402   int session_id = vcm_->Open(dummy_device);
403   VideoCaptureControllerID client_id = StartClient(session_id, true);
404   message_loop_->RunUntilIdle();
405
406   StopClient(client_id);
407   vcm_->Close(session_id);
408   message_loop_->RunUntilIdle();
409
410   vcm_->Unregister();
411 }
412
413 // Start a device without calling Open, using a non-magic ID.
414 TEST_F(VideoCaptureManagerTest, StartInvalidSession) {
415   StartClient(22, false);
416
417   // Wait to check callbacks before removing the listener.
418   message_loop_->RunUntilIdle();
419   vcm_->Unregister();
420 }
421
422 // Open and start a device, close it before calling Stop.
423 TEST_F(VideoCaptureManagerTest, CloseWithoutStop) {
424   StreamDeviceInfoArray devices;
425
426   InSequence s;
427   EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
428       .Times(1).WillOnce(SaveArg<1>(&devices));
429   EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
430   EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
431
432   vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
433
434   // Wait to get device callback.
435   message_loop_->RunUntilIdle();
436
437   int video_session_id = vcm_->Open(devices.front());
438
439   VideoCaptureControllerID client_id = StartClient(video_session_id, true);
440
441   // Close will stop the running device, an assert will be triggered in
442   // VideoCaptureManager destructor otherwise.
443   vcm_->Close(video_session_id);
444   StopClient(client_id);
445
446   // Wait to check callbacks before removing the listener
447   message_loop_->RunUntilIdle();
448   vcm_->Unregister();
449 }
450
451 }  // namespace content