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/command_line.h"
6 #include "base/debug/trace_event_impl.h"
7 #include "base/json/json_reader.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/test/trace_event_analyzer.h"
10 #include "base/values.h"
11 #include "content/browser/media/webrtc_internals.h"
12 #include "content/browser/web_contents/web_contents_impl.h"
13 #include "content/public/common/content_switches.h"
14 #include "content/public/test/browser_test_utils.h"
15 #include "content/public/test/content_browser_test_utils.h"
16 #include "content/public/test/test_utils.h"
17 #include "content/shell/browser/shell.h"
18 #include "content/test/webrtc_content_browsertest_base.h"
19 #include "net/test/embedded_test_server/embedded_test_server.h"
20 #include "testing/perf/perf_test.h"
23 #include "base/win/windows_version.h"
26 using trace_analyzer::TraceAnalyzer;
27 using trace_analyzer::Query;
28 using trace_analyzer::TraceEventVector;
32 static const char kGetUserMediaAndStop[] = "getUserMediaAndStop";
33 static const char kGetUserMediaAndGetStreamUp[] = "getUserMediaAndGetStreamUp";
34 static const char kGetUserMediaAndAnalyseAndStop[] =
35 "getUserMediaAndAnalyseAndStop";
36 static const char kGetUserMediaAndExpectFailure[] =
37 "getUserMediaAndExpectFailure";
38 static const char kRenderSameTrackMediastreamAndStop[] =
39 "renderSameTrackMediastreamAndStop";
40 static const char kRenderClonedMediastreamAndStop[] =
41 "renderClonedMediastreamAndStop";
42 static const char kRenderClonedTrackMediastreamAndStop[] =
43 "renderClonedTrackMediastreamAndStop";
44 static const char kRenderDuplicatedMediastreamAndStop[] =
45 "renderDuplicatedMediastreamAndStop";
47 // Results returned by JS.
48 static const char kOK[] = "OK";
50 std::string GenerateGetUserMediaWithMandatorySourceID(
51 const std::string& function_name,
52 const std::string& audio_source_id,
53 const std::string& video_source_id) {
54 const std::string audio_constraint =
55 "audio: {mandatory: { sourceId:\"" + audio_source_id + "\"}}, ";
57 const std::string video_constraint =
58 "video: {mandatory: { sourceId:\"" + video_source_id + "\"}}";
59 return function_name + "({" + audio_constraint + video_constraint + "});";
62 std::string GenerateGetUserMediaWithOptionalSourceID(
63 const std::string& function_name,
64 const std::string& audio_source_id,
65 const std::string& video_source_id) {
66 const std::string audio_constraint =
67 "audio: {optional: [{sourceId:\"" + audio_source_id + "\"}]}, ";
69 const std::string video_constraint =
70 "video: {optional: [{ sourceId:\"" + video_source_id + "\"}]}";
71 return function_name + "({" + audio_constraint + video_constraint + "});";
78 class WebRtcGetUserMediaBrowserTest: public WebRtcContentBrowserTest {
80 WebRtcGetUserMediaBrowserTest() : trace_log_(NULL) {}
81 virtual ~WebRtcGetUserMediaBrowserTest() {}
84 CHECK(trace_log_ == NULL) << "Can only can start tracing once";
85 trace_log_ = base::debug::TraceLog::GetInstance();
86 base::debug::TraceOptions trace_options(base::debug::RECORD_UNTIL_FULL);
87 trace_options.enable_sampling = true;
88 trace_log_->SetEnabled(base::debug::CategoryFilter("video"),
89 base::debug::TraceLog::RECORDING_MODE,
91 // Check that we are indeed recording.
92 EXPECT_EQ(trace_log_->GetNumTracesRecorded(), 1);
96 CHECK(message_loop_runner_ == NULL) << "Calling StopTracing more than once";
97 trace_log_->SetDisabled();
98 message_loop_runner_ = new MessageLoopRunner;
99 trace_log_->Flush(base::Bind(
100 &WebRtcGetUserMediaBrowserTest::OnTraceDataCollected,
101 base::Unretained(this)));
102 message_loop_runner_->Run();
105 void OnTraceDataCollected(
106 const scoped_refptr<base::RefCountedString>& events_str_ptr,
107 bool has_more_events) {
108 CHECK(!has_more_events);
109 recorded_trace_data_ = events_str_ptr;
110 message_loop_runner_->Quit();
113 TraceAnalyzer* CreateTraceAnalyzer() {
114 return TraceAnalyzer::Create("[" + recorded_trace_data_->data() + "]");
117 void RunGetUserMediaAndCollectMeasures(const int time_to_sample_secs,
118 const std::string& measure_filter,
119 const std::string& graph_name) {
120 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
122 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
123 NavigateToURL(shell(), url);
125 // Put getUserMedia to work and let it run for a couple of seconds.
126 DCHECK(time_to_sample_secs);
127 ExecuteJavascriptAndWaitForOk(
128 base::StringPrintf("%s({video: true});",
129 kGetUserMediaAndGetStreamUp));
131 // Now the stream is up and running, start collecting traces.
134 // Let the stream run for a while in javascript.
135 ExecuteJavascriptAndWaitForOk(
136 base::StringPrintf("waitAndStopVideoTrack(%d);", time_to_sample_secs));
138 // Wait until the page title changes to "OK". Do not sleep() here since that
139 // would stop both this code and the browser underneath.
142 scoped_ptr<TraceAnalyzer> analyzer(CreateTraceAnalyzer());
143 analyzer->AssociateBeginEndEvents();
144 trace_analyzer::TraceEventVector events;
145 DCHECK(measure_filter.size());
146 analyzer->FindEvents(
147 Query::EventNameIs(measure_filter),
149 ASSERT_GT(events.size(), 0u)
150 << "Could not collect any samples during test, this is bad";
152 std::string duration_us;
153 std::string interarrival_us;
154 for (size_t i = 0; i != events.size(); ++i) {
156 base::StringPrintf("%d,", static_cast<int>(events[i]->duration)));
159 for (size_t i = 1; i < events.size(); ++i) {
160 // The event |timestamp| comes in ns, divide to get us like |duration|.
161 interarrival_us.append(base::StringPrintf("%d,",
162 static_cast<int>((events[i]->timestamp - events[i - 1]->timestamp) /
163 base::Time::kNanosecondsPerMicrosecond)));
166 perf_test::PrintResultList(
167 graph_name, "", "sample_duration", duration_us, "us", true);
169 perf_test::PrintResultList(
170 graph_name, "", "interarrival_time", interarrival_us, "us", true);
173 // Runs the JavaScript twoGetUserMedia with |constraints1| and |constraint2|.
174 void RunTwoGetTwoGetUserMediaWithDifferentContraints(
175 const std::string& constraints1,
176 const std::string& constraints2,
177 const std::string& expected_result) {
178 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
180 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
181 NavigateToURL(shell(), url);
183 std::string command = "twoGetUserMedia(" + constraints1 + ',' +
186 EXPECT_EQ(expected_result, ExecuteJavascriptAndReturnResult(command));
189 void GetInputDevices(std::vector<std::string>* audio_ids,
190 std::vector<std::string>* video_ids) {
191 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
192 NavigateToURL(shell(), url);
194 std::string devices_as_json = ExecuteJavascriptAndReturnResult(
196 EXPECT_FALSE(devices_as_json.empty());
199 std::string error_message;
200 scoped_ptr<base::Value> value(
201 base::JSONReader::ReadAndReturnError(devices_as_json,
202 base::JSON_ALLOW_TRAILING_COMMAS,
206 ASSERT_TRUE(value.get() != NULL) << error_message;
207 EXPECT_EQ(value->GetType(), base::Value::TYPE_LIST);
209 base::ListValue* values;
210 ASSERT_TRUE(value->GetAsList(&values));
212 for (base::ListValue::iterator it = values->begin();
213 it != values->end(); ++it) {
214 const base::DictionaryValue* dict;
216 std::string device_id;
217 ASSERT_TRUE((*it)->GetAsDictionary(&dict));
218 ASSERT_TRUE(dict->GetString("kind", &kind));
219 ASSERT_TRUE(dict->GetString("id", &device_id));
220 ASSERT_FALSE(device_id.empty());
221 EXPECT_TRUE(kind == "audio" || kind == "video");
222 if (kind == "audio") {
223 audio_ids->push_back(device_id);
224 } else if (kind == "video") {
225 video_ids->push_back(device_id);
228 ASSERT_FALSE(audio_ids->empty());
229 ASSERT_FALSE(video_ids->empty());
233 base::debug::TraceLog* trace_log_;
234 scoped_refptr<base::RefCountedString> recorded_trace_data_;
235 scoped_refptr<MessageLoopRunner> message_loop_runner_;
238 // These tests will all make a getUserMedia call with different constraints and
239 // see that the success callback is called. If the error callback is called or
240 // none of the callbacks are called the tests will simply time out and fail.
241 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest, GetVideoStreamAndStop) {
242 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
244 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
245 NavigateToURL(shell(), url);
247 ExecuteJavascriptAndWaitForOk(
248 base::StringPrintf("%s({video: true});", kGetUserMediaAndStop));
251 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
252 RenderSameTrackMediastreamAndStop) {
253 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
255 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
256 NavigateToURL(shell(), url);
258 ExecuteJavascriptAndWaitForOk(
259 base::StringPrintf("%s({video: true});",
260 kRenderSameTrackMediastreamAndStop));
263 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
264 RenderClonedMediastreamAndStop) {
265 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
267 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
268 NavigateToURL(shell(), url);
271 ExecuteJavascriptAndWaitForOk(
272 base::StringPrintf("%s({video: true});",
273 kRenderClonedMediastreamAndStop));
276 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
277 kRenderClonedTrackMediastreamAndStop) {
278 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
280 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
281 NavigateToURL(shell(), url);
283 ExecuteJavascriptAndWaitForOk(
284 base::StringPrintf("%s({video: true});",
285 kRenderClonedTrackMediastreamAndStop));
288 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
289 kRenderDuplicatedMediastreamAndStop) {
290 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
292 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
293 NavigateToURL(shell(), url);
295 ExecuteJavascriptAndWaitForOk(
296 base::StringPrintf("%s({video: true});",
297 kRenderDuplicatedMediastreamAndStop));
300 // Flaky on Android. http://crbug.com/387895
301 #if defined(OS_ANDROID)
302 #define MAYBE_GetAudioAndVideoStreamAndStop DISABLED_GetAudioAndVideoStreamAndStop
304 #define MAYBE_GetAudioAndVideoStreamAndStop GetAudioAndVideoStreamAndStop
307 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
308 MAYBE_GetAudioAndVideoStreamAndStop) {
309 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
311 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
312 NavigateToURL(shell(), url);
314 ExecuteJavascriptAndWaitForOk(base::StringPrintf(
315 "%s({video: true, audio: true});", kGetUserMediaAndStop));
318 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
319 GetAudioAndVideoStreamAndClone) {
320 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
322 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
323 NavigateToURL(shell(), url);
325 ExecuteJavascriptAndWaitForOk("getUserMediaAndClone();");
328 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
329 RenderVideoTrackInMultipleTagsAndPause) {
330 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
332 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
333 NavigateToURL(shell(), url);
335 ExecuteJavascriptAndWaitForOk("getUserMediaAndRenderInSeveralVideoTags();");
340 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
341 GetUserMediaWithMandatorySourceID) {
342 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
344 std::vector<std::string> audio_ids;
345 std::vector<std::string> video_ids;
346 GetInputDevices(&audio_ids, &video_ids);
348 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
350 // Test all combinations of mandatory sourceID;
351 for (std::vector<std::string>::const_iterator video_it = video_ids.begin();
352 video_it != video_ids.end(); ++video_it) {
353 for (std::vector<std::string>::const_iterator audio_it = audio_ids.begin();
354 audio_it != audio_ids.end(); ++audio_it) {
355 NavigateToURL(shell(), url);
356 EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
357 GenerateGetUserMediaWithMandatorySourceID(
358 kGetUserMediaAndStop,
365 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
366 GetUserMediaWithInvalidMandatorySourceID) {
367 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
369 std::vector<std::string> audio_ids;
370 std::vector<std::string> video_ids;
371 GetInputDevices(&audio_ids, &video_ids);
373 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
375 // Test with invalid mandatory audio sourceID.
376 NavigateToURL(shell(), url);
377 EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult(
378 GenerateGetUserMediaWithMandatorySourceID(
379 kGetUserMediaAndExpectFailure,
383 // Test with invalid mandatory video sourceID.
384 EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult(
385 GenerateGetUserMediaWithMandatorySourceID(
386 kGetUserMediaAndExpectFailure,
388 "something invalid")));
390 // Test with empty mandatory audio sourceID.
391 EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult(
392 GenerateGetUserMediaWithMandatorySourceID(
393 kGetUserMediaAndExpectFailure,
398 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
399 GetUserMediaWithInvalidOptionalSourceID) {
400 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
402 std::vector<std::string> audio_ids;
403 std::vector<std::string> video_ids;
404 GetInputDevices(&audio_ids, &video_ids);
406 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
408 // Test with invalid optional audio sourceID.
409 NavigateToURL(shell(), url);
410 EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
411 GenerateGetUserMediaWithOptionalSourceID(
412 kGetUserMediaAndStop,
416 // Test with invalid optional video sourceID.
417 EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
418 GenerateGetUserMediaWithOptionalSourceID(
419 kGetUserMediaAndStop,
421 "something invalid")));
423 // Test with empty optional audio sourceID.
424 EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
425 GenerateGetUserMediaWithOptionalSourceID(
426 kGetUserMediaAndStop,
431 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest, TwoGetUserMediaAndStop) {
432 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
434 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
435 NavigateToURL(shell(), url);
437 ExecuteJavascriptAndWaitForOk(
438 "twoGetUserMediaAndStop({video: true, audio: true});");
441 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
442 TwoGetUserMediaWithEqualConstraints) {
443 std::string constraints1 = "{video: true, audio: true}";
444 const std::string& constraints2 = constraints1;
445 std::string expected_result = "w=640:h=480-w=640:h=480";
447 RunTwoGetTwoGetUserMediaWithDifferentContraints(constraints1, constraints2,
451 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
452 TwoGetUserMediaWithSecondVideoCropped) {
453 std::string constraints1 = "{video: true}";
454 std::string constraints2 = "{video: {mandatory: {maxHeight: 360}}}";
455 std::string expected_result = "w=640:h=480-w=640:h=360";
456 RunTwoGetTwoGetUserMediaWithDifferentContraints(constraints1, constraints2,
460 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
461 TwoGetUserMediaWithFirstHdSecondVga) {
462 std::string constraints1 =
463 "{video: {mandatory: {minWidth:1280 , minHeight: 720}}}";
464 std::string constraints2 =
465 "{video: {mandatory: {maxWidth:640 , maxHeight: 480}}}";
466 std::string expected_result = "w=1280:h=720-w=640:h=480";
467 RunTwoGetTwoGetUserMediaWithDifferentContraints(constraints1, constraints2,
471 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
472 TwoGetUserMediaAndVerifyFrameRate) {
473 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
475 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
476 NavigateToURL(shell(), url);
478 std::string constraints1 =
479 "{video: {mandatory: {minWidth:640 , minHeight: 480, "
480 "minFrameRate : 15, maxFrameRate : 15}}}";
481 std::string constraints2 =
482 "{video: {mandatory: {maxWidth:320 , maxHeight: 240,"
483 "minFrameRate : 7, maxFrameRate : 7}}}";
485 std::string command = "twoGetUserMediaAndVerifyFrameRate(" +
486 constraints1 + ',' + constraints2 + ", 15, 7)";
487 ExecuteJavascriptAndWaitForOk(command);
490 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
491 GetUserMediaWithTooHighVideoConstraintsValues) {
492 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
494 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
496 int large_value = 99999;
497 std::string call = GenerateGetUserMediaCall(kGetUserMediaAndExpectFailure,
504 NavigateToURL(shell(), url);
506 EXPECT_EQ("ConstraintNotSatisfiedError",
507 ExecuteJavascriptAndReturnResult(call));
510 // This test will make a simple getUserMedia page, verify that video is playing
511 // in a simple local <video>, and for a couple of seconds, collect some
512 // performance traces from VideoCaptureController colorspace conversion and
513 // potential resizing.
514 IN_PROC_BROWSER_TEST_F(
515 WebRtcGetUserMediaBrowserTest,
516 TraceVideoCaptureControllerPerformanceDuringGetUserMedia) {
517 RunGetUserMediaAndCollectMeasures(
519 "VideoCaptureController::OnIncomingCapturedData",
520 "VideoCaptureController");
523 // This test calls getUserMedia and checks for aspect ratio behavior.
524 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
525 TestGetUserMediaAspectRatio4To3) {
526 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
528 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
530 std::string constraints_4_3 = GenerateGetUserMediaCall(
531 kGetUserMediaAndAnalyseAndStop, 640, 640, 480, 480, 10, 30);
533 NavigateToURL(shell(), url);
534 ASSERT_EQ("w=640:h=480",
535 ExecuteJavascriptAndReturnResult(constraints_4_3));
538 // This test calls getUserMedia and checks for aspect ratio behavior.
539 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
540 TestGetUserMediaAspectRatio16To9) {
541 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
543 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
545 std::string constraints_16_9 = GenerateGetUserMediaCall(
546 kGetUserMediaAndAnalyseAndStop, 640, 640, 360, 360, 10, 30);
548 NavigateToURL(shell(), url);
549 ASSERT_EQ("w=640:h=360",
550 ExecuteJavascriptAndReturnResult(constraints_16_9));
553 // This test calls getUserMedia and checks for aspect ratio behavior.
554 IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
555 TestGetUserMediaAspectRatio1To1) {
556 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
558 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
560 std::string constraints_1_1 = GenerateGetUserMediaCall(
561 kGetUserMediaAndAnalyseAndStop, 320, 320, 320, 320, 10, 30);
563 NavigateToURL(shell(), url);
564 ASSERT_EQ("w=320:h=320",
565 ExecuteJavascriptAndReturnResult(constraints_1_1));
570 struct UserMediaSizes {
581 class WebRtcConstraintsBrowserTest
582 : public WebRtcContentBrowserTest,
583 public testing::WithParamInterface<UserMediaSizes> {
585 WebRtcConstraintsBrowserTest() : user_media_(GetParam()) {}
586 const UserMediaSizes& user_media() const { return user_media_; }
589 UserMediaSizes user_media_;
592 // This test calls getUserMedia in sequence with different constraints.
593 IN_PROC_BROWSER_TEST_P(WebRtcConstraintsBrowserTest, GetUserMediaConstraints) {
594 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
596 GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
598 std::string call = GenerateGetUserMediaCall(kGetUserMediaAndStop,
599 user_media().min_width,
600 user_media().max_width,
601 user_media().min_height,
602 user_media().max_height,
603 user_media().min_frame_rate,
604 user_media().max_frame_rate);
605 DVLOG(1) << "Calling getUserMedia: " << call;
606 NavigateToURL(shell(), url);
607 ExecuteJavascriptAndWaitForOk(call);
610 static const UserMediaSizes kAllUserMediaSizes[] = {
611 {320, 320, 180, 180, 10, 30},
612 {320, 320, 240, 240, 10, 30},
613 {640, 640, 360, 360, 10, 30},
614 {640, 640, 480, 480, 10, 30},
615 {960, 960, 720, 720, 10, 30},
616 {1280, 1280, 720, 720, 10, 30}};
618 INSTANTIATE_TEST_CASE_P(UserMedia,
619 WebRtcConstraintsBrowserTest,
620 testing::ValuesIn(kAllUserMediaSizes));
622 } // namespace content