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