[Android] Implement 3-way sensor fallback for Device Orientation.
[chromium-blink-merge.git] / content / renderer / media / media_stream_video_capture_source_unittest.cc
blob3efc0cb969ac4dc8656f47d6779d0bedd1da2b93
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/location.h"
8 #include "base/run_loop.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/child/child_process.h"
12 #include "content/public/renderer/media_stream_video_sink.h"
13 #include "content/renderer/media/media_stream_video_capturer_source.h"
14 #include "content/renderer/media/media_stream_video_track.h"
15 #include "content/renderer/media/mock_media_constraint_factory.h"
16 #include "media/base/bind_to_current_loop.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/WebKit/public/web/WebHeap.h"
21 using ::testing::_;
23 namespace content {
25 class MockVideoCapturerDelegate : public VideoCapturerDelegate {
26 public:
27 explicit MockVideoCapturerDelegate(const StreamDeviceInfo& device_info)
28 : VideoCapturerDelegate(device_info) {}
30 MOCK_METHOD4(
31 StartCapture,
32 void(const media::VideoCaptureParams& params,
33 const VideoCaptureDeliverFrameCB& new_frame_callback,
34 scoped_refptr<base::SingleThreadTaskRunner>
35 frame_callback_task_runner,
36 const RunningCallback& running_callback));
37 MOCK_METHOD0(StopCapture, void());
40 class MediaStreamVideoCapturerSourceTest : public testing::Test {
41 public:
42 MediaStreamVideoCapturerSourceTest()
43 : child_process_(new ChildProcess()),
44 source_(NULL),
45 delegate_(NULL),
46 source_stopped_(false) {
49 void TearDown() override {
50 webkit_source_.reset();
51 blink::WebHeap::collectAllGarbageForTesting();
54 void InitWithDeviceInfo(const StreamDeviceInfo& device_info) {
55 scoped_ptr<MockVideoCapturerDelegate> delegate(
56 new MockVideoCapturerDelegate(device_info));
57 delegate_ = delegate.get();
58 source_ = new MediaStreamVideoCapturerSource(
59 base::Bind(&MediaStreamVideoCapturerSourceTest::OnSourceStopped,
60 base::Unretained(this)),
61 delegate.Pass());
62 source_->SetDeviceInfo(device_info);
64 webkit_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
65 blink::WebMediaStreamSource::TypeVideo,
66 base::UTF8ToUTF16("dummy_source_name"),
67 false /* remote */ , true /* readonly */);
68 webkit_source_.setExtraData(source_);
69 webkit_source_id_ = webkit_source_.id();
72 MockMediaConstraintFactory* constraint_factory() {
73 return &constraint_factory_;
76 blink::WebMediaStreamTrack StartSource() {
77 bool enabled = true;
78 // CreateVideoTrack will trigger OnConstraintsApplied.
79 return MediaStreamVideoTrack::CreateVideoTrack(
80 source_, constraint_factory_.CreateWebMediaConstraints(),
81 base::Bind(
82 &MediaStreamVideoCapturerSourceTest::OnConstraintsApplied,
83 base::Unretained(this)),
84 enabled);
87 MockVideoCapturerDelegate& mock_delegate() {
88 return *delegate_;
91 void OnSourceStopped(const blink::WebMediaStreamSource& source) {
92 source_stopped_ = true;
93 EXPECT_EQ(source.id(), webkit_source_id_);
96 protected:
97 void OnConstraintsApplied(MediaStreamSource* source,
98 MediaStreamRequestResult result,
99 const blink::WebString& result_name) {
102 base::MessageLoopForUI message_loop_;
103 scoped_ptr<ChildProcess> child_process_;
104 blink::WebMediaStreamSource webkit_source_;
105 MediaStreamVideoCapturerSource* source_; // owned by |webkit_source_|.
106 MockVideoCapturerDelegate* delegate_; // owned by |source|.
107 blink::WebString webkit_source_id_;
108 bool source_stopped_;
109 MockMediaConstraintFactory constraint_factory_;
112 TEST_F(MediaStreamVideoCapturerSourceTest, TabCaptureFixedResolutionByDefault) {
113 StreamDeviceInfo device_info;
114 device_info.device.type = MEDIA_TAB_VIDEO_CAPTURE;
115 InitWithDeviceInfo(device_info);
117 // No constraints are being provided to the implementation, so expect only
118 // default values.
119 media::VideoCaptureParams expected_params;
120 expected_params.requested_format.frame_size.SetSize(
121 MediaStreamVideoSource::kDefaultWidth,
122 MediaStreamVideoSource::kDefaultHeight);
123 expected_params.requested_format.frame_rate =
124 MediaStreamVideoSource::kDefaultFrameRate;
125 expected_params.requested_format.pixel_format =
126 media::VIDEO_CAPTURE_PIXEL_FORMAT_I420;
127 expected_params.resolution_change_policy =
128 media::RESOLUTION_POLICY_FIXED_RESOLUTION;
130 EXPECT_CALL(mock_delegate(), StartCapture(expected_params, _, _, _)).Times(1);
131 blink::WebMediaStreamTrack track = StartSource();
132 // When the track goes out of scope, the source will be stopped.
133 EXPECT_CALL(mock_delegate(), StopCapture());
136 TEST_F(MediaStreamVideoCapturerSourceTest,
137 DesktopCaptureAllowAnyResolutionChangeByDefault) {
138 StreamDeviceInfo device_info;
139 device_info.device.type = MEDIA_DESKTOP_VIDEO_CAPTURE;
140 InitWithDeviceInfo(device_info);
142 // No constraints are being provided to the implementation, so expect only
143 // default values.
144 media::VideoCaptureParams expected_params;
145 expected_params.requested_format.frame_size.SetSize(
146 MediaStreamVideoSource::kDefaultWidth,
147 MediaStreamVideoSource::kDefaultHeight);
148 expected_params.requested_format.frame_rate =
149 MediaStreamVideoSource::kDefaultFrameRate;
150 expected_params.requested_format.pixel_format =
151 media::VIDEO_CAPTURE_PIXEL_FORMAT_I420;
152 expected_params.resolution_change_policy =
153 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT;
155 EXPECT_CALL(mock_delegate(), StartCapture(expected_params, _, _, _)).Times(1);
156 blink::WebMediaStreamTrack track = StartSource();
157 // When the track goes out of scope, the source will be stopped.
158 EXPECT_CALL(mock_delegate(), StopCapture());
161 TEST_F(MediaStreamVideoCapturerSourceTest,
162 TabCaptureConstraintsImplyFixedAspectRatio) {
163 StreamDeviceInfo device_info;
164 device_info.device.type = MEDIA_TAB_VIDEO_CAPTURE;
165 InitWithDeviceInfo(device_info);
167 // Specify max and min size constraints that have the same ~16:9 aspect ratio.
168 constraint_factory()->AddMandatory(MediaStreamVideoSource::kMaxWidth, 1920);
169 constraint_factory()->AddMandatory(MediaStreamVideoSource::kMaxHeight, 1080);
170 constraint_factory()->AddMandatory(MediaStreamVideoSource::kMinWidth, 854);
171 constraint_factory()->AddMandatory(MediaStreamVideoSource::kMinHeight, 480);
172 constraint_factory()->AddMandatory(MediaStreamVideoSource::kMaxFrameRate,
173 60.0);
175 media::VideoCaptureParams expected_params;
176 expected_params.requested_format.frame_size.SetSize(1920, 1080);
177 expected_params.requested_format.frame_rate = 60.0;
178 expected_params.requested_format.pixel_format =
179 media::VIDEO_CAPTURE_PIXEL_FORMAT_I420;
180 expected_params.resolution_change_policy =
181 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO;
183 EXPECT_CALL(
184 mock_delegate(),
185 StartCapture(
186 testing::Field(&media::VideoCaptureParams::resolution_change_policy,
187 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO),
188 _, _, _))
189 .Times(1);
190 blink::WebMediaStreamTrack track = StartSource();
191 // When the track goes out of scope, the source will be stopped.
192 EXPECT_CALL(mock_delegate(), StopCapture());
195 TEST_F(MediaStreamVideoCapturerSourceTest,
196 TabCaptureConstraintsImplyAllowingAnyResolutionChange) {
197 StreamDeviceInfo device_info;
198 device_info.device.type = MEDIA_TAB_VIDEO_CAPTURE;
199 InitWithDeviceInfo(device_info);
201 // Specify max and min size constraints with different aspect ratios.
202 constraint_factory()->AddMandatory(MediaStreamVideoSource::kMaxWidth, 1920);
203 constraint_factory()->AddMandatory(MediaStreamVideoSource::kMaxHeight, 1080);
204 constraint_factory()->AddMandatory(MediaStreamVideoSource::kMinWidth, 0);
205 constraint_factory()->AddMandatory(MediaStreamVideoSource::kMinHeight, 0);
206 constraint_factory()->AddMandatory(MediaStreamVideoSource::kMaxFrameRate,
207 60.0);
209 media::VideoCaptureParams expected_params;
210 expected_params.requested_format.frame_size.SetSize(1920, 1080);
211 expected_params.requested_format.frame_rate = 60.0;
212 expected_params.requested_format.pixel_format =
213 media::VIDEO_CAPTURE_PIXEL_FORMAT_I420;
214 expected_params.resolution_change_policy =
215 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT;
217 EXPECT_CALL(mock_delegate(), StartCapture(expected_params, _, _, _)).Times(1);
218 blink::WebMediaStreamTrack track = StartSource();
219 // When the track goes out of scope, the source will be stopped.
220 EXPECT_CALL(mock_delegate(), StopCapture());
223 TEST_F(MediaStreamVideoCapturerSourceTest, Ended) {
224 StreamDeviceInfo device_info;
225 device_info.device.type = MEDIA_DESKTOP_VIDEO_CAPTURE;
226 scoped_ptr<VideoCapturerDelegate> delegate(
227 new VideoCapturerDelegate(device_info));
228 VideoCapturerDelegate* delegate_ptr = delegate.get();
229 source_ = new MediaStreamVideoCapturerSource(
230 base::Bind(&MediaStreamVideoCapturerSourceTest::OnSourceStopped,
231 base::Unretained(this)),
232 delegate.Pass());
233 source_->SetDeviceInfo(device_info);
234 webkit_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
235 blink::WebMediaStreamSource::TypeVideo,
236 base::UTF8ToUTF16("dummy_source_name"),
237 false /* remote */ , true /* readonly */);
238 webkit_source_.setExtraData(source_);
239 webkit_source_id_ = webkit_source_.id();
240 blink::WebMediaStreamTrack track = StartSource();
241 message_loop_.RunUntilIdle();
243 delegate_ptr->OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED);
244 message_loop_.RunUntilIdle();
245 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
246 webkit_source_.readyState());
248 EXPECT_FALSE(source_stopped_);
249 delegate_ptr->OnStateUpdate(VIDEO_CAPTURE_STATE_ERROR);
250 message_loop_.RunUntilIdle();
251 EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded,
252 webkit_source_.readyState());
253 // Verify that MediaStreamSource::SourceStoppedCallback has been triggered.
254 EXPECT_TRUE(source_stopped_);
257 class FakeMediaStreamVideoSink : public MediaStreamVideoSink {
258 public:
259 FakeMediaStreamVideoSink(base::TimeTicks* capture_time,
260 media::VideoFrameMetadata* metadata,
261 base::Closure got_frame_cb)
262 : capture_time_(capture_time),
263 metadata_(metadata),
264 got_frame_cb_(got_frame_cb) {
267 void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame,
268 const base::TimeTicks& capture_time) {
269 *capture_time_ = capture_time;
270 metadata_->Clear();
271 base::DictionaryValue tmp;
272 frame->metadata()->MergeInternalValuesInto(&tmp);
273 metadata_->MergeInternalValuesFrom(tmp);
274 base::ResetAndReturn(&got_frame_cb_).Run();
277 private:
278 base::TimeTicks* const capture_time_;
279 media::VideoFrameMetadata* const metadata_;
280 base::Closure got_frame_cb_;
283 TEST_F(MediaStreamVideoCapturerSourceTest, CaptureTimeAndMetadataPlumbing) {
284 StreamDeviceInfo device_info;
285 device_info.device.type = MEDIA_DESKTOP_VIDEO_CAPTURE;
286 InitWithDeviceInfo(device_info);
288 VideoCaptureDeliverFrameCB deliver_frame_cb;
289 VideoCapturerDelegate::RunningCallback running_cb;
291 EXPECT_CALL(mock_delegate(), StartCapture(_, _, _, _))
292 .Times(1)
293 .WillOnce(testing::DoAll(testing::SaveArg<1>(&deliver_frame_cb),
294 testing::SaveArg<3>(&running_cb)));
295 EXPECT_CALL(mock_delegate(), StopCapture());
296 blink::WebMediaStreamTrack track = StartSource();
297 running_cb.Run(true);
299 base::RunLoop run_loop;
300 base::TimeTicks reference_capture_time =
301 base::TimeTicks::FromInternalValue(60013);
302 base::TimeTicks capture_time;
303 media::VideoFrameMetadata metadata;
304 FakeMediaStreamVideoSink fake_sink(
305 &capture_time,
306 &metadata,
307 media::BindToCurrentLoop(run_loop.QuitClosure()));
308 FakeMediaStreamVideoSink::AddToVideoTrack(
309 &fake_sink,
310 base::Bind(&FakeMediaStreamVideoSink::OnVideoFrame,
311 base::Unretained(&fake_sink)),
312 track);
313 const scoped_refptr<media::VideoFrame> frame =
314 media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2));
315 frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, 30.0);
316 child_process_->io_task_runner()->PostTask(
317 FROM_HERE, base::Bind(deliver_frame_cb, frame, reference_capture_time));
318 run_loop.Run();
319 FakeMediaStreamVideoSink::RemoveFromVideoTrack(&fake_sink, track);
320 EXPECT_EQ(reference_capture_time, capture_time);
321 double metadata_value;
322 EXPECT_TRUE(metadata.GetDouble(media::VideoFrameMetadata::FRAME_RATE,
323 &metadata_value));
324 EXPECT_EQ(30.0, metadata_value);
327 } // namespace content