blob: 7d347e5da89017c0c8f69bcdae4a2b7c283eb61c [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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
Ben Murdoch9ab55632013-07-18 11:57:30 +01005#include "base/message_loop/message_loop.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01006#include "content/child/child_process.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007#include "content/common/media/video_capture_messages.h"
8#include "content/renderer/media/video_capture_impl.h"
9#include "testing/gmock/include/gmock/gmock.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12using ::testing::_;
13using ::testing::AtLeast;
14using ::testing::Return;
15
Torne (Richard Coles)58218062012-11-14 11:43:16 +000016namespace content {
17
18class MockVideoCaptureMessageFilter : public VideoCaptureMessageFilter {
19 public:
20 MockVideoCaptureMessageFilter() : VideoCaptureMessageFilter() {}
21
22 // Filter implementation.
23 MOCK_METHOD1(Send, bool(IPC::Message* message));
24
25 protected:
26 virtual ~MockVideoCaptureMessageFilter() {}
27
28 private:
29 DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureMessageFilter);
30};
31
32class MockVideoCaptureClient : public media::VideoCapture::EventHandler {
33 public:
34 MockVideoCaptureClient() {}
35 virtual ~MockVideoCaptureClient() {}
36
37 // EventHandler implementation.
38 MOCK_METHOD1(OnStarted, void(media::VideoCapture* capture));
39 MOCK_METHOD1(OnStopped, void(media::VideoCapture* capture));
40 MOCK_METHOD1(OnPaused, void(media::VideoCapture* capture));
41 MOCK_METHOD2(OnError, void(media::VideoCapture* capture, int error_code));
42 MOCK_METHOD1(OnRemoved, void(media::VideoCapture* capture));
43 MOCK_METHOD2(OnBufferReady,
44 void(media::VideoCapture* capture,
45 scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf));
46 MOCK_METHOD2(OnDeviceInfoReceived,
47 void(media::VideoCapture* capture,
48 const media::VideoCaptureParams& device_info));
49
50 private:
51 DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureClient);
52};
53
54class VideoCaptureImplTest : public ::testing::Test {
55 public:
56 class MockVideoCaptureImpl : public VideoCaptureImpl {
57 public:
58 MockVideoCaptureImpl(const media::VideoCaptureSessionId id,
59 scoped_refptr<base::MessageLoopProxy> ml_proxy,
60 VideoCaptureMessageFilter* filter)
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010061 : VideoCaptureImpl(id, ml_proxy.get(), filter) {}
Torne (Richard Coles)58218062012-11-14 11:43:16 +000062 virtual ~MockVideoCaptureImpl() {}
63
64 // Override Send() to mimic device to send events.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000065 virtual void Send(IPC::Message* message) OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000066 CHECK(message);
67
68 // In this method, messages are sent to the according handlers as if
69 // we are the device.
70 bool handled = true;
71 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureImpl, *message)
72 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, DeviceStartCapture)
73 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, DevicePauseCapture)
74 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, DeviceStopCapture)
75 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady,
76 DeviceReceiveEmptyBuffer)
77 IPC_MESSAGE_UNHANDLED(handled = false)
78 IPC_END_MESSAGE_MAP()
79 EXPECT_TRUE(handled);
80 delete message;
81 }
82
83 void DeviceStartCapture(int device_id,
84 const media::VideoCaptureParams& params) {
85 media::VideoCaptureParams device_info = params;
86 OnDeviceInfoReceived(device_info);
87 OnStateChanged(VIDEO_CAPTURE_STATE_STARTED);
88 }
89
90 void DevicePauseCapture(int device_id) {}
91
92 void DeviceStopCapture(int device_id) {
93 OnStateChanged(VIDEO_CAPTURE_STATE_STOPPED);
94 }
95
96 void DeviceReceiveEmptyBuffer(int device_id, int buffer_id) {}
97 };
98
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010099 VideoCaptureImplTest()
100 : capability_small_(176,
101 144,
102 30,
103 media::VideoCaptureCapability::kI420,
104 0,
105 false,
106 media::ConstantResolutionVideoCaptureDevice),
107 capability_large_(320,
108 240,
109 30,
110 media::VideoCaptureCapability::kI420,
111 0,
112 false,
113 media::ConstantResolutionVideoCaptureDevice) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100114 message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100115 message_loop_proxy_ = base::MessageLoopProxy::current().get();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000116 child_process_.reset(new ChildProcess());
117
118 message_filter_ = new MockVideoCaptureMessageFilter;
119 session_id_ = 1;
120
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100121 video_capture_impl_ = new MockVideoCaptureImpl(
122 session_id_, message_loop_proxy_, message_filter_.get());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000123
124 video_capture_impl_->device_id_ = 2;
125 }
126
127 virtual ~VideoCaptureImplTest() {
128 delete video_capture_impl_;
129 }
130
131 protected:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100132 scoped_ptr<base::MessageLoop> message_loop_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000133 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
134 scoped_ptr<ChildProcess> child_process_;
135 scoped_refptr<MockVideoCaptureMessageFilter> message_filter_;
136 media::VideoCaptureSessionId session_id_;
137 MockVideoCaptureImpl* video_capture_impl_;
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100138 const media::VideoCaptureCapability capability_small_;
139 const media::VideoCaptureCapability capability_large_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000140
141 private:
142 DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplTest);
143};
144
145TEST_F(VideoCaptureImplTest, Simple) {
146 // Execute SetCapture() and StopCapture() for one client.
147 scoped_ptr<MockVideoCaptureClient> client(new MockVideoCaptureClient);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000148
149 EXPECT_CALL(*client, OnStarted(_))
150 .WillOnce(Return());
151 EXPECT_CALL(*client, OnDeviceInfoReceived(_,_))
152 .WillOnce(Return());
153
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100154 video_capture_impl_->StartCapture(client.get(), capability_small_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000155 message_loop_->RunUntilIdle();
156
157 EXPECT_CALL(*client, OnStopped(_))
158 .WillOnce(Return());
159 EXPECT_CALL(*client, OnRemoved(_))
160 .WillOnce(Return());
161
162 video_capture_impl_->StopCapture(client.get());
163 message_loop_->RunUntilIdle();
164}
165
166TEST_F(VideoCaptureImplTest, TwoClientsInSequence) {
167 // Execute SetCapture() and StopCapture() for 2 clients in sequence.
168 scoped_ptr<MockVideoCaptureClient> client(new MockVideoCaptureClient);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000169
170 EXPECT_CALL(*client, OnStarted(_))
171 .WillOnce(Return());
172 EXPECT_CALL(*client, OnDeviceInfoReceived(_,_))
173 .WillOnce(Return());
174
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100175 video_capture_impl_->StartCapture(client.get(), capability_small_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000176 message_loop_->RunUntilIdle();
177
178 EXPECT_CALL(*client, OnStopped(_))
179 .WillOnce(Return());
180 EXPECT_CALL(*client, OnRemoved(_))
181 .WillOnce(Return());
182
183 video_capture_impl_->StopCapture(client.get());
184 message_loop_->RunUntilIdle();
185
186 EXPECT_CALL(*client, OnStarted(_))
187 .WillOnce(Return());
188 EXPECT_CALL(*client, OnDeviceInfoReceived(_,_))
189 .WillOnce(Return());
190
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100191 video_capture_impl_->StartCapture(client.get(), capability_small_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000192 message_loop_->RunUntilIdle();
193
194 EXPECT_CALL(*client, OnStopped(_))
195 .WillOnce(Return());
196 EXPECT_CALL(*client, OnRemoved(_))
197 .WillOnce(Return());
198
199 video_capture_impl_->StopCapture(client.get());
200 message_loop_->RunUntilIdle();
201}
202
203TEST_F(VideoCaptureImplTest, LargeAndSmall) {
204 // Execute SetCapture() and StopCapture() for 2 clients simultaneously.
205 // The large client starts first and stops first.
206 scoped_ptr<MockVideoCaptureClient> client_small(new MockVideoCaptureClient);
207 scoped_ptr<MockVideoCaptureClient> client_large(new MockVideoCaptureClient);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000208
209 EXPECT_CALL(*client_large, OnStarted(_))
210 .WillOnce(Return());
211 EXPECT_CALL(*client_large, OnDeviceInfoReceived(_,_))
212 .WillOnce(Return());
213 EXPECT_CALL(*client_small, OnStarted(_))
214 .WillOnce(Return());
215 EXPECT_CALL(*client_small, OnDeviceInfoReceived(_,_))
216 .WillOnce(Return());
217
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100218 video_capture_impl_->StartCapture(client_large.get(), capability_large_);
219 video_capture_impl_->StartCapture(client_small.get(), capability_small_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000220 message_loop_->RunUntilIdle();
221
222 EXPECT_CALL(*client_large, OnStopped(_))
223 .WillOnce(Return());
224 EXPECT_CALL(*client_large, OnRemoved(_))
225 .WillOnce(Return());
226 EXPECT_CALL(*client_small, OnStopped(_))
227 .WillOnce(Return());
228 EXPECT_CALL(*client_small, OnRemoved(_))
229 .WillOnce(Return());
230
231 video_capture_impl_->StopCapture(client_large.get());
232 video_capture_impl_->StopCapture(client_small.get());
233 message_loop_->RunUntilIdle();
234}
235
236TEST_F(VideoCaptureImplTest, SmallAndLarge) {
237 // Execute SetCapture() and StopCapture() for 2 clients simultaneously.
238 // The small client starts first and stops first.
239 scoped_ptr<MockVideoCaptureClient> client_small(new MockVideoCaptureClient);
240 scoped_ptr<MockVideoCaptureClient> client_large(new MockVideoCaptureClient);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000241
242 EXPECT_CALL(*client_large, OnStarted(_))
243 .WillOnce(Return());
244 EXPECT_CALL(*client_large, OnDeviceInfoReceived(_,_))
245 .WillOnce(Return());
246 EXPECT_CALL(*client_small, OnStarted(_))
247 .WillOnce(Return());
248 EXPECT_CALL(*client_small, OnDeviceInfoReceived(_,_))
249 .Times(AtLeast(1))
250 .WillRepeatedly(Return());
251
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100252 video_capture_impl_->StartCapture(client_small.get(), capability_small_);
253 video_capture_impl_->StartCapture(client_large.get(), capability_large_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000254 message_loop_->RunUntilIdle();
255
256 EXPECT_CALL(*client_large, OnStopped(_))
257 .WillOnce(Return());
258 EXPECT_CALL(*client_large, OnRemoved(_))
259 .WillOnce(Return());
260 EXPECT_CALL(*client_small, OnStopped(_))
261 .WillOnce(Return());
262 EXPECT_CALL(*client_small, OnRemoved(_))
263 .WillOnce(Return());
264
265 video_capture_impl_->StopCapture(client_small.get());
266 video_capture_impl_->StopCapture(client_large.get());
267 message_loop_->RunUntilIdle();
268}
269
270TEST_F(VideoCaptureImplTest, TwoClientsWithSameSize) {
271 // Execute SetCapture() and StopCapture() for 2 clients simultaneously.
272 // The client1 starts first and stops first.
273 scoped_ptr<MockVideoCaptureClient> client1(new MockVideoCaptureClient);
274 scoped_ptr<MockVideoCaptureClient> client2(new MockVideoCaptureClient);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000275
276 EXPECT_CALL(*client1, OnStarted(_))
277 .WillOnce(Return());
278 EXPECT_CALL(*client1, OnDeviceInfoReceived(_,_))
279 .WillOnce(Return());
280 EXPECT_CALL(*client2, OnStarted(_))
281 .WillOnce(Return());
282 EXPECT_CALL(*client2, OnDeviceInfoReceived(_,_))
283 .WillOnce(Return());
284
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100285 video_capture_impl_->StartCapture(client1.get(), capability_small_);
286 video_capture_impl_->StartCapture(client2.get(), capability_small_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000287 message_loop_->RunUntilIdle();
288
289 EXPECT_CALL(*client1, OnStopped(_))
290 .WillOnce(Return());
291 EXPECT_CALL(*client1, OnRemoved(_))
292 .WillOnce(Return());
293 EXPECT_CALL(*client2, OnStopped(_))
294 .WillOnce(Return());
295 EXPECT_CALL(*client2, OnRemoved(_))
296 .WillOnce(Return());
297
298 video_capture_impl_->StopCapture(client1.get());
299 video_capture_impl_->StopCapture(client2.get());
300 message_loop_->RunUntilIdle();
301}
302
303} // namespace content