1 // Copyright 2014 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.
6 #include "base/callback.h"
7 #include "base/memory/ref_counted.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "content/child/child_process.h"
11 #include "content/renderer/media/video_capture_impl.h"
12 #include "content/renderer/media/video_capture_impl_manager.h"
13 #include "content/renderer/media/video_capture_message_filter.h"
14 #include "media/base/bind_to_current_loop.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
19 using ::testing::DoAll
;
20 using ::testing::SaveArg
;
21 using media::BindToCurrentLoop
;
25 ACTION_P(RunClosure
, closure
) {
29 class MockVideoCaptureImpl
: public VideoCaptureImpl
{
31 MockVideoCaptureImpl(media::VideoCaptureSessionId session_id
,
32 VideoCaptureMessageFilter
* filter
,
33 base::Closure destruct_callback
)
34 : VideoCaptureImpl(session_id
, filter
),
35 destruct_callback_(destruct_callback
) {
38 ~MockVideoCaptureImpl() override
{ destruct_callback_
.Run(); }
41 base::Closure destruct_callback_
;
43 DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureImpl
);
46 class MockVideoCaptureImplManager
: public VideoCaptureImplManager
{
48 explicit MockVideoCaptureImplManager(
49 base::Closure destruct_video_capture_callback
)
50 : destruct_video_capture_callback_(
51 destruct_video_capture_callback
) {}
52 ~MockVideoCaptureImplManager() override
{}
55 VideoCaptureImpl
* CreateVideoCaptureImplForTesting(
56 media::VideoCaptureSessionId id
,
57 VideoCaptureMessageFilter
* filter
) const override
{
58 return new MockVideoCaptureImpl(id
,
60 destruct_video_capture_callback_
);
64 base::Closure destruct_video_capture_callback_
;
66 DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureImplManager
);
69 class VideoCaptureImplManagerTest
: public ::testing::Test
{
71 VideoCaptureImplManagerTest()
72 : manager_(new MockVideoCaptureImplManager(
73 BindToCurrentLoop(cleanup_run_loop_
.QuitClosure()))) {
74 params_
.requested_format
= media::VideoCaptureFormat(
75 gfx::Size(176, 144), 30, media::VIDEO_CAPTURE_PIXEL_FORMAT_I420
);
76 child_process_
.reset(new ChildProcess());
79 void FakeChannelSetup() {
80 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
=
81 child_process_
->io_task_runner();
82 if (!task_runner
->BelongsToCurrentThread()) {
83 task_runner
->PostTask(
84 FROM_HERE
, base::Bind(&VideoCaptureImplManagerTest::FakeChannelSetup
,
85 base::Unretained(this)));
88 manager_
->video_capture_message_filter()->OnFilterAdded(NULL
);
92 MOCK_METHOD2(OnFrameReady
,
93 void(const scoped_refptr
<media::VideoFrame
>&,
94 const base::TimeTicks
& estimated_capture_time
));
95 MOCK_METHOD0(OnStarted
, void());
96 MOCK_METHOD0(OnStopped
, void());
98 void OnStateUpdate(VideoCaptureState state
) {
100 case VIDEO_CAPTURE_STATE_STARTED
:
103 case VIDEO_CAPTURE_STATE_STOPPED
:
111 base::Closure
StartCapture(const media::VideoCaptureSessionId id
,
112 const media::VideoCaptureParams
& params
) {
113 return manager_
->StartCapture(
114 id
, params
, base::Bind(&VideoCaptureImplManagerTest::OnStateUpdate
,
115 base::Unretained(this)),
116 base::Bind(&VideoCaptureImplManagerTest::OnFrameReady
,
117 base::Unretained(this)));
120 base::MessageLoop message_loop_
;
121 scoped_ptr
<ChildProcess
> child_process_
;
122 media::VideoCaptureParams params_
;
123 base::RunLoop cleanup_run_loop_
;
124 scoped_ptr
<MockVideoCaptureImplManager
> manager_
;
127 DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplManagerTest
);
130 TEST_F(VideoCaptureImplManagerTest
, MultipleImpls
) {
131 base::Closure release_cb1
= manager_
->UseDevice(0);
132 base::Closure release_cb2
= manager_
->UseDevice(1);
133 base::Closure stop_cb1
, stop_cb2
;
135 base::RunLoop run_loop
;
136 base::Closure quit_closure
= BindToCurrentLoop(run_loop
.QuitClosure());
137 EXPECT_CALL(*this, OnStarted()).WillOnce(RunClosure(quit_closure
));
138 EXPECT_CALL(*this, OnStarted()).RetiresOnSaturation();
139 stop_cb1
= StartCapture(0, params_
);
140 stop_cb2
= StartCapture(1, params_
);
146 base::RunLoop run_loop
;
147 base::Closure quit_closure
= BindToCurrentLoop(run_loop
.QuitClosure());
148 EXPECT_CALL(*this, OnStopped()).WillOnce(RunClosure(quit_closure
));
149 EXPECT_CALL(*this, OnStopped()).RetiresOnSaturation();
157 cleanup_run_loop_
.Run();
160 TEST_F(VideoCaptureImplManagerTest
, RefusesMultipleClients
) {
161 // TODO(ajose): EXPECT_DEATH is unsafe in a threaded context - what to use
163 base::Closure release_cb1
= manager_
->UseDevice(0);
164 EXPECT_DEATH(base::Closure release_cb2
= manager_
->UseDevice(0), "");
167 TEST_F(VideoCaptureImplManagerTest
, NoLeak
) {
168 manager_
->UseDevice(0).Reset();
170 cleanup_run_loop_
.Run();
173 } // namespace content