Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: content/browser/renderer_host/media/video_capture_host_unittest.cc

Issue 2409893003: VideoCapture: more migration IPC-->mojo, part 5 (Closed)
Patch Set: rebase content/common/BUILD.gn Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/renderer_host/media/video_capture_host.cc ('k') | content/common/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/media/video_capture_host.h" 5 #include "content/browser/renderer_host/media/video_capture_host.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <map> 9 #include <map>
10 #include <memory> 10 #include <memory>
(...skipping 11 matching lines...) Expand all
22 #include "content/browser/browser_thread_impl.h" 22 #include "content/browser/browser_thread_impl.h"
23 #include "content/browser/renderer_host/media/media_stream_manager.h" 23 #include "content/browser/renderer_host/media/media_stream_manager.h"
24 #include "content/browser/renderer_host/media/media_stream_requester.h" 24 #include "content/browser/renderer_host/media/media_stream_requester.h"
25 #include "content/browser/renderer_host/media/video_capture_manager.h" 25 #include "content/browser/renderer_host/media/video_capture_manager.h"
26 #include "content/common/media/video_capture_messages.h" 26 #include "content/common/media/video_capture_messages.h"
27 #include "content/public/common/content_switches.h" 27 #include "content/public/common/content_switches.h"
28 #include "content/public/test/mock_resource_context.h" 28 #include "content/public/test/mock_resource_context.h"
29 #include "content/public/test/test_browser_context.h" 29 #include "content/public/test/test_browser_context.h"
30 #include "content/public/test/test_browser_thread_bundle.h" 30 #include "content/public/test/test_browser_thread_bundle.h"
31 #include "content/test/test_content_browser_client.h" 31 #include "content/test/test_content_browser_client.h"
32 #include "media/audio/audio_manager.h" 32 #include "media/audio/mock_audio_manager.h"
33 #include "media/base/media_switches.h" 33 #include "media/base/media_switches.h"
34 #include "media/base/video_capture_types.h" 34 #include "media/base/video_capture_types.h"
35 #include "net/url_request/url_request_context.h" 35 #include "net/url_request/url_request_context.h"
36 #include "testing/gmock/include/gmock/gmock.h" 36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h" 37 #include "testing/gtest/include/gtest/gtest.h"
38 38
39 #if defined(OS_CHROMEOS)
40 #include "chromeos/audio/cras_audio_handler.h"
41 #endif
42
43 using ::testing::_; 39 using ::testing::_;
44 using ::testing::AnyNumber; 40 using ::testing::AnyNumber;
45 using ::testing::DoAll; 41 using ::testing::DoAll;
46 using ::testing::InSequence; 42 using ::testing::InSequence;
47 using ::testing::Mock; 43 using ::testing::Mock;
48 using ::testing::Return; 44 using ::testing::Return;
49 using ::testing::SaveArg; 45 using ::testing::SaveArg;
50 using ::testing::StrictMock; 46 using ::testing::StrictMock;
51 47
52 namespace content { 48 namespace content {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 const StreamDeviceInfo& device_info)); 80 const StreamDeviceInfo& device_info));
85 MOCK_METHOD1(DevicesChanged, void(MediaStreamType type)); 81 MOCK_METHOD1(DevicesChanged, void(MediaStreamType type));
86 82
87 private: 83 private:
88 DISALLOW_COPY_AND_ASSIGN(MockMediaStreamRequester); 84 DISALLOW_COPY_AND_ASSIGN(MockMediaStreamRequester);
89 }; 85 };
90 86
91 class MockVideoCaptureHost : public VideoCaptureHost { 87 class MockVideoCaptureHost : public VideoCaptureHost {
92 public: 88 public:
93 MockVideoCaptureHost(MediaStreamManager* manager) 89 MockVideoCaptureHost(MediaStreamManager* manager)
94 : VideoCaptureHost(manager), return_buffers_immediately_(false) {} 90 : VideoCaptureHost(manager) {}
95 91
96 MOCK_METHOD4(OnNewBufferCreated, 92 MOCK_METHOD4(OnNewBufferCreated,
97 void(int device_id, 93 void(int device_id,
98 base::SharedMemoryHandle handle, 94 base::SharedMemoryHandle handle,
99 int length, 95 int length,
100 int buffer_id)); 96 int buffer_id));
101 MOCK_METHOD2(OnBufferFreed, void(int device_id, int buffer_id));
102 MOCK_METHOD1(OnBufferFilled, void(int device_id));
103
104 void SetReturnReceivedBuffersImmediately(bool enable) {
105 return_buffers_immediately_ = enable;
106 }
107
108 void ReturnReceivedBuffers(int device_id) {
109 while (!buffer_ids_.empty()) {
110 this->ReleaseBuffer(device_id, *buffer_ids_.begin(), gpu::SyncToken(),
111 -1.0);
112 buffer_ids_.pop_front();
113 }
114 }
115 97
116 private: 98 private:
117 ~MockVideoCaptureHost() override {} 99 ~MockVideoCaptureHost() override {}
118 100
119 // This method is used to dispatch IPC messages to the renderer. We intercept
120 // some of these messages here to MOCK them and to map/unmap buffers.
121 bool Send(IPC::Message* message) override { 101 bool Send(IPC::Message* message) override {
122 CHECK(message);
123
124 // In this method we dispatch the messages to the according handlers as if
125 // we are the renderer.
126 bool handled = true; 102 bool handled = true;
127 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureHost, *message) 103 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureHost, *message)
128 IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnNewBufferCreatedDispatch) 104 IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnNewBufferCreated)
129 IPC_MESSAGE_HANDLER(VideoCaptureMsg_FreeBuffer, OnBufferFreedDispatch)
130 IPC_MESSAGE_HANDLER(VideoCaptureMsg_BufferReady, OnBufferFilledDispatch)
131 IPC_MESSAGE_UNHANDLED(handled = false) 105 IPC_MESSAGE_UNHANDLED(handled = false)
132 IPC_END_MESSAGE_MAP() 106 IPC_END_MESSAGE_MAP()
133 EXPECT_TRUE(handled); 107 EXPECT_TRUE(handled);
134 108
135 delete message; 109 delete message;
136 return true; 110 return true;
137 } 111 }
138
139 // These handler methods do minimal things and delegate to the mock methods.
140 void OnNewBufferCreatedDispatch(int device_id,
141 base::SharedMemoryHandle handle,
142 uint32_t length,
143 int buffer_id) {
144 OnNewBufferCreated(device_id, handle, length, buffer_id);
145 buffer_ids_.push_back(buffer_id);
146 }
147
148 void OnBufferFreedDispatch(int device_id, int buffer_id) {
149 OnBufferFreed(device_id, buffer_id);
150
151 auto buffer = std::find(buffer_ids_.begin(), buffer_ids_.end(), buffer_id);
152 ASSERT_TRUE(buffer != buffer_ids_.end());
153 buffer_ids_.erase(buffer);
154 }
155
156 void OnBufferFilledDispatch(
157 const VideoCaptureMsg_BufferReady_Params& params) {
158 OnBufferFilled(params.device_id);
159 if (!return_buffers_immediately_)
160 return;
161
162 VideoCaptureHost::ReleaseBuffer(params.device_id, params.buffer_id,
163 gpu::SyncToken(), -1.0);
164 }
165
166 std::list<int> buffer_ids_;
167 bool return_buffers_immediately_;
168 }; 112 };
169 113
170 ACTION_P2(ExitMessageLoop, task_runner, quit_closure) { 114 ACTION_P2(ExitMessageLoop, task_runner, quit_closure) {
171 task_runner->PostTask(FROM_HERE, quit_closure); 115 task_runner->PostTask(FROM_HERE, quit_closure);
172 } 116 }
173 117
174 // This is an integration test of VideoCaptureHost in conjunction with 118 // This is an integration test of VideoCaptureHost in conjunction with
175 // MediaStreamManager, VideoCaptureManager, VideoCaptureController, and 119 // MediaStreamManager, VideoCaptureManager, VideoCaptureController, and
176 // VideoCaptureDevice. 120 // VideoCaptureDevice.
177 class VideoCaptureHostTest : public testing::Test, 121 class VideoCaptureHostTest : public testing::Test,
178 public mojom::VideoCaptureObserver { 122 public mojom::VideoCaptureObserver {
179 public: 123 public:
180 VideoCaptureHostTest() 124 VideoCaptureHostTest()
181 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 125 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
126 audio_manager_(
127 new media::MockAudioManager(base::ThreadTaskRunnerHandle::Get())),
182 task_runner_(base::ThreadTaskRunnerHandle::Get()), 128 task_runner_(base::ThreadTaskRunnerHandle::Get()),
183 opened_session_id_(kInvalidMediaCaptureSessionId), 129 opened_session_id_(kInvalidMediaCaptureSessionId),
184 observer_binding_(this) {} 130 observer_binding_(this) {}
185 131
186 void SetUp() override { 132 void SetUp() override {
187 SetBrowserClientForTesting(&browser_client_); 133 SetBrowserClientForTesting(&browser_client_);
188 134
189 #if defined(OS_CHROMEOS)
190 chromeos::CrasAudioHandler::InitializeForTesting();
191 #endif
192
193 audio_manager_ = media::AudioManager::CreateForTesting(task_runner_);
194 base::CommandLine::ForCurrentProcess()->AppendSwitch( 135 base::CommandLine::ForCurrentProcess()->AppendSwitch(
195 switches::kUseFakeDeviceForMediaStream); 136 switches::kUseFakeDeviceForMediaStream);
196 base::CommandLine::ForCurrentProcess()->AppendSwitch( 137 base::CommandLine::ForCurrentProcess()->AppendSwitch(
197 switches::kUseFakeUIForMediaStream); 138 switches::kUseFakeUIForMediaStream);
198 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); 139 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
199 140
200 // Create a Host and connect it to a simulated IPC channel. 141 // Create a Host and connect it to a simulated IPC channel.
201 host_ = new MockVideoCaptureHost(media_stream_manager_.get()); 142 host_ = new MockVideoCaptureHost(media_stream_manager_.get());
202 host_->OnChannelConnected(base::GetCurrentProcId()); 143 host_->OnChannelConnected(base::GetCurrentProcId());
203 144
204 OpenSession(); 145 OpenSession();
205 } 146 }
206 147
207 void TearDown() override { 148 void TearDown() override {
208 Mock::VerifyAndClearExpectations(host_.get()); 149 Mock::VerifyAndClearExpectations(host_.get());
209 EXPECT_TRUE(host_->controllers_.empty()); 150 EXPECT_TRUE(host_->controllers_.empty());
210 151
211 CloseSession(); 152 CloseSession();
212 153
213 // Simulate closing the IPC sender. 154 // Simulate closing the IPC sender.
214 host_->OnChannelClosing(); 155 host_->OnChannelClosing();
215 156
216 // Release the reference to the mock object. The object will be destructed 157 // Release the reference to the mock object. The object will be destructed
217 // on the current message loop. 158 // on the current message loop.
218 host_ = nullptr; 159 host_ = nullptr;
219
220 #if defined(OS_CHROMEOS)
221 chromeos::CrasAudioHandler::Shutdown();
222 #endif
223 } 160 }
224 161
225 void OpenSession() { 162 void OpenSession() {
226 const int render_process_id = 1; 163 const int render_process_id = 1;
227 const int render_frame_id = 1; 164 const int render_frame_id = 1;
228 const int page_request_id = 1; 165 const int page_request_id = 1;
229 const url::Origin security_origin(GURL("http://test.com")); 166 const url::Origin security_origin(GURL("http://test.com"));
230 167
231 ASSERT_TRUE(opened_device_label_.empty()); 168 ASSERT_TRUE(opened_device_label_.empty());
232 169
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 219
283 void CloseSession() { 220 void CloseSession() {
284 if (opened_device_label_.empty()) 221 if (opened_device_label_.empty())
285 return; 222 return;
286 media_stream_manager_->CancelRequest(opened_device_label_); 223 media_stream_manager_->CancelRequest(opened_device_label_);
287 opened_device_label_.clear(); 224 opened_device_label_.clear();
288 opened_session_id_ = kInvalidMediaCaptureSessionId; 225 opened_session_id_ = kInvalidMediaCaptureSessionId;
289 } 226 }
290 227
291 protected: 228 protected:
229 // mojom::VideoCaptureObserver implementation.
292 MOCK_METHOD1(OnStateChanged, void(mojom::VideoCaptureState)); 230 MOCK_METHOD1(OnStateChanged, void(mojom::VideoCaptureState));
231 void OnBufferReady(int32_t buffer_id,
232 mojom::VideoFrameInfoPtr info) override {
233 DoOnBufferReady(buffer_id);
234 }
235 MOCK_METHOD1(DoOnBufferReady, void(int32_t));
236 MOCK_METHOD1(OnBufferDestroyed, void(int32_t));
293 237
294 void StartCapture() { 238 void StartCapture() {
295 EXPECT_CALL(*host_.get(), OnNewBufferCreated(kDeviceId, _, _, _))
296 .Times(AnyNumber())
297 .WillRepeatedly(Return());
298
299 base::RunLoop run_loop; 239 base::RunLoop run_loop;
300 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId))
301 .Times(AnyNumber())
302 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure()));
303
304 media::VideoCaptureParams params; 240 media::VideoCaptureParams params;
305 params.requested_format = media::VideoCaptureFormat( 241 params.requested_format = media::VideoCaptureFormat(
306 gfx::Size(352, 288), 30, media::PIXEL_FORMAT_I420); 242 gfx::Size(352, 288), 30, media::PIXEL_FORMAT_I420);
307 243
308 EXPECT_CALL(*this, OnStateChanged(mojom::VideoCaptureState::STARTED)); 244 EXPECT_CALL(*this, OnStateChanged(mojom::VideoCaptureState::STARTED));
245 EXPECT_CALL(*host_.get(), OnNewBufferCreated(kDeviceId, _, _, _))
246 .Times(AnyNumber())
247 .WillRepeatedly(Return());
248 EXPECT_CALL(*this, DoOnBufferReady(_))
249 .Times(AnyNumber())
250 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure()));
251
309 host_->Start(kDeviceId, opened_session_id_, params, 252 host_->Start(kDeviceId, opened_session_id_, params,
310 observer_binding_.CreateInterfacePtrAndBind()); 253 observer_binding_.CreateInterfacePtrAndBind());
311 254
312 run_loop.Run(); 255 run_loop.Run();
313 } 256 }
314 257
315 void StartStopCapture() { 258 void StartStopCapture() {
316 // Quickly start and then stop capture, without giving much chance for 259 // Quickly start and then stop capture, without giving much chance for
317 // asynchronous start operations to complete. 260 // asynchronous capture operations to produce frames.
318 InSequence s; 261 InSequence s;
319 base::RunLoop run_loop; 262 base::RunLoop run_loop;
320 263
321 media::VideoCaptureParams params; 264 media::VideoCaptureParams params;
322 params.requested_format = media::VideoCaptureFormat( 265 params.requested_format = media::VideoCaptureFormat(
323 gfx::Size(352, 288), 30, media::PIXEL_FORMAT_I420); 266 gfx::Size(352, 288), 30, media::PIXEL_FORMAT_I420);
324 267
325 EXPECT_CALL(*this, OnStateChanged(mojom::VideoCaptureState::STARTED)); 268 EXPECT_CALL(*this, OnStateChanged(mojom::VideoCaptureState::STARTED));
326 host_->Start(kDeviceId, opened_session_id_, params, 269 host_->Start(kDeviceId, opened_session_id_, params,
327 observer_binding_.CreateInterfacePtrAndBind()); 270 observer_binding_.CreateInterfacePtrAndBind());
(...skipping 20 matching lines...) Expand all
348 run_loop.RunUntilIdle(); 291 run_loop.RunUntilIdle();
349 WaitForVideoDeviceThread(); 292 WaitForVideoDeviceThread();
350 } 293 }
351 294
352 void StopCapture() { 295 void StopCapture() {
353 base::RunLoop run_loop; 296 base::RunLoop run_loop;
354 297
355 EXPECT_CALL(*this, OnStateChanged(mojom::VideoCaptureState::STOPPED)) 298 EXPECT_CALL(*this, OnStateChanged(mojom::VideoCaptureState::STOPPED))
356 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure())); 299 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure()));
357 host_->Stop(kDeviceId); 300 host_->Stop(kDeviceId);
358 host_->SetReturnReceivedBuffersImmediately(true);
359 host_->ReturnReceivedBuffers(kDeviceId);
360 301
361 run_loop.Run(); 302 run_loop.Run();
362 303
363 // Expect the VideoCaptureDevice has been stopped
364 EXPECT_TRUE(host_->controllers_.empty()); 304 EXPECT_TRUE(host_->controllers_.empty());
365 } 305 }
366 306
367 void NotifyPacketReady() { 307 void WaitForOneCapturedBuffer() {
368 base::RunLoop run_loop; 308 base::RunLoop run_loop;
369 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId)) 309
310 EXPECT_CALL(*this, DoOnBufferReady(_))
370 .Times(AnyNumber()) 311 .Times(AnyNumber())
371 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure())) 312 .WillOnce(ExitMessageLoop(task_runner_, run_loop.QuitClosure()))
372 .RetiresOnSaturation(); 313 .RetiresOnSaturation();
373 run_loop.Run(); 314 run_loop.Run();
374 } 315 }
375 316
376 void ReturnReceivedPackets() {
377 host_->ReturnReceivedBuffers(kDeviceId);
378 }
379
380 void SimulateError() { 317 void SimulateError() {
381 // Expect a change state to error state sent through IPC.
382 EXPECT_CALL(*this, OnStateChanged(mojom::VideoCaptureState::FAILED)); 318 EXPECT_CALL(*this, OnStateChanged(mojom::VideoCaptureState::FAILED));
383 VideoCaptureControllerID id(kDeviceId); 319 VideoCaptureControllerID id(kDeviceId);
384 host_->OnError(id); 320 host_->OnError(id);
385 // Wait for the error callback.
386 base::RunLoop().RunUntilIdle(); 321 base::RunLoop().RunUntilIdle();
387 } 322 }
388 323
389 void WaitForVideoDeviceThread() { 324 void WaitForVideoDeviceThread() {
390 base::RunLoop run_loop; 325 base::RunLoop run_loop;
391 media_stream_manager_->video_capture_manager()->device_task_runner() 326 media_stream_manager_->video_capture_manager()->device_task_runner()
392 ->PostTaskAndReply( 327 ->PostTaskAndReply(
393 FROM_HERE, 328 FROM_HERE,
394 base::Bind(&base::DoNothing), 329 base::Bind(&base::DoNothing),
395 run_loop.QuitClosure()); 330 run_loop.QuitClosure());
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 CloseSession(); 362 CloseSession();
428 base::RunLoop().RunUntilIdle(); 363 base::RunLoop().RunUntilIdle();
429 } 364 }
430 365
431 TEST_F(VideoCaptureHostTest, StopWhileStartPending) { 366 TEST_F(VideoCaptureHostTest, StopWhileStartPending) {
432 StartStopCapture(); 367 StartStopCapture();
433 } 368 }
434 369
435 TEST_F(VideoCaptureHostTest, StartCapturePlayStop) { 370 TEST_F(VideoCaptureHostTest, StartCapturePlayStop) {
436 StartCapture(); 371 StartCapture();
437 NotifyPacketReady(); 372 WaitForOneCapturedBuffer();
438 NotifyPacketReady(); 373 WaitForOneCapturedBuffer();
439 ReturnReceivedPackets();
440 StopCapture(); 374 StopCapture();
441 } 375 }
442 376
443 TEST_F(VideoCaptureHostTest, StartCaptureErrorStop) { 377 TEST_F(VideoCaptureHostTest, StartCaptureErrorStop) {
444 StartCapture(); 378 StartCapture();
445 SimulateError(); 379 SimulateError();
446 StopCapture(); 380 StopCapture();
447 } 381 }
448 382
449 TEST_F(VideoCaptureHostTest, StartCaptureError) { 383 TEST_F(VideoCaptureHostTest, StartCaptureError) {
450 EXPECT_CALL(*this, OnStateChanged(mojom::VideoCaptureState::STOPPED)) 384 EXPECT_CALL(*this, OnStateChanged(mojom::VideoCaptureState::STOPPED))
451 .Times(0); 385 .Times(0);
452 StartCapture(); 386 StartCapture();
453 NotifyPacketReady(); 387 WaitForOneCapturedBuffer();
454 SimulateError(); 388 SimulateError();
455 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200)); 389 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200));
456 } 390 }
457 391
458 TEST_F(VideoCaptureHostTest, PauseResumeCapture) { 392 TEST_F(VideoCaptureHostTest, PauseResumeCapture) {
459 StartCapture(); 393 StartCapture();
460 PauseResumeCapture(); 394 PauseResumeCapture();
461 StopCapture(); 395 StopCapture();
462 } 396 }
463 397
464 } // namespace content 398 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/video_capture_host.cc ('k') | content/common/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698