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 VideoCaptureController.
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_controller.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"
25 using ::testing::AnyNumber
;
26 using ::testing::AtLeast
;
27 using ::testing::InSequence
;
28 using ::testing::Return
;
32 enum { kDeviceId
= 1 };
34 ACTION_P4(StopCapture
, controller
, controller_id
, controller_handler
,
36 message_loop
->PostTask(FROM_HERE
,
37 base::Bind(&VideoCaptureController::StopCapture
,
38 controller
, controller_id
, controller_handler
));
39 message_loop
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
42 ACTION_P3(StopSession
, controller
, session_id
, message_loop
) {
43 message_loop
->PostTask(FROM_HERE
,
44 base::Bind(&VideoCaptureController::StopSession
,
45 controller
, session_id
));
46 message_loop
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
49 class MockVideoCaptureControllerEventHandler
50 : public VideoCaptureControllerEventHandler
{
52 MockVideoCaptureControllerEventHandler(VideoCaptureController
* controller
,
53 base::MessageLoop
* message_loop
)
54 : controller_(controller
),
55 message_loop_(message_loop
),
56 controller_id_(kDeviceId
),
57 process_handle_(base::kNullProcessHandle
) {
59 virtual ~MockVideoCaptureControllerEventHandler() {}
61 MOCK_METHOD1(DoBufferCreated
, void(const VideoCaptureControllerID
&));
62 MOCK_METHOD1(DoBufferReady
, void(const VideoCaptureControllerID
&));
63 MOCK_METHOD1(DoFrameInfo
, void(const VideoCaptureControllerID
&));
64 MOCK_METHOD1(DoEnded
, void(const VideoCaptureControllerID
&));
66 virtual void OnError(const VideoCaptureControllerID
& id
) OVERRIDE
{}
67 virtual void OnBufferCreated(const VideoCaptureControllerID
& id
,
68 base::SharedMemoryHandle handle
,
69 int length
, int buffer_id
) OVERRIDE
{
70 EXPECT_EQ(id
, controller_id_
);
73 virtual void OnBufferReady(const VideoCaptureControllerID
& id
,
75 base::Time timestamp
) OVERRIDE
{
76 EXPECT_EQ(id
, controller_id_
);
78 message_loop_
->PostTask(FROM_HERE
,
79 base::Bind(&VideoCaptureController::ReturnBuffer
,
80 controller_
, controller_id_
, this, buffer_id
));
82 virtual void OnFrameInfo(const VideoCaptureControllerID
& id
,
85 int frame_per_second
) OVERRIDE
{
86 EXPECT_EQ(id
, controller_id_
);
89 virtual void OnEnded(const VideoCaptureControllerID
& id
) OVERRIDE
{
90 EXPECT_EQ(id
, controller_id_
);
94 scoped_refptr
<VideoCaptureController
> controller_
;
95 base::MessageLoop
* message_loop_
;
96 VideoCaptureControllerID controller_id_
;
97 base::ProcessHandle process_handle_
;
100 class MockVideoCaptureManager
: public VideoCaptureManager
{
102 MockVideoCaptureManager()
103 : video_session_id_(kStartOpenSessionId
) {}
106 device_name_
.unique_id
= "/dev/video0";
107 device_name_
.device_name
= "fake_device_0";
109 video_capture_device_
.reset(
110 media::FakeVideoCaptureDevice::Create(device_name_
));
111 ASSERT_TRUE(video_capture_device_
.get() != NULL
);
114 MOCK_METHOD3(StartCapture
, void(int, int,
115 media::VideoCaptureDevice::EventHandler
*));
116 MOCK_METHOD1(StopCapture
, void(const media::VideoCaptureSessionId
&));
118 void Start(const media::VideoCaptureParams
& capture_params
,
119 media::VideoCaptureDevice::EventHandler
* vc_receiver
) OVERRIDE
{
120 StartCapture(capture_params
.width
, capture_params
.height
, vc_receiver
);
121 video_capture_device_
->Allocate(capture_params
.width
, capture_params
.height
,
122 capture_params
.frame_per_second
,
124 video_capture_device_
->Start();
127 void Stop(const media::VideoCaptureSessionId
& capture_session_id
,
128 base::Closure stopped_cb
) OVERRIDE
{
129 StopCapture(capture_session_id
);
130 video_capture_device_
->Stop();
131 video_capture_device_
->DeAllocate();
134 int video_session_id_
;
135 media::VideoCaptureDevice::Name device_name_
;
136 scoped_ptr
<media::VideoCaptureDevice
> video_capture_device_
;
139 virtual ~MockVideoCaptureManager() {}
140 DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureManager
);
144 class VideoCaptureControllerTest
: public testing::Test
{
146 VideoCaptureControllerTest() {}
147 virtual ~VideoCaptureControllerTest() {}
150 virtual void SetUp() OVERRIDE
{
151 message_loop_
.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO
));
152 file_thread_
.reset(new BrowserThreadImpl(BrowserThread::FILE,
153 message_loop_
.get()));
154 io_thread_
.reset(new BrowserThreadImpl(BrowserThread::IO
,
155 message_loop_
.get()));
157 vcm_
= new MockVideoCaptureManager();
159 controller_
= new VideoCaptureController(vcm_
.get());
160 controller_handler_
.reset(new MockVideoCaptureControllerEventHandler(
161 controller_
.get(), message_loop_
.get()));
164 virtual void TearDown() OVERRIDE
{}
166 scoped_ptr
<base::MessageLoop
> message_loop_
;
167 scoped_ptr
<BrowserThreadImpl
> file_thread_
;
168 scoped_ptr
<BrowserThreadImpl
> io_thread_
;
169 scoped_refptr
<MockVideoCaptureManager
> vcm_
;
170 scoped_ptr
<MockVideoCaptureControllerEventHandler
> controller_handler_
;
171 scoped_refptr
<VideoCaptureController
> controller_
;
174 DISALLOW_COPY_AND_ASSIGN(VideoCaptureControllerTest
);
177 // Try to start and stop capture.
178 TEST_F(VideoCaptureControllerTest
, StartAndStop
) {
179 media::VideoCaptureParams capture_params
;
180 capture_params
.session_id
= vcm_
->video_session_id_
;
181 capture_params
.width
= 320;
182 capture_params
.height
= 240;
183 capture_params
.frame_per_second
= 30;
186 EXPECT_CALL(*vcm_
.get(),
187 StartCapture(capture_params
.width
,
188 capture_params
.height
,
189 controller_
.get())).Times(1);
190 EXPECT_CALL(*controller_handler_
,
191 DoFrameInfo(controller_handler_
->controller_id_
))
193 EXPECT_CALL(*controller_handler_
,
194 DoBufferCreated(controller_handler_
->controller_id_
))
196 EXPECT_CALL(*controller_handler_
,
197 DoBufferReady(controller_handler_
->controller_id_
))
199 .WillOnce(StopCapture(controller_
.get(),
200 controller_handler_
->controller_id_
,
201 controller_handler_
.get(),
202 message_loop_
.get()));
203 EXPECT_CALL(*vcm_
.get(), StopCapture(vcm_
->video_session_id_
)).Times(1);
205 controller_
->StartCapture(controller_handler_
->controller_id_
,
206 controller_handler_
.get(),
207 controller_handler_
->process_handle_
,
209 message_loop_
->Run();
212 // Try to stop session before stopping capture.
213 TEST_F(VideoCaptureControllerTest
, StopSession
) {
214 media::VideoCaptureParams capture_params
;
215 capture_params
.session_id
= vcm_
->video_session_id_
;
216 capture_params
.width
= 320;
217 capture_params
.height
= 240;
218 capture_params
.frame_per_second
= 30;
221 EXPECT_CALL(*vcm_
.get(),
222 StartCapture(capture_params
.width
,
223 capture_params
.height
,
224 controller_
.get())).Times(1);
225 EXPECT_CALL(*controller_handler_
,
226 DoFrameInfo(controller_handler_
->controller_id_
))
228 EXPECT_CALL(*controller_handler_
,
229 DoBufferCreated(controller_handler_
->controller_id_
))
231 EXPECT_CALL(*controller_handler_
,
232 DoBufferReady(controller_handler_
->controller_id_
))
234 .WillOnce(StopSession(controller_
.get(),
235 vcm_
->video_session_id_
,
236 message_loop_
.get()));
237 EXPECT_CALL(*controller_handler_
,
238 DoEnded(controller_handler_
->controller_id_
))
241 controller_
->StartCapture(controller_handler_
->controller_id_
,
242 controller_handler_
.get(),
243 controller_handler_
->process_handle_
,
245 message_loop_
->Run();
247 // The session is stopped now. There should be no buffer coming from
249 EXPECT_CALL(*controller_handler_
,
250 DoBufferReady(controller_handler_
->controller_id_
))
252 message_loop_
->PostDelayedTask(FROM_HERE
,
253 base::MessageLoop::QuitClosure(), base::TimeDelta::FromSeconds(1));
254 message_loop_
->Run();
256 EXPECT_CALL(*vcm_
.get(), StopCapture(vcm_
->video_session_id_
)).Times(1);
257 controller_
->StopCapture(controller_handler_
->controller_id_
,
258 controller_handler_
.get());
261 } // namespace content