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.
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop.h"
13 #include "base/process_util.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_manager.h"
17 #include "content/common/media/media_stream_options.h"
18 #include "media/video/capture/video_capture_device.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
23 using ::testing::AnyNumber
;
24 using ::testing::InSequence
;
25 using testing::SaveArg
;
26 using ::testing::Return
;
30 // Listener class used to track progress of VideoCaptureManager test.
31 class MockMediaStreamProviderListener
: public MediaStreamProviderListener
{
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_METHOD3(Error
, void(MediaStreamType
, int,
41 MediaStreamProviderError
));
42 }; // class MockMediaStreamProviderListener
44 // Needed as an input argument to Start().
45 class MockFrameObserver
: public media::VideoCaptureDevice::EventHandler
{
47 virtual scoped_refptr
<media::VideoFrame
> ReserveOutputBuffer() OVERRIDE
{
50 virtual void OnError() OVERRIDE
{}
51 virtual void OnFrameInfo(
52 const media::VideoCaptureCapability
& info
) OVERRIDE
{}
53 virtual void OnIncomingCapturedFrame(const uint8
* data
,
58 bool flip_horiz
) OVERRIDE
{}
59 virtual void OnIncomingCapturedVideoFrame(
60 const scoped_refptr
<media::VideoFrame
>& frame
,
61 base::Time timestamp
) OVERRIDE
{}
65 class VideoCaptureManagerTest
: public testing::Test
{
67 VideoCaptureManagerTest() {}
68 virtual ~VideoCaptureManagerTest() {}
71 virtual void SetUp() OVERRIDE
{
72 listener_
.reset(new MockMediaStreamProviderListener());
73 message_loop_
.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO
));
74 io_thread_
.reset(new BrowserThreadImpl(BrowserThread::IO
,
75 message_loop_
.get()));
76 vcm_
= new VideoCaptureManager();
77 vcm_
->UseFakeDevice();
78 vcm_
->Register(listener_
.get(), message_loop_
->message_loop_proxy().get());
79 frame_observer_
.reset(new MockFrameObserver());
82 virtual void TearDown() OVERRIDE
{}
84 scoped_refptr
<VideoCaptureManager
> vcm_
;
85 scoped_ptr
<MockMediaStreamProviderListener
> listener_
;
86 scoped_ptr
<base::MessageLoop
> message_loop_
;
87 scoped_ptr
<BrowserThreadImpl
> io_thread_
;
88 scoped_ptr
<MockFrameObserver
> frame_observer_
;
91 DISALLOW_COPY_AND_ASSIGN(VideoCaptureManagerTest
);
96 // Try to open, start, stop and close a device.
97 TEST_F(VideoCaptureManagerTest
, CreateAndClose
) {
98 StreamDeviceInfoArray devices
;
101 EXPECT_CALL(*listener_
, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE
, _
))
102 .Times(1).WillOnce(SaveArg
<1>(&devices
));
103 EXPECT_CALL(*listener_
, Opened(MEDIA_DEVICE_VIDEO_CAPTURE
, _
)).Times(1);
104 EXPECT_CALL(*listener_
, Closed(MEDIA_DEVICE_VIDEO_CAPTURE
, _
)).Times(1);
106 vcm_
->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE
);
108 // Wait to get device callback.
109 message_loop_
->RunUntilIdle();
111 int video_session_id
= vcm_
->Open(devices
.front());
113 media::VideoCaptureParams capture_params
;
114 capture_params
.session_id
= video_session_id
;
115 capture_params
.width
= 320;
116 capture_params
.height
= 240;
117 capture_params
.frame_per_second
= 30;
118 vcm_
->Start(capture_params
, frame_observer_
.get());
120 vcm_
->Stop(video_session_id
, base::Closure());
121 vcm_
->Close(video_session_id
);
123 // Wait to check callbacks before removing the listener.
124 message_loop_
->RunUntilIdle();
128 // Open the same device twice.
129 TEST_F(VideoCaptureManagerTest
, OpenTwice
) {
130 StreamDeviceInfoArray devices
;
133 EXPECT_CALL(*listener_
, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE
, _
))
134 .Times(1).WillOnce(SaveArg
<1>(&devices
));
135 EXPECT_CALL(*listener_
, Opened(MEDIA_DEVICE_VIDEO_CAPTURE
, _
)).Times(2);
136 EXPECT_CALL(*listener_
, Closed(MEDIA_DEVICE_VIDEO_CAPTURE
, _
)).Times(2);
138 vcm_
->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE
);
140 // Wait to get device callback.
141 message_loop_
->RunUntilIdle();
143 int video_session_id_first
= vcm_
->Open(devices
.front());
145 // This should trigger an error callback with error code
146 // 'kDeviceAlreadyInUse'.
147 int video_session_id_second
= vcm_
->Open(devices
.front());
148 EXPECT_NE(video_session_id_first
, video_session_id_second
);
150 vcm_
->Close(video_session_id_first
);
151 vcm_
->Close(video_session_id_second
);
153 // Wait to check callbacks before removing the listener.
154 message_loop_
->RunUntilIdle();
158 // Open two different devices.
159 TEST_F(VideoCaptureManagerTest
, OpenTwo
) {
160 StreamDeviceInfoArray devices
;
163 EXPECT_CALL(*listener_
, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE
, _
))
164 .Times(1).WillOnce(SaveArg
<1>(&devices
));
165 EXPECT_CALL(*listener_
, Opened(MEDIA_DEVICE_VIDEO_CAPTURE
, _
)).Times(2);
166 EXPECT_CALL(*listener_
, Closed(MEDIA_DEVICE_VIDEO_CAPTURE
, _
)).Times(2);
168 vcm_
->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE
);
170 // Wait to get device callback.
171 message_loop_
->RunUntilIdle();
173 StreamDeviceInfoArray::iterator it
= devices
.begin();
175 int video_session_id_first
= vcm_
->Open(*it
);
177 int video_session_id_second
= vcm_
->Open(*it
);
179 vcm_
->Close(video_session_id_first
);
180 vcm_
->Close(video_session_id_second
);
182 // Wait to check callbacks before removing the listener.
183 message_loop_
->RunUntilIdle();
187 // Try open a non-existing device.
188 TEST_F(VideoCaptureManagerTest
, OpenNotExisting
) {
189 StreamDeviceInfoArray devices
;
192 EXPECT_CALL(*listener_
, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE
, _
))
193 .Times(1).WillOnce(SaveArg
<1>(&devices
));
194 EXPECT_CALL(*listener_
, Error(MEDIA_DEVICE_VIDEO_CAPTURE
,
195 _
, kDeviceNotAvailable
))
198 vcm_
->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE
);
200 // Wait to get device callback.
201 message_loop_
->RunUntilIdle();
203 MediaStreamType stream_type
= MEDIA_DEVICE_VIDEO_CAPTURE
;
204 std::string
device_name("device_doesnt_exist");
205 std::string
device_id("id_doesnt_exist");
206 StreamDeviceInfo
dummy_device(stream_type
, device_name
, device_id
, false);
208 // This should fail with error code 'kDeviceNotAvailable'.
209 vcm_
->Open(dummy_device
);
211 // Wait to check callbacks before removing the listener.
212 message_loop_
->RunUntilIdle();
216 // Start a device using "magic" id, i.e. call Start without calling Open.
217 TEST_F(VideoCaptureManagerTest
, StartUsingId
) {
219 EXPECT_CALL(*listener_
, Opened(MEDIA_DEVICE_VIDEO_CAPTURE
, _
)).Times(1);
220 EXPECT_CALL(*listener_
, Closed(MEDIA_DEVICE_VIDEO_CAPTURE
, _
)).Times(1);
222 media::VideoCaptureParams capture_params
;
223 capture_params
.session_id
= VideoCaptureManager::kStartOpenSessionId
;
224 capture_params
.width
= 320;
225 capture_params
.height
= 240;
226 capture_params
.frame_per_second
= 30;
228 // Start shall trigger the Open callback.
229 vcm_
->Start(capture_params
, frame_observer_
.get());
231 // Stop shall trigger the Close callback
232 vcm_
->Stop(VideoCaptureManager::kStartOpenSessionId
, base::Closure());
234 // Wait to check callbacks before removing the listener.
235 message_loop_
->RunUntilIdle();
239 // Open and start a device, close it before calling Stop.
240 TEST_F(VideoCaptureManagerTest
, CloseWithoutStop
) {
241 StreamDeviceInfoArray devices
;
244 EXPECT_CALL(*listener_
, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE
, _
))
245 .Times(1).WillOnce(SaveArg
<1>(&devices
));
246 EXPECT_CALL(*listener_
, Opened(MEDIA_DEVICE_VIDEO_CAPTURE
, _
)).Times(1);
247 EXPECT_CALL(*listener_
, Closed(MEDIA_DEVICE_VIDEO_CAPTURE
, _
)).Times(1);
249 vcm_
->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE
);
251 // Wait to get device callback.
252 message_loop_
->RunUntilIdle();
254 int video_session_id
= vcm_
->Open(devices
.front());
256 media::VideoCaptureParams capture_params
;
257 capture_params
.session_id
= video_session_id
;
258 capture_params
.width
= 320;
259 capture_params
.height
= 240;
260 capture_params
.frame_per_second
= 30;
261 vcm_
->Start(capture_params
, frame_observer_
.get());
263 // Close will stop the running device, an assert will be triggered in
264 // VideoCaptureManager destructor otherwise.
265 vcm_
->Close(video_session_id
);
266 vcm_
->Stop(video_session_id
, base::Closure());
268 // Wait to check callbacks before removing the listener
269 message_loop_
->RunUntilIdle();
273 } // namespace content