Fix crash on app list start page contents not existing.
[chromium-blink-merge.git] / content / renderer / media / media_stream_video_capture_source_unittest.cc
blob6ebecadb37c58f3738e770f90e9ade2ea52a4910
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.
5 #include "base/bind.h"
6 #include "base/callback_helpers.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/child/child_process.h"
11 #include "content/public/renderer/media_stream_video_sink.h"
12 #include "content/renderer/media/media_stream_video_capturer_source.h"
13 #include "content/renderer/media/media_stream_video_track.h"
14 #include "content/renderer/media/mock_media_constraint_factory.h"
15 #include "media/base/bind_to_current_loop.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/WebKit/public/web/WebHeap.h"
20 namespace content {
22 class MockVideoCapturerDelegate : public VideoCapturerDelegate {
23 public:
24 explicit MockVideoCapturerDelegate(const StreamDeviceInfo& device_info)
25 : VideoCapturerDelegate(device_info) {}
27 MOCK_METHOD3(StartCapture,
28 void(const media::VideoCaptureParams& params,
29 const VideoCaptureDeliverFrameCB& new_frame_callback,
30 const RunningCallback& running_callback));
31 MOCK_METHOD0(StopCapture, void());
33 virtual ~MockVideoCapturerDelegate() {}
36 class MediaStreamVideoCapturerSourceTest : public testing::Test {
37 public:
38 MediaStreamVideoCapturerSourceTest()
39 : child_process_(new ChildProcess()),
40 source_(NULL),
41 delegate_(NULL),
42 source_stopped_(false) {
45 void TearDown() override {
46 webkit_source_.reset();
47 blink::WebHeap::collectAllGarbageForTesting();
50 void InitWithDeviceInfo(const StreamDeviceInfo& device_info) {
51 scoped_ptr<MockVideoCapturerDelegate> delegate(
52 new MockVideoCapturerDelegate(device_info));
53 delegate_ = delegate.get();
54 source_ = new MediaStreamVideoCapturerSource(
55 device_info,
56 base::Bind(&MediaStreamVideoCapturerSourceTest::OnSourceStopped,
57 base::Unretained(this)),
58 delegate.Pass());
60 webkit_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
61 blink::WebMediaStreamSource::TypeVideo,
62 base::UTF8ToUTF16("dummy_source_name"),
63 false /* remote */ , true /* readonly */);
64 webkit_source_.setExtraData(source_);
65 webkit_source_id_ = webkit_source_.id();
68 blink::WebMediaStreamTrack StartSource() {
69 MockMediaConstraintFactory factory;
70 bool enabled = true;
71 // CreateVideoTrack will trigger OnConstraintsApplied.
72 return MediaStreamVideoTrack::CreateVideoTrack(
73 source_, factory.CreateWebMediaConstraints(),
74 base::Bind(
75 &MediaStreamVideoCapturerSourceTest::OnConstraintsApplied,
76 base::Unretained(this)),
77 enabled);
80 MockVideoCapturerDelegate& mock_delegate() {
81 return *delegate_;
84 void OnSourceStopped(const blink::WebMediaStreamSource& source) {
85 source_stopped_ = true;
86 EXPECT_EQ(source.id(), webkit_source_id_);
89 protected:
90 void OnConstraintsApplied(MediaStreamSource* source,
91 MediaStreamRequestResult result,
92 const blink::WebString& result_name) {
95 base::MessageLoopForUI message_loop_;
96 scoped_ptr<ChildProcess> child_process_;
97 blink::WebMediaStreamSource webkit_source_;
98 MediaStreamVideoCapturerSource* source_; // owned by |webkit_source_|.
99 MockVideoCapturerDelegate* delegate_; // owned by |source|.
100 blink::WebString webkit_source_id_;
101 bool source_stopped_;
104 TEST_F(MediaStreamVideoCapturerSourceTest, TabCaptureAllowResolutionChange) {
105 StreamDeviceInfo device_info;
106 device_info.device.type = MEDIA_TAB_VIDEO_CAPTURE;
107 InitWithDeviceInfo(device_info);
109 EXPECT_CALL(mock_delegate(), StartCapture(
110 testing::Field(&media::VideoCaptureParams::resolution_change_policy,
111 media::RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT),
112 testing::_,
113 testing::_)).Times(1);
114 blink::WebMediaStreamTrack track = StartSource();
115 // When the track goes out of scope, the source will be stopped.
116 EXPECT_CALL(mock_delegate(), StopCapture());
119 TEST_F(MediaStreamVideoCapturerSourceTest,
120 DesktopCaptureAllowResolutionChange) {
121 StreamDeviceInfo device_info;
122 device_info.device.type = MEDIA_DESKTOP_VIDEO_CAPTURE;
123 InitWithDeviceInfo(device_info);
125 EXPECT_CALL(mock_delegate(), StartCapture(
126 testing::Field(&media::VideoCaptureParams::resolution_change_policy,
127 media::RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT),
128 testing::_,
129 testing::_)).Times(1);
130 blink::WebMediaStreamTrack track = StartSource();
131 // When the track goes out of scope, the source will be stopped.
132 EXPECT_CALL(mock_delegate(), StopCapture());
135 TEST_F(MediaStreamVideoCapturerSourceTest, Ended) {
136 StreamDeviceInfo device_info;
137 device_info.device.type = MEDIA_DESKTOP_VIDEO_CAPTURE;
138 scoped_ptr<VideoCapturerDelegate> delegate(
139 new VideoCapturerDelegate(device_info));
140 VideoCapturerDelegate* delegate_ptr = delegate.get();
141 source_ = new MediaStreamVideoCapturerSource(
142 device_info,
143 base::Bind(&MediaStreamVideoCapturerSourceTest::OnSourceStopped,
144 base::Unretained(this)),
145 delegate.Pass());
146 webkit_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
147 blink::WebMediaStreamSource::TypeVideo,
148 base::UTF8ToUTF16("dummy_source_name"),
149 false /* remote */ , true /* readonly */);
150 webkit_source_.setExtraData(source_);
151 webkit_source_id_ = webkit_source_.id();
152 blink::WebMediaStreamTrack track = StartSource();
153 message_loop_.RunUntilIdle();
155 delegate_ptr->OnStateUpdateOnRenderThread(VIDEO_CAPTURE_STATE_STARTED);
156 message_loop_.RunUntilIdle();
157 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
158 webkit_source_.readyState());
160 EXPECT_FALSE(source_stopped_);
161 delegate_ptr->OnStateUpdateOnRenderThread(VIDEO_CAPTURE_STATE_ERROR);
162 message_loop_.RunUntilIdle();
163 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded,
164 webkit_source_.readyState());
165 // Verify that MediaStreamSource::SourceStoppedCallback has been triggered.
166 EXPECT_TRUE(source_stopped_);
169 class FakeMediaStreamVideoSink : public MediaStreamVideoSink {
170 public:
171 FakeMediaStreamVideoSink(base::TimeTicks* capture_time,
172 base::Closure got_frame_cb)
173 : capture_time_(capture_time),
174 got_frame_cb_(got_frame_cb) {
177 void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame,
178 const media::VideoCaptureFormat& format,
179 const base::TimeTicks& capture_time) {
180 *capture_time_ = capture_time;
181 base::ResetAndReturn(&got_frame_cb_).Run();
184 private:
185 base::TimeTicks* capture_time_;
186 base::Closure got_frame_cb_;
189 TEST_F(MediaStreamVideoCapturerSourceTest, CaptureTime) {
190 StreamDeviceInfo device_info;
191 device_info.device.type = MEDIA_DESKTOP_VIDEO_CAPTURE;
192 InitWithDeviceInfo(device_info);
194 VideoCaptureDeliverFrameCB deliver_frame_cb;
195 VideoCapturerDelegate::RunningCallback running_cb;
197 EXPECT_CALL(mock_delegate(), StartCapture(
198 testing::_,
199 testing::_,
200 testing::_))
201 .Times(1)
202 .WillOnce(testing::DoAll(testing::SaveArg<1>(&deliver_frame_cb),
203 testing::SaveArg<2>(&running_cb)));
204 EXPECT_CALL(mock_delegate(), StopCapture());
205 blink::WebMediaStreamTrack track = StartSource();
206 running_cb.Run(MEDIA_DEVICE_OK);
208 base::RunLoop run_loop;
209 base::TimeTicks reference_capture_time =
210 base::TimeTicks::FromInternalValue(60013);
211 base::TimeTicks capture_time;
212 FakeMediaStreamVideoSink fake_sink(
213 &capture_time,
214 media::BindToCurrentLoop(run_loop.QuitClosure()));
215 FakeMediaStreamVideoSink::AddToVideoTrack(
216 &fake_sink,
217 base::Bind(&FakeMediaStreamVideoSink::OnVideoFrame,
218 base::Unretained(&fake_sink)),
219 track);
220 child_process_->io_message_loop()->PostTask(
221 FROM_HERE,
222 base::Bind(deliver_frame_cb,
223 media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2)),
224 media::VideoCaptureFormat(),
225 reference_capture_time));
226 run_loop.Run();
227 FakeMediaStreamVideoSink::RemoveFromVideoTrack(&fake_sink, track);
228 EXPECT_EQ(reference_capture_time, capture_time);
231 } // namespace content