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.
4
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"
21
22#if defined(OS_WIN)
23#include "base/win/windows_version.h"
24#endif
25
26using trace_analyzer::TraceAnalyzer;
27using trace_analyzer::Query;
28using trace_analyzer::TraceEventVector;
29
30namespace {
31
32static const char kGetUserMediaAndStop[] = "getUserMediaAndStop";
33static const char kGetUserMediaAndGetStreamUp[] = "getUserMediaAndGetStreamUp";
34static const char kGetUserMediaAndAnalyseAndStop[] =
35    "getUserMediaAndAnalyseAndStop";
36static const char kGetUserMediaAndExpectFailure[] =
37    "getUserMediaAndExpectFailure";
38static const char kRenderSameTrackMediastreamAndStop[] =
39    "renderSameTrackMediastreamAndStop";
40static const char kRenderClonedMediastreamAndStop[] =
41    "renderClonedMediastreamAndStop";
42static const char kRenderClonedTrackMediastreamAndStop[] =
43    "renderClonedTrackMediastreamAndStop";
44static const char kRenderDuplicatedMediastreamAndStop[] =
45    "renderDuplicatedMediastreamAndStop";
46
47// Results returned by JS.
48static const char kOK[] = "OK";
49
50std::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 + "\"}}, ";
56
57  const std::string video_constraint =
58      "video: {mandatory: { sourceId:\"" + video_source_id + "\"}}";
59  return function_name + "({" + audio_constraint + video_constraint + "});";
60}
61
62std::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 + "\"}]}, ";
68
69  const std::string video_constraint =
70      "video: {optional: [{ sourceId:\"" + video_source_id + "\"}]}";
71  return function_name + "({" + audio_constraint + video_constraint + "});";
72}
73
74}  // namespace
75
76namespace content {
77
78class WebRtcGetUserMediaBrowserTest: public WebRtcContentBrowserTest {
79 public:
80  WebRtcGetUserMediaBrowserTest() : trace_log_(NULL) {}
81  virtual ~WebRtcGetUserMediaBrowserTest() {}
82
83  void StartTracing() {
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,
90                           trace_options);
91    // Check that we are indeed recording.
92    EXPECT_EQ(trace_log_->GetNumTracesRecorded(), 1);
93  }
94
95  void StopTracing() {
96    CHECK(message_loop_runner_.get() == NULL)
97        << "Calling StopTracing more than once";
98    trace_log_->SetDisabled();
99    message_loop_runner_ = new MessageLoopRunner;
100    trace_log_->Flush(base::Bind(
101        &WebRtcGetUserMediaBrowserTest::OnTraceDataCollected,
102        base::Unretained(this)));
103    message_loop_runner_->Run();
104  }
105
106  void OnTraceDataCollected(
107      const scoped_refptr<base::RefCountedString>& events_str_ptr,
108      bool has_more_events) {
109    CHECK(!has_more_events);
110    recorded_trace_data_ = events_str_ptr;
111    message_loop_runner_->Quit();
112  }
113
114  TraceAnalyzer* CreateTraceAnalyzer() {
115    return TraceAnalyzer::Create("[" + recorded_trace_data_->data() + "]");
116  }
117
118  void RunGetUserMediaAndCollectMeasures(const int time_to_sample_secs,
119                                         const std::string& measure_filter,
120                                         const std::string& graph_name) {
121    ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
122
123    GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
124    NavigateToURL(shell(), url);
125
126    // Put getUserMedia to work and let it run for a couple of seconds.
127    DCHECK(time_to_sample_secs);
128    ExecuteJavascriptAndWaitForOk(
129        base::StringPrintf("%s({video: true});",
130                           kGetUserMediaAndGetStreamUp));
131
132    // Now the stream is up and running, start collecting traces.
133    StartTracing();
134
135    // Let the stream run for a while in javascript.
136    ExecuteJavascriptAndWaitForOk(
137        base::StringPrintf("waitAndStopVideoTrack(%d);", time_to_sample_secs));
138
139    // Wait until the page title changes to "OK". Do not sleep() here since that
140    // would stop both this code and the browser underneath.
141    StopTracing();
142
143    scoped_ptr<TraceAnalyzer> analyzer(CreateTraceAnalyzer());
144    analyzer->AssociateBeginEndEvents();
145    trace_analyzer::TraceEventVector events;
146    DCHECK(measure_filter.size());
147    analyzer->FindEvents(
148        Query::EventNameIs(measure_filter),
149        &events);
150    ASSERT_GT(events.size(), 0u)
151        << "Could not collect any samples during test, this is bad";
152
153    std::string duration_us;
154    std::string interarrival_us;
155    for (size_t i = 0; i != events.size(); ++i) {
156      duration_us.append(
157          base::StringPrintf("%d,", static_cast<int>(events[i]->duration)));
158    }
159
160    for (size_t i = 1; i < events.size(); ++i) {
161      // The event |timestamp| comes in ns, divide to get us like |duration|.
162      interarrival_us.append(base::StringPrintf("%d,",
163          static_cast<int>((events[i]->timestamp - events[i - 1]->timestamp) /
164                           base::Time::kNanosecondsPerMicrosecond)));
165    }
166
167    perf_test::PrintResultList(
168        graph_name, "", "sample_duration", duration_us, "us", true);
169
170    perf_test::PrintResultList(
171        graph_name, "", "interarrival_time", interarrival_us, "us", true);
172  }
173
174  // Runs the JavaScript twoGetUserMedia with |constraints1| and |constraint2|.
175  void RunTwoGetTwoGetUserMediaWithDifferentContraints(
176      const std::string& constraints1,
177      const std::string& constraints2,
178      const std::string& expected_result) {
179    ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
180
181    GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
182    NavigateToURL(shell(), url);
183
184    std::string command = "twoGetUserMedia(" + constraints1 + ',' +
185        constraints2 + ')';
186
187    EXPECT_EQ(expected_result, ExecuteJavascriptAndReturnResult(command));
188  }
189
190  void GetInputDevices(std::vector<std::string>* audio_ids,
191                       std::vector<std::string>* video_ids) {
192    GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
193    NavigateToURL(shell(), url);
194
195    std::string devices_as_json = ExecuteJavascriptAndReturnResult(
196        "getSources()");
197    EXPECT_FALSE(devices_as_json.empty());
198
199    int error_code;
200    std::string error_message;
201    scoped_ptr<base::Value> value(
202        base::JSONReader::ReadAndReturnError(devices_as_json,
203                                             base::JSON_ALLOW_TRAILING_COMMAS,
204                                             &error_code,
205                                             &error_message));
206
207    ASSERT_TRUE(value.get() != NULL) << error_message;
208    EXPECT_EQ(value->GetType(), base::Value::TYPE_LIST);
209
210    base::ListValue* values;
211    ASSERT_TRUE(value->GetAsList(&values));
212
213    for (base::ListValue::iterator it = values->begin();
214         it != values->end(); ++it) {
215      const base::DictionaryValue* dict;
216      std::string kind;
217      std::string device_id;
218      ASSERT_TRUE((*it)->GetAsDictionary(&dict));
219      ASSERT_TRUE(dict->GetString("kind", &kind));
220      ASSERT_TRUE(dict->GetString("id", &device_id));
221      ASSERT_FALSE(device_id.empty());
222      EXPECT_TRUE(kind == "audio" || kind == "video");
223      if (kind == "audio") {
224        audio_ids->push_back(device_id);
225      } else if (kind == "video") {
226        video_ids->push_back(device_id);
227      }
228    }
229    ASSERT_FALSE(audio_ids->empty());
230    ASSERT_FALSE(video_ids->empty());
231  }
232
233 private:
234  base::debug::TraceLog* trace_log_;
235  scoped_refptr<base::RefCountedString> recorded_trace_data_;
236  scoped_refptr<MessageLoopRunner> message_loop_runner_;
237};
238
239// These tests will all make a getUserMedia call with different constraints and
240// see that the success callback is called. If the error callback is called or
241// none of the callbacks are called the tests will simply time out and fail.
242IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest, GetVideoStreamAndStop) {
243  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
244
245  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
246  NavigateToURL(shell(), url);
247
248  ExecuteJavascriptAndWaitForOk(
249      base::StringPrintf("%s({video: true});", kGetUserMediaAndStop));
250}
251
252IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
253                       RenderSameTrackMediastreamAndStop) {
254  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
255
256  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
257  NavigateToURL(shell(), url);
258
259  ExecuteJavascriptAndWaitForOk(
260      base::StringPrintf("%s({video: true});",
261                         kRenderSameTrackMediastreamAndStop));
262}
263
264IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
265                       RenderClonedMediastreamAndStop) {
266  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
267
268  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
269  NavigateToURL(shell(), url);
270
271
272  ExecuteJavascriptAndWaitForOk(
273      base::StringPrintf("%s({video: true});",
274                         kRenderClonedMediastreamAndStop));
275}
276
277IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
278                       kRenderClonedTrackMediastreamAndStop) {
279  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
280
281  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
282  NavigateToURL(shell(), url);
283
284  ExecuteJavascriptAndWaitForOk(
285      base::StringPrintf("%s({video: true});",
286                         kRenderClonedTrackMediastreamAndStop));
287}
288
289IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
290                       kRenderDuplicatedMediastreamAndStop) {
291  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
292
293  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
294  NavigateToURL(shell(), url);
295
296  ExecuteJavascriptAndWaitForOk(
297      base::StringPrintf("%s({video: true});",
298                          kRenderDuplicatedMediastreamAndStop));
299}
300
301// Flaky on Android.  http://crbug.com/387895
302#if defined(OS_ANDROID)
303#define MAYBE_GetAudioAndVideoStreamAndStop DISABLED_GetAudioAndVideoStreamAndStop
304#else
305#define MAYBE_GetAudioAndVideoStreamAndStop GetAudioAndVideoStreamAndStop
306#endif
307
308IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
309                       MAYBE_GetAudioAndVideoStreamAndStop) {
310  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
311
312  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
313  NavigateToURL(shell(), url);
314
315  ExecuteJavascriptAndWaitForOk(base::StringPrintf(
316      "%s({video: true, audio: true});", kGetUserMediaAndStop));
317}
318
319IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
320                       GetAudioAndVideoStreamAndClone) {
321  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
322
323  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
324  NavigateToURL(shell(), url);
325
326  ExecuteJavascriptAndWaitForOk("getUserMediaAndClone();");
327}
328
329IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
330                       RenderVideoTrackInMultipleTagsAndPause) {
331  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
332
333  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
334  NavigateToURL(shell(), url);
335
336  ExecuteJavascriptAndWaitForOk("getUserMediaAndRenderInSeveralVideoTags();");
337}
338
339
340
341IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
342                       GetUserMediaWithMandatorySourceID) {
343  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
344
345  std::vector<std::string> audio_ids;
346  std::vector<std::string> video_ids;
347  GetInputDevices(&audio_ids, &video_ids);
348
349  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
350
351  // Test all combinations of mandatory sourceID;
352  for (std::vector<std::string>::const_iterator video_it = video_ids.begin();
353       video_it != video_ids.end(); ++video_it) {
354    for (std::vector<std::string>::const_iterator audio_it = audio_ids.begin();
355         audio_it != audio_ids.end(); ++audio_it) {
356      NavigateToURL(shell(), url);
357      EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
358          GenerateGetUserMediaWithMandatorySourceID(
359              kGetUserMediaAndStop,
360              *audio_it,
361              *video_it)));
362    }
363  }
364}
365
366IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
367                       GetUserMediaWithInvalidMandatorySourceID) {
368  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
369
370  std::vector<std::string> audio_ids;
371  std::vector<std::string> video_ids;
372  GetInputDevices(&audio_ids, &video_ids);
373
374  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
375
376  // Test with invalid mandatory audio sourceID.
377  NavigateToURL(shell(), url);
378  EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult(
379      GenerateGetUserMediaWithMandatorySourceID(
380          kGetUserMediaAndExpectFailure,
381          "something invalid",
382          video_ids[0])));
383
384  // Test with invalid mandatory video sourceID.
385  EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult(
386      GenerateGetUserMediaWithMandatorySourceID(
387          kGetUserMediaAndExpectFailure,
388          audio_ids[0],
389          "something invalid")));
390
391  // Test with empty mandatory audio sourceID.
392  EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult(
393      GenerateGetUserMediaWithMandatorySourceID(
394          kGetUserMediaAndExpectFailure,
395          "",
396          video_ids[0])));
397}
398
399IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
400                       GetUserMediaWithInvalidOptionalSourceID) {
401  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
402
403  std::vector<std::string> audio_ids;
404  std::vector<std::string> video_ids;
405  GetInputDevices(&audio_ids, &video_ids);
406
407  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
408
409  // Test with invalid optional audio sourceID.
410  NavigateToURL(shell(), url);
411  EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
412      GenerateGetUserMediaWithOptionalSourceID(
413          kGetUserMediaAndStop,
414          "something invalid",
415          video_ids[0])));
416
417  // Test with invalid optional video sourceID.
418  EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
419      GenerateGetUserMediaWithOptionalSourceID(
420          kGetUserMediaAndStop,
421          audio_ids[0],
422          "something invalid")));
423
424  // Test with empty optional audio sourceID.
425  EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
426      GenerateGetUserMediaWithOptionalSourceID(
427          kGetUserMediaAndStop,
428          "",
429          video_ids[0])));
430}
431
432IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest, TwoGetUserMediaAndStop) {
433  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
434
435  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
436  NavigateToURL(shell(), url);
437
438  ExecuteJavascriptAndWaitForOk(
439      "twoGetUserMediaAndStop({video: true, audio: true});");
440}
441
442#if defined(OS_WIN) && !defined(NDEBUG)
443// Flaky on Webkit Win7 Debug bot: http://crbug.com/417756
444#define MAYBE_TwoGetUserMediaWithEqualConstraints \
445    DISABLED_TwoGetUserMediaWithEqualConstraints
446#else
447#define MAYBE_TwoGetUserMediaWithEqualConstraints \
448    TwoGetUserMediaWithEqualConstraints
449#endif
450IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
451                       MAYBE_TwoGetUserMediaWithEqualConstraints) {
452  std::string constraints1 = "{video: true, audio: true}";
453  const std::string& constraints2 = constraints1;
454  std::string expected_result = "w=640:h=480-w=640:h=480";
455
456  RunTwoGetTwoGetUserMediaWithDifferentContraints(constraints1, constraints2,
457                                                  expected_result);
458}
459
460IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
461                       TwoGetUserMediaWithSecondVideoCropped) {
462  std::string constraints1 = "{video: true}";
463  std::string constraints2 = "{video: {mandatory: {maxHeight: 360}}}";
464  std::string expected_result = "w=640:h=480-w=640:h=360";
465  RunTwoGetTwoGetUserMediaWithDifferentContraints(constraints1, constraints2,
466                                                  expected_result);
467}
468
469#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(NDEBUG))
470// Flaky on Windows and on Linux Debug: http://crbug.com/417756
471#define MAYBE_TwoGetUserMediaWithFirstHdSecondVga \
472    DISABLED_TwoGetUserMediaWithFirstHdSecondVga
473#else
474#define MAYBE_TwoGetUserMediaWithFirstHdSecondVga \
475    TwoGetUserMediaWithFirstHdSecondVga
476#endif
477IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
478                       MAYBE_TwoGetUserMediaWithFirstHdSecondVga) {
479  std::string constraints1 =
480      "{video: {mandatory: {minWidth:1280 , minHeight: 720}}}";
481  std::string constraints2 =
482      "{video: {mandatory: {maxWidth:640 , maxHeight: 480}}}";
483  std::string expected_result = "w=1280:h=720-w=640:h=480";
484  RunTwoGetTwoGetUserMediaWithDifferentContraints(constraints1, constraints2,
485                                                  expected_result);
486}
487
488IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
489                       TwoGetUserMediaAndVerifyFrameRate) {
490  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
491
492  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
493  NavigateToURL(shell(), url);
494
495  std::string constraints1 =
496      "{video: {mandatory: {minWidth:640 , minHeight: 480, "
497      "minFrameRate : 15, maxFrameRate : 15}}}";
498  std::string constraints2 =
499      "{video: {mandatory: {maxWidth:320 , maxHeight: 240,"
500      "minFrameRate : 7, maxFrameRate : 7}}}";
501
502  std::string command = "twoGetUserMediaAndVerifyFrameRate(" +
503      constraints1 + ',' + constraints2 + ", 15, 7)";
504  ExecuteJavascriptAndWaitForOk(command);
505}
506
507IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
508                       GetUserMediaWithTooHighVideoConstraintsValues) {
509  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
510
511  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
512
513  int large_value = 99999;
514  std::string call = GenerateGetUserMediaCall(kGetUserMediaAndExpectFailure,
515                                              large_value,
516                                              large_value,
517                                              large_value,
518                                              large_value,
519                                              large_value,
520                                              large_value);
521  NavigateToURL(shell(), url);
522
523  EXPECT_EQ("ConstraintNotSatisfiedError",
524            ExecuteJavascriptAndReturnResult(call));
525}
526
527// This test will make a simple getUserMedia page, verify that video is playing
528// in a simple local <video>, and for a couple of seconds, collect some
529// performance traces from VideoCaptureController colorspace conversion and
530// potential resizing.
531IN_PROC_BROWSER_TEST_F(
532    WebRtcGetUserMediaBrowserTest,
533    TraceVideoCaptureControllerPerformanceDuringGetUserMedia) {
534  RunGetUserMediaAndCollectMeasures(
535      10,
536      "VideoCaptureController::OnIncomingCapturedData",
537      "VideoCaptureController");
538}
539
540// This test calls getUserMedia and checks for aspect ratio behavior.
541IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
542                       TestGetUserMediaAspectRatio4To3) {
543  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
544
545  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
546
547  std::string constraints_4_3 = GenerateGetUserMediaCall(
548      kGetUserMediaAndAnalyseAndStop, 640, 640, 480, 480, 10, 30);
549
550  NavigateToURL(shell(), url);
551  ASSERT_EQ("w=640:h=480",
552            ExecuteJavascriptAndReturnResult(constraints_4_3));
553}
554
555// This test calls getUserMedia and checks for aspect ratio behavior.
556IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
557                       TestGetUserMediaAspectRatio16To9) {
558  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
559
560  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
561
562  std::string constraints_16_9 = GenerateGetUserMediaCall(
563      kGetUserMediaAndAnalyseAndStop, 640, 640, 360, 360, 10, 30);
564
565  NavigateToURL(shell(), url);
566  ASSERT_EQ("w=640:h=360",
567            ExecuteJavascriptAndReturnResult(constraints_16_9));
568}
569
570// This test calls getUserMedia and checks for aspect ratio behavior.
571IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
572                       TestGetUserMediaAspectRatio1To1) {
573  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
574
575  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
576
577  std::string constraints_1_1 = GenerateGetUserMediaCall(
578      kGetUserMediaAndAnalyseAndStop, 320, 320, 320, 320, 10, 30);
579
580  NavigateToURL(shell(), url);
581  ASSERT_EQ("w=320:h=320",
582            ExecuteJavascriptAndReturnResult(constraints_1_1));
583}
584
585namespace {
586
587struct UserMediaSizes {
588  int min_width;
589  int max_width;
590  int min_height;
591  int max_height;
592  int min_frame_rate;
593  int max_frame_rate;
594};
595
596}  // namespace
597
598class WebRtcConstraintsBrowserTest
599    : public WebRtcContentBrowserTest,
600      public testing::WithParamInterface<UserMediaSizes> {
601 public:
602  WebRtcConstraintsBrowserTest() : user_media_(GetParam()) {}
603  const UserMediaSizes& user_media() const { return user_media_; }
604
605 private:
606  UserMediaSizes user_media_;
607};
608
609// This test calls getUserMedia in sequence with different constraints.
610IN_PROC_BROWSER_TEST_P(WebRtcConstraintsBrowserTest, GetUserMediaConstraints) {
611  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
612
613  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
614
615  std::string call = GenerateGetUserMediaCall(kGetUserMediaAndStop,
616                                              user_media().min_width,
617                                              user_media().max_width,
618                                              user_media().min_height,
619                                              user_media().max_height,
620                                              user_media().min_frame_rate,
621                                              user_media().max_frame_rate);
622  DVLOG(1) << "Calling getUserMedia: " << call;
623  NavigateToURL(shell(), url);
624  ExecuteJavascriptAndWaitForOk(call);
625}
626
627static const UserMediaSizes kAllUserMediaSizes[] = {
628    {320, 320, 180, 180, 10, 30},
629    {320, 320, 240, 240, 10, 30},
630    {640, 640, 360, 360, 10, 30},
631    {640, 640, 480, 480, 10, 30},
632    {960, 960, 720, 720, 10, 30},
633    {1280, 1280, 720, 720, 10, 30}};
634
635INSTANTIATE_TEST_CASE_P(UserMedia,
636                        WebRtcConstraintsBrowserTest,
637                        testing::ValuesIn(kAllUserMediaSizes));
638
639}  // namespace content
640