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 #include "base/message_loop/message_loop.h"
6 #include "base/run_loop.h"
7 #include "content/child/child_process.h"
8 #include "content/common/media/video_capture_messages.h"
9 #include "content/renderer/media/video_capture_impl.h"
10 #include "media/base/bind_to_current_loop.h"
11 #include "media/video/capture/mock_video_capture_event_handler.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
16 using ::testing::AtLeast;
17 using ::testing::InvokeWithoutArgs;
18 using ::testing::Return;
19 using ::testing::SaveArg;
20 using media::MockVideoCaptureEventHandler;
24 class MockVideoCaptureMessageFilter : public VideoCaptureMessageFilter {
26 MockVideoCaptureMessageFilter() : VideoCaptureMessageFilter() {}
28 // Filter implementation.
29 MOCK_METHOD1(Send, bool(IPC::Message* message));
32 virtual ~MockVideoCaptureMessageFilter() {}
35 DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureMessageFilter);
38 class VideoCaptureImplTest : public ::testing::Test {
40 class MockVideoCaptureImpl : public VideoCaptureImpl {
42 MockVideoCaptureImpl(const media::VideoCaptureSessionId id,
43 VideoCaptureMessageFilter* filter)
44 : VideoCaptureImpl(id, filter) {
46 virtual ~MockVideoCaptureImpl() {}
48 // Override Send() to mimic device to send events.
49 virtual void Send(IPC::Message* message) OVERRIDE {
52 // In this method, messages are sent to the according handlers as if
55 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureImpl, *message)
56 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, DeviceStartCapture)
57 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, DevicePauseCapture)
58 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, DeviceStopCapture)
59 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady,
60 DeviceReceiveEmptyBuffer)
61 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceSupportedFormats,
62 DeviceGetSupportedFormats)
63 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceFormatsInUse,
64 DeviceGetFormatsInUse)
65 IPC_MESSAGE_UNHANDLED(handled = false)
71 void DeviceStartCapture(int device_id,
72 media::VideoCaptureSessionId session_id,
73 const media::VideoCaptureParams& params) {
74 OnStateChanged(VIDEO_CAPTURE_STATE_STARTED);
77 void DevicePauseCapture(int device_id) {}
79 void DeviceStopCapture(int device_id) {
80 OnStateChanged(VIDEO_CAPTURE_STATE_STOPPED);
83 void DeviceReceiveEmptyBuffer(int device_id, int buffer_id) {}
85 void DeviceGetSupportedFormats(int device_id,
86 media::VideoCaptureSessionId session_id) {
87 // When the mock message filter receives a request for the device
88 // supported formats, replies immediately with an empty format list.
89 OnDeviceSupportedFormatsEnumerated(
90 media::VideoCaptureFormats());
93 void DeviceGetFormatsInUse(int device_id,
94 media::VideoCaptureSessionId session_id) {
95 OnDeviceFormatsInUseReceived(media::VideoCaptureFormats());
99 VideoCaptureImplTest() {
100 params_small_.requested_format = media::VideoCaptureFormat(
101 gfx::Size(176, 144), 30, media::PIXEL_FORMAT_I420);
103 params_large_.requested_format = media::VideoCaptureFormat(
104 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);
106 child_process_.reset(new ChildProcess());
108 message_filter_ = new MockVideoCaptureMessageFilter;
111 video_capture_impl_ = new MockVideoCaptureImpl(
112 session_id_, message_filter_.get());
114 video_capture_impl_->device_id_ = 2;
117 virtual ~VideoCaptureImplTest() {
118 delete video_capture_impl_;
122 base::MessageLoop message_loop_;
123 base::RunLoop run_loop_;
124 scoped_ptr<ChildProcess> child_process_;
125 scoped_refptr<MockVideoCaptureMessageFilter> message_filter_;
126 media::VideoCaptureSessionId session_id_;
127 MockVideoCaptureImpl* video_capture_impl_;
128 media::VideoCaptureParams params_small_;
129 media::VideoCaptureParams params_large_;
132 DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplTest);
135 TEST_F(VideoCaptureImplTest, Simple) {
136 // Execute SetCapture() and StopCapture() for one client.
137 scoped_ptr<MockVideoCaptureEventHandler> client(
138 new MockVideoCaptureEventHandler);
140 EXPECT_CALL(*client, OnStarted(_));
141 EXPECT_CALL(*client, OnStopped(_));
142 EXPECT_CALL(*client, OnRemoved(_));
144 video_capture_impl_->StartCapture(client.get(), params_small_);
145 video_capture_impl_->StopCapture(client.get());
146 video_capture_impl_->DeInit(
147 media::BindToCurrentLoop(run_loop_.QuitClosure()));
151 TEST_F(VideoCaptureImplTest, TwoClientsInSequence) {
152 // Execute SetCapture() and StopCapture() for 2 clients in sequence.
153 scoped_ptr<MockVideoCaptureEventHandler> client1(
154 new MockVideoCaptureEventHandler);
155 scoped_ptr<MockVideoCaptureEventHandler> client2(
156 new MockVideoCaptureEventHandler);
158 EXPECT_CALL(*client1, OnStarted(_));
159 EXPECT_CALL(*client1, OnStopped(_));
160 EXPECT_CALL(*client1, OnRemoved(_));
161 EXPECT_CALL(*client2, OnStarted(_));
162 EXPECT_CALL(*client2, OnStopped(_));
163 EXPECT_CALL(*client2, OnRemoved(_));
165 video_capture_impl_->StartCapture(client1.get(), params_small_);
166 video_capture_impl_->StopCapture(client1.get());
167 video_capture_impl_->StartCapture(client2.get(), params_small_);
168 video_capture_impl_->StopCapture(client2.get());
169 video_capture_impl_->DeInit(
170 media::BindToCurrentLoop(run_loop_.QuitClosure()));
174 TEST_F(VideoCaptureImplTest, LargeAndSmall) {
175 // Execute SetCapture() and StopCapture() for 2 clients simultaneously.
176 // The large client starts first and stops first.
177 scoped_ptr<MockVideoCaptureEventHandler> client_small(
178 new MockVideoCaptureEventHandler);
179 scoped_ptr<MockVideoCaptureEventHandler> client_large(
180 new MockVideoCaptureEventHandler);
182 EXPECT_CALL(*client_large, OnStarted(_));
183 EXPECT_CALL(*client_small, OnStarted(_));
184 EXPECT_CALL(*client_large, OnStopped(_));
185 EXPECT_CALL(*client_large, OnRemoved(_));
186 EXPECT_CALL(*client_small, OnStopped(_));
187 EXPECT_CALL(*client_small, OnRemoved(_));
189 video_capture_impl_->StartCapture(client_large.get(), params_large_);
190 video_capture_impl_->StartCapture(client_small.get(), params_small_);
191 video_capture_impl_->StopCapture(client_large.get());
192 video_capture_impl_->StopCapture(client_small.get());
193 video_capture_impl_->DeInit(
194 media::BindToCurrentLoop(run_loop_.QuitClosure()));
198 TEST_F(VideoCaptureImplTest, SmallAndLarge) {
199 // Execute SetCapture() and StopCapture() for 2 clients simultaneously.
200 // The small client starts first and stops first.
201 scoped_ptr<MockVideoCaptureEventHandler> client_small(
202 new MockVideoCaptureEventHandler);
203 scoped_ptr<MockVideoCaptureEventHandler> client_large(
204 new MockVideoCaptureEventHandler);
206 EXPECT_CALL(*client_small, OnStarted(_));
207 EXPECT_CALL(*client_large, OnStarted(_));
208 EXPECT_CALL(*client_small, OnStopped(_));
209 EXPECT_CALL(*client_small, OnRemoved(_));
210 EXPECT_CALL(*client_large, OnStopped(_));
211 EXPECT_CALL(*client_large, OnRemoved(_));
213 video_capture_impl_->StartCapture(client_small.get(), params_small_);
214 video_capture_impl_->StartCapture(client_large.get(), params_large_);
215 video_capture_impl_->StopCapture(client_small.get());
216 video_capture_impl_->StopCapture(client_large.get());
217 video_capture_impl_->DeInit(
218 media::BindToCurrentLoop(run_loop_.QuitClosure()));
222 // Check that a request to GetDeviceSupportedFormats() ends up eventually in the
223 // provided callback.
224 TEST_F(VideoCaptureImplTest, GetDeviceFormats) {
225 scoped_ptr<MockVideoCaptureEventHandler> client(
226 new MockVideoCaptureEventHandler);
228 EXPECT_CALL(*client, OnDeviceSupportedFormatsEnumerated(_));
230 const base::Callback<void(const media::VideoCaptureFormats&)>
231 callback = base::Bind(
232 &MockVideoCaptureEventHandler::OnDeviceSupportedFormatsEnumerated,
233 base::Unretained(client.get()));
234 video_capture_impl_->GetDeviceSupportedFormats(callback);
235 video_capture_impl_->DeInit(
236 media::BindToCurrentLoop(run_loop_.QuitClosure()));
240 // Check that two requests to GetDeviceSupportedFormats() end up eventually
241 // calling the provided callbacks.
242 TEST_F(VideoCaptureImplTest, TwoClientsGetDeviceFormats) {
243 scoped_ptr<MockVideoCaptureEventHandler> client1(
244 new MockVideoCaptureEventHandler);
245 scoped_ptr<MockVideoCaptureEventHandler> client2(
246 new MockVideoCaptureEventHandler);
248 EXPECT_CALL(*client1, OnDeviceSupportedFormatsEnumerated(_));
249 EXPECT_CALL(*client2, OnDeviceSupportedFormatsEnumerated(_));
251 const base::Callback<void(const media::VideoCaptureFormats&)>
252 callback1 = base::Bind(
253 &MockVideoCaptureEventHandler::OnDeviceSupportedFormatsEnumerated,
254 base::Unretained(client1.get()));
255 const base::Callback<void(const media::VideoCaptureFormats&)>
256 callback2 = base::Bind(
257 &MockVideoCaptureEventHandler::OnDeviceSupportedFormatsEnumerated,
258 base::Unretained(client2.get()));
260 video_capture_impl_->GetDeviceSupportedFormats(callback1);
261 video_capture_impl_->GetDeviceSupportedFormats(callback2);
262 video_capture_impl_->DeInit(
263 media::BindToCurrentLoop(run_loop_.QuitClosure()));
267 // Check that a request to GetDeviceFormatsInUse() ends up eventually in the
268 // provided callback.
269 TEST_F(VideoCaptureImplTest, GetDeviceFormatsInUse) {
270 scoped_ptr<MockVideoCaptureEventHandler> client(
271 new MockVideoCaptureEventHandler);
273 media::VideoCaptureFormats formats_in_use;
274 EXPECT_CALL(*client, OnDeviceFormatsInUseReceived(_))
275 .WillOnce(SaveArg<0>(&formats_in_use));
277 const base::Callback<void(const media::VideoCaptureFormats&)> callback =
278 base::Bind(&MockVideoCaptureEventHandler::OnDeviceFormatsInUseReceived,
279 base::Unretained(client.get()));
280 video_capture_impl_->GetDeviceFormatsInUse(callback);
281 video_capture_impl_->DeInit(
282 media::BindToCurrentLoop(run_loop_.QuitClosure()));
285 EXPECT_TRUE(formats_in_use.empty());
288 } // namespace content