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(OnFrameReady, 44 void(media::VideoCapture* capture, 45 const scoped_refptr<media::VideoFrame>& frame)); 46 MOCK_METHOD2(OnDeviceInfoReceived, 47 void(media::VideoCapture* capture, 48 const media::VideoCaptureFormat& 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 media::VideoCaptureSessionId session_id, 85 const media::VideoCaptureParams& params) { 86 OnStateChanged(VIDEO_CAPTURE_STATE_STARTED); 87 } 88 89 void DevicePauseCapture(int device_id) {} 90 91 void DeviceStopCapture(int device_id) { 92 OnStateChanged(VIDEO_CAPTURE_STATE_STOPPED); 93 } 94 95 void DeviceReceiveEmptyBuffer(int device_id, int buffer_id) {} 96 }; 97 98 VideoCaptureImplTest() { 99 params_small_.requested_format = media::VideoCaptureFormat( 100 gfx::Size(176, 144), 30, media::PIXEL_FORMAT_I420); 101 102 params_large_.requested_format = media::VideoCaptureFormat( 103 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); 104 105 message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO)); 106 message_loop_proxy_ = base::MessageLoopProxy::current().get(); 107 child_process_.reset(new ChildProcess()); 108 109 message_filter_ = new MockVideoCaptureMessageFilter; 110 session_id_ = 1; 111 112 video_capture_impl_ = new MockVideoCaptureImpl( 113 session_id_, message_loop_proxy_, message_filter_.get()); 114 115 video_capture_impl_->device_id_ = 2; 116 } 117 118 virtual ~VideoCaptureImplTest() { 119 delete video_capture_impl_; 120 } 121 122 protected: 123 scoped_ptr<base::MessageLoop> message_loop_; 124 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; 125 scoped_ptr<ChildProcess> child_process_; 126 scoped_refptr<MockVideoCaptureMessageFilter> message_filter_; 127 media::VideoCaptureSessionId session_id_; 128 MockVideoCaptureImpl* video_capture_impl_; 129 media::VideoCaptureParams params_small_; 130 media::VideoCaptureParams params_large_; 131 132 private: 133 DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplTest); 134 }; 135 136 TEST_F(VideoCaptureImplTest, Simple) { 137 // Execute SetCapture() and StopCapture() for one client. 138 scoped_ptr<MockVideoCaptureClient> client(new MockVideoCaptureClient); 139 140 EXPECT_CALL(*client, OnStarted(_)) 141 .WillOnce(Return()); 142 143 video_capture_impl_->StartCapture(client.get(), params_small_); 144 message_loop_->RunUntilIdle(); 145 146 EXPECT_CALL(*client, OnStopped(_)) 147 .WillOnce(Return()); 148 EXPECT_CALL(*client, OnRemoved(_)) 149 .WillOnce(Return()); 150 151 video_capture_impl_->StopCapture(client.get()); 152 message_loop_->RunUntilIdle(); 153 } 154 155 TEST_F(VideoCaptureImplTest, TwoClientsInSequence) { 156 // Execute SetCapture() and StopCapture() for 2 clients in sequence. 157 scoped_ptr<MockVideoCaptureClient> client(new MockVideoCaptureClient); 158 159 EXPECT_CALL(*client, OnStarted(_)) 160 .WillOnce(Return()); 161 162 video_capture_impl_->StartCapture(client.get(), params_small_); 163 message_loop_->RunUntilIdle(); 164 165 EXPECT_CALL(*client, OnStopped(_)) 166 .WillOnce(Return()); 167 EXPECT_CALL(*client, OnRemoved(_)) 168 .WillOnce(Return()); 169 170 video_capture_impl_->StopCapture(client.get()); 171 message_loop_->RunUntilIdle(); 172 173 EXPECT_CALL(*client, OnStarted(_)) 174 .WillOnce(Return()); 175 176 video_capture_impl_->StartCapture(client.get(), params_small_); 177 message_loop_->RunUntilIdle(); 178 179 EXPECT_CALL(*client, OnStopped(_)) 180 .WillOnce(Return()); 181 EXPECT_CALL(*client, OnRemoved(_)) 182 .WillOnce(Return()); 183 184 video_capture_impl_->StopCapture(client.get()); 185 message_loop_->RunUntilIdle(); 186 } 187 188 TEST_F(VideoCaptureImplTest, LargeAndSmall) { 189 // Execute SetCapture() and StopCapture() for 2 clients simultaneously. 190 // The large client starts first and stops first. 191 scoped_ptr<MockVideoCaptureClient> client_small(new MockVideoCaptureClient); 192 scoped_ptr<MockVideoCaptureClient> client_large(new MockVideoCaptureClient); 193 194 EXPECT_CALL(*client_large, OnStarted(_)) 195 .WillOnce(Return()); 196 EXPECT_CALL(*client_small, OnStarted(_)) 197 .WillOnce(Return()); 198 199 video_capture_impl_->StartCapture(client_large.get(), params_large_); 200 video_capture_impl_->StartCapture(client_small.get(), params_small_); 201 message_loop_->RunUntilIdle(); 202 203 EXPECT_CALL(*client_large, OnStopped(_)) 204 .WillOnce(Return()); 205 EXPECT_CALL(*client_large, OnRemoved(_)) 206 .WillOnce(Return()); 207 EXPECT_CALL(*client_small, OnStopped(_)) 208 .WillOnce(Return()); 209 EXPECT_CALL(*client_small, OnRemoved(_)) 210 .WillOnce(Return()); 211 212 video_capture_impl_->StopCapture(client_large.get()); 213 video_capture_impl_->StopCapture(client_small.get()); 214 message_loop_->RunUntilIdle(); 215 } 216 217 TEST_F(VideoCaptureImplTest, SmallAndLarge) { 218 // Execute SetCapture() and StopCapture() for 2 clients simultaneously. 219 // The small client starts first and stops first. 220 scoped_ptr<MockVideoCaptureClient> client_small(new MockVideoCaptureClient); 221 scoped_ptr<MockVideoCaptureClient> client_large(new MockVideoCaptureClient); 222 223 EXPECT_CALL(*client_large, OnStarted(_)) 224 .WillOnce(Return()); 225 EXPECT_CALL(*client_small, OnStarted(_)) 226 .WillOnce(Return()); 227 228 video_capture_impl_->StartCapture(client_small.get(), params_small_); 229 video_capture_impl_->StartCapture(client_large.get(), params_large_); 230 message_loop_->RunUntilIdle(); 231 232 EXPECT_CALL(*client_large, OnStopped(_)) 233 .WillOnce(Return()); 234 EXPECT_CALL(*client_large, OnRemoved(_)) 235 .WillOnce(Return()); 236 EXPECT_CALL(*client_small, OnStopped(_)) 237 .WillOnce(Return()); 238 EXPECT_CALL(*client_small, OnRemoved(_)) 239 .WillOnce(Return()); 240 241 video_capture_impl_->StopCapture(client_small.get()); 242 video_capture_impl_->StopCapture(client_large.get()); 243 message_loop_->RunUntilIdle(); 244 } 245 246 TEST_F(VideoCaptureImplTest, TwoClientsWithSameSize) { 247 // Execute SetCapture() and StopCapture() for 2 clients simultaneously. 248 // The client1 starts first and stops first. 249 scoped_ptr<MockVideoCaptureClient> client1(new MockVideoCaptureClient); 250 scoped_ptr<MockVideoCaptureClient> client2(new MockVideoCaptureClient); 251 252 EXPECT_CALL(*client1, OnStarted(_)) 253 .WillOnce(Return()); 254 EXPECT_CALL(*client2, OnStarted(_)) 255 .WillOnce(Return()); 256 257 video_capture_impl_->StartCapture(client1.get(), params_small_); 258 video_capture_impl_->StartCapture(client2.get(), params_small_); 259 message_loop_->RunUntilIdle(); 260 261 EXPECT_CALL(*client1, OnStopped(_)) 262 .WillOnce(Return()); 263 EXPECT_CALL(*client1, OnRemoved(_)) 264 .WillOnce(Return()); 265 EXPECT_CALL(*client2, OnStopped(_)) 266 .WillOnce(Return()); 267 EXPECT_CALL(*client2, OnRemoved(_)) 268 .WillOnce(Return()); 269 270 video_capture_impl_->StopCapture(client1.get()); 271 video_capture_impl_->StopCapture(client2.get()); 272 message_loop_->RunUntilIdle(); 273 } 274 275 } // namespace content 276