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 "media/base/bind_to_current_loop.h" 10#include "testing/gmock/include/gmock/gmock.h" 11#include "testing/gtest/include/gtest/gtest.h" 12 13using ::testing::_; 14using ::testing::AtLeast; 15using ::testing::InvokeWithoutArgs; 16using ::testing::Return; 17using ::testing::SaveArg; 18 19namespace content { 20 21class MockVideoCaptureMessageFilter : public VideoCaptureMessageFilter { 22 public: 23 MockVideoCaptureMessageFilter() : VideoCaptureMessageFilter() {} 24 25 // Filter implementation. 26 MOCK_METHOD1(Send, bool(IPC::Message* message)); 27 28 protected: 29 virtual ~MockVideoCaptureMessageFilter() {} 30 31 private: 32 DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureMessageFilter); 33}; 34 35class VideoCaptureImplTest : public ::testing::Test { 36 public: 37 class MockVideoCaptureImpl : public VideoCaptureImpl { 38 public: 39 MockVideoCaptureImpl(const media::VideoCaptureSessionId id, 40 VideoCaptureMessageFilter* filter) 41 : VideoCaptureImpl(id, filter) { 42 } 43 virtual ~MockVideoCaptureImpl() {} 44 45 // Override Send() to mimic device to send events. 46 virtual void Send(IPC::Message* message) OVERRIDE { 47 CHECK(message); 48 49 // In this method, messages are sent to the according handlers as if 50 // we are the device. 51 bool handled = true; 52 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureImpl, *message) 53 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, DeviceStartCapture) 54 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, DevicePauseCapture) 55 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, DeviceStopCapture) 56 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady, 57 DeviceReceiveEmptyBuffer) 58 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceSupportedFormats, 59 DeviceGetSupportedFormats) 60 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceFormatsInUse, 61 DeviceGetFormatsInUse) 62 IPC_MESSAGE_UNHANDLED(handled = false) 63 IPC_END_MESSAGE_MAP() 64 EXPECT_TRUE(handled); 65 delete message; 66 } 67 68 void DeviceStartCapture(int device_id, 69 media::VideoCaptureSessionId session_id, 70 const media::VideoCaptureParams& params) { 71 OnStateChanged(VIDEO_CAPTURE_STATE_STARTED); 72 capture_params_ = params; 73 } 74 75 void DevicePauseCapture(int device_id) {} 76 77 void DeviceStopCapture(int device_id) { 78 OnStateChanged(VIDEO_CAPTURE_STATE_STOPPED); 79 } 80 81 void DeviceReceiveEmptyBuffer(int device_id, 82 int buffer_id, 83 const std::vector<uint32>& sync_points) {} 84 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()); 91 } 92 93 void DeviceGetFormatsInUse(int device_id, 94 media::VideoCaptureSessionId session_id) { 95 OnDeviceFormatsInUseReceived(media::VideoCaptureFormats()); 96 } 97 98 void ReceiveStateChangeMessage(VideoCaptureState state) { 99 OnStateChanged(state); 100 } 101 102 const media::VideoCaptureParams& capture_params() const { 103 return capture_params_; 104 } 105 106 private: 107 media::VideoCaptureParams capture_params_; 108 }; 109 110 VideoCaptureImplTest() { 111 params_small_.requested_format = media::VideoCaptureFormat( 112 gfx::Size(176, 144), 30, media::PIXEL_FORMAT_I420); 113 114 params_large_.requested_format = media::VideoCaptureFormat( 115 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); 116 117 child_process_.reset(new ChildProcess()); 118 119 message_filter_ = new MockVideoCaptureMessageFilter; 120 session_id_ = 1; 121 122 video_capture_impl_.reset(new MockVideoCaptureImpl( 123 session_id_, message_filter_.get())); 124 125 video_capture_impl_->device_id_ = 2; 126 } 127 128 virtual ~VideoCaptureImplTest() { 129 } 130 131 protected: 132 MOCK_METHOD3(OnFrameReady, 133 void(const scoped_refptr<media::VideoFrame>&, 134 const media::VideoCaptureFormat&, 135 const base::TimeTicks&)); 136 MOCK_METHOD1(OnStateUpdate, void(VideoCaptureState)); 137 MOCK_METHOD1(OnDeviceFormatsInUse, 138 void(const media::VideoCaptureFormats&)); 139 MOCK_METHOD1(OnDeviceSupportedFormats, 140 void(const media::VideoCaptureFormats&)); 141 142 void Init() { 143 video_capture_impl_->Init(); 144 } 145 146 void StartCapture(int client_id, 147 const media::VideoCaptureParams& params) { 148 video_capture_impl_->StartCapture( 149 client_id, params, 150 base::Bind(&VideoCaptureImplTest::OnStateUpdate, 151 base::Unretained(this)), 152 base::Bind(&VideoCaptureImplTest::OnFrameReady, 153 base::Unretained(this))); 154 } 155 156 void StopCapture(int client_id) { 157 video_capture_impl_->StopCapture(client_id); 158 } 159 160 void DeInit() { 161 video_capture_impl_->DeInit(); 162 } 163 164 void GetDeviceSupportedFormats() { 165 const base::Callback<void(const media::VideoCaptureFormats&)> 166 callback = base::Bind( 167 &VideoCaptureImplTest::OnDeviceSupportedFormats, 168 base::Unretained(this)); 169 video_capture_impl_->GetDeviceSupportedFormats(callback); 170 } 171 172 void GetDeviceFormatsInUse() { 173 const base::Callback<void(const media::VideoCaptureFormats&)> 174 callback = base::Bind( 175 &VideoCaptureImplTest::OnDeviceFormatsInUse, 176 base::Unretained(this)); 177 video_capture_impl_->GetDeviceFormatsInUse(callback); 178 } 179 180 base::MessageLoop message_loop_; 181 scoped_ptr<ChildProcess> child_process_; 182 scoped_refptr<MockVideoCaptureMessageFilter> message_filter_; 183 media::VideoCaptureSessionId session_id_; 184 scoped_ptr<MockVideoCaptureImpl> video_capture_impl_; 185 media::VideoCaptureParams params_small_; 186 media::VideoCaptureParams params_large_; 187 188 private: 189 DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplTest); 190}; 191 192TEST_F(VideoCaptureImplTest, Simple) { 193 // Execute SetCapture() and StopCapture() for one client. 194 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)); 195 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)); 196 197 Init(); 198 StartCapture(0, params_small_); 199 StopCapture(0); 200 DeInit(); 201} 202 203TEST_F(VideoCaptureImplTest, TwoClientsInSequence) { 204 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)).Times(2); 205 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)).Times(2); 206 207 Init(); 208 StartCapture(0, params_small_); 209 StopCapture(0); 210 StartCapture(1, params_small_); 211 StopCapture(1); 212 DeInit(); 213} 214 215TEST_F(VideoCaptureImplTest, LargeAndSmall) { 216 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)).Times(2); 217 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)).Times(2); 218 219 Init(); 220 StartCapture(0, params_large_); 221 StopCapture(0); 222 StartCapture(1, params_small_); 223 StopCapture(1); 224 DeInit(); 225} 226 227TEST_F(VideoCaptureImplTest, SmallAndLarge) { 228 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)).Times(2); 229 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)).Times(2); 230 231 Init(); 232 StartCapture(0, params_small_); 233 StopCapture(0); 234 StartCapture(1, params_large_); 235 StopCapture(1); 236 DeInit(); 237} 238 239// Check that a request to GetDeviceSupportedFormats() ends up eventually in the 240// provided callback. 241TEST_F(VideoCaptureImplTest, GetDeviceFormats) { 242 EXPECT_CALL(*this, OnDeviceSupportedFormats(_)); 243 244 Init(); 245 GetDeviceSupportedFormats(); 246 DeInit(); 247} 248 249// Check that two requests to GetDeviceSupportedFormats() end up eventually 250// calling the provided callbacks. 251TEST_F(VideoCaptureImplTest, TwoClientsGetDeviceFormats) { 252 EXPECT_CALL(*this, OnDeviceSupportedFormats(_)).Times(2); 253 254 Init(); 255 GetDeviceSupportedFormats(); 256 GetDeviceSupportedFormats(); 257 DeInit(); 258} 259 260// Check that a request to GetDeviceFormatsInUse() ends up eventually in the 261// provided callback. 262TEST_F(VideoCaptureImplTest, GetDeviceFormatsInUse) { 263 EXPECT_CALL(*this, OnDeviceFormatsInUse(_)); 264 265 Init(); 266 GetDeviceFormatsInUse(); 267 DeInit(); 268} 269 270TEST_F(VideoCaptureImplTest, AlreadyStarted) { 271 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)).Times(2); 272 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)).Times(2); 273 274 Init(); 275 StartCapture(0, params_small_); 276 StartCapture(1, params_large_); 277 StopCapture(0); 278 StopCapture(1); 279 DeInit(); 280 DCHECK(video_capture_impl_->capture_params().requested_format 281 .frame_size == 282 params_small_.requested_format.frame_size); 283} 284 285TEST_F(VideoCaptureImplTest, EndedBeforeStop) { 286 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)); 287 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)); 288 289 Init(); 290 StartCapture(0, params_small_); 291 292 // Receive state change message from browser. 293 video_capture_impl_->ReceiveStateChangeMessage(VIDEO_CAPTURE_STATE_ENDED); 294 295 StopCapture(0); 296 DeInit(); 297} 298 299TEST_F(VideoCaptureImplTest, ErrorBeforeStop) { 300 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)); 301 EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_ERROR)); 302 303 Init(); 304 StartCapture(0, params_small_); 305 306 // Receive state change message from browser. 307 video_capture_impl_->ReceiveStateChangeMessage(VIDEO_CAPTURE_STATE_ERROR); 308 309 StopCapture(0); 310 DeInit(); 311} 312 313} // namespace content 314