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 #include "base/message_loop/message_loop.h" 6 #include "content/child/child_process.h" 7 #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 12 using ::testing::_; 13 using ::testing::AtLeast; 14 using ::testing::Return; 15 16 namespace content { 17 18 class 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 32 class 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 54 class 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) 61 : VideoCaptureImpl(id, ml_proxy.get(), filter) {} 62 virtual ~MockVideoCaptureImpl() {} 63 64 // Override Send() to mimic device to send events. 65 virtual void Send(IPC::Message* message) OVERRIDE { 66 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 99 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) { 114 message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO)); 115 message_loop_proxy_ = base::MessageLoopProxy::current().get(); 116 child_process_.reset(new ChildProcess()); 117 118 message_filter_ = new MockVideoCaptureMessageFilter; 119 session_id_ = 1; 120 121 video_capture_impl_ = new MockVideoCaptureImpl( 122 session_id_, message_loop_proxy_, message_filter_.get()); 123 124 video_capture_impl_->device_id_ = 2; 125 } 126 127 virtual ~VideoCaptureImplTest() { 128 delete video_capture_impl_; 129 } 130 131 protected: 132 scoped_ptr<base::MessageLoop> message_loop_; 133 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_; 138 const media::VideoCaptureCapability capability_small_; 139 const media::VideoCaptureCapability capability_large_; 140 141 private: 142 DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplTest); 143 }; 144 145 TEST_F(VideoCaptureImplTest, Simple) { 146 // Execute SetCapture() and StopCapture() for one client. 147 scoped_ptr<MockVideoCaptureClient> client(new MockVideoCaptureClient); 148 149 EXPECT_CALL(*client, OnStarted(_)) 150 .WillOnce(Return()); 151 EXPECT_CALL(*client, OnDeviceInfoReceived(_,_)) 152 .WillOnce(Return()); 153 154 video_capture_impl_->StartCapture(client.get(), capability_small_); 155 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 166 TEST_F(VideoCaptureImplTest, TwoClientsInSequence) { 167 // Execute SetCapture() and StopCapture() for 2 clients in sequence. 168 scoped_ptr<MockVideoCaptureClient> client(new MockVideoCaptureClient); 169 170 EXPECT_CALL(*client, OnStarted(_)) 171 .WillOnce(Return()); 172 EXPECT_CALL(*client, OnDeviceInfoReceived(_,_)) 173 .WillOnce(Return()); 174 175 video_capture_impl_->StartCapture(client.get(), capability_small_); 176 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 191 video_capture_impl_->StartCapture(client.get(), capability_small_); 192 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 203 TEST_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); 208 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 218 video_capture_impl_->StartCapture(client_large.get(), capability_large_); 219 video_capture_impl_->StartCapture(client_small.get(), capability_small_); 220 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 236 TEST_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); 241 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 252 video_capture_impl_->StartCapture(client_small.get(), capability_small_); 253 video_capture_impl_->StartCapture(client_large.get(), capability_large_); 254 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 270 TEST_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); 275 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 285 video_capture_impl_->StartCapture(client1.get(), capability_small_); 286 video_capture_impl_->StartCapture(client2.get(), capability_small_); 287 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 304