summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/media/webrtc_getusermedia_browsertest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/media/webrtc_getusermedia_browsertest.cc')
-rw-r--r--chromium/content/browser/media/webrtc_getusermedia_browsertest.cc607
1 files changed, 607 insertions, 0 deletions
diff --git a/chromium/content/browser/media/webrtc_getusermedia_browsertest.cc b/chromium/content/browser/media/webrtc_getusermedia_browsertest.cc
new file mode 100644
index 00000000000..c7e1b4214e5
--- /dev/null
+++ b/chromium/content/browser/media/webrtc_getusermedia_browsertest.cc
@@ -0,0 +1,607 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "base/debug/trace_event_impl.h"
+#include "base/json/json_reader.h"
+#include "base/strings/stringprintf.h"
+#include "base/test/trace_event_analyzer.h"
+#include "base/values.h"
+#include "content/browser/media/webrtc_internals.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/webrtc_content_browsertest_base.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "testing/perf/perf_test.h"
+
+#if defined(OS_WIN)
+#include "base/win/windows_version.h"
+#endif
+
+using trace_analyzer::TraceAnalyzer;
+using trace_analyzer::Query;
+using trace_analyzer::TraceEventVector;
+
+namespace {
+
+static const char kGetUserMediaAndStop[] = "getUserMediaAndStop";
+static const char kGetUserMediaAndGetStreamUp[] = "getUserMediaAndGetStreamUp";
+static const char kGetUserMediaAndAnalyseAndStop[] =
+ "getUserMediaAndAnalyseAndStop";
+static const char kGetUserMediaAndExpectFailure[] =
+ "getUserMediaAndExpectFailure";
+static const char kRenderSameTrackMediastreamAndStop[] =
+ "renderSameTrackMediastreamAndStop";
+static const char kRenderClonedMediastreamAndStop[] =
+ "renderClonedMediastreamAndStop";
+static const char kRenderClonedTrackMediastreamAndStop[] =
+ "renderClonedTrackMediastreamAndStop";
+static const char kRenderDuplicatedMediastreamAndStop[] =
+ "renderDuplicatedMediastreamAndStop";
+
+// Results returned by JS.
+static const char kOK[] = "OK";
+
+std::string GenerateGetUserMediaWithMandatorySourceID(
+ const std::string& function_name,
+ const std::string& audio_source_id,
+ const std::string& video_source_id) {
+ const std::string audio_constraint =
+ "audio: {mandatory: { sourceId:\"" + audio_source_id + "\"}}, ";
+
+ const std::string video_constraint =
+ "video: {mandatory: { sourceId:\"" + video_source_id + "\"}}";
+ return function_name + "({" + audio_constraint + video_constraint + "});";
+}
+
+std::string GenerateGetUserMediaWithOptionalSourceID(
+ const std::string& function_name,
+ const std::string& audio_source_id,
+ const std::string& video_source_id) {
+ const std::string audio_constraint =
+ "audio: {optional: [{sourceId:\"" + audio_source_id + "\"}]}, ";
+
+ const std::string video_constraint =
+ "video: {optional: [{ sourceId:\"" + video_source_id + "\"}]}";
+ return function_name + "({" + audio_constraint + video_constraint + "});";
+}
+
+} // namespace
+
+namespace content {
+
+class WebRtcGetUserMediaBrowserTest: public WebRtcContentBrowserTest,
+ public testing::WithParamInterface<bool> {
+ public:
+ WebRtcGetUserMediaBrowserTest() : trace_log_(NULL) {}
+ virtual ~WebRtcGetUserMediaBrowserTest() {}
+
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ WebRtcContentBrowserTest::SetUpCommandLine(command_line);
+
+ bool enable_audio_track_processing = GetParam();
+ if (!enable_audio_track_processing)
+ command_line->AppendSwitch(switches::kDisableAudioTrackProcessing);
+ }
+
+ void StartTracing() {
+ CHECK(trace_log_ == NULL) << "Can only can start tracing once";
+ trace_log_ = base::debug::TraceLog::GetInstance();
+ trace_log_->SetEnabled(base::debug::CategoryFilter("video"),
+ base::debug::TraceLog::RECORDING_MODE,
+ base::debug::TraceLog::ENABLE_SAMPLING);
+ // Check that we are indeed recording.
+ EXPECT_EQ(trace_log_->GetNumTracesRecorded(), 1);
+ }
+
+ void StopTracing() {
+ CHECK(message_loop_runner_ == NULL) << "Calling StopTracing more than once";
+ trace_log_->SetDisabled();
+ message_loop_runner_ = new MessageLoopRunner;
+ trace_log_->Flush(base::Bind(
+ &WebRtcGetUserMediaBrowserTest::OnTraceDataCollected,
+ base::Unretained(this)));
+ message_loop_runner_->Run();
+ }
+
+ void OnTraceDataCollected(
+ const scoped_refptr<base::RefCountedString>& events_str_ptr,
+ bool has_more_events) {
+ CHECK(!has_more_events);
+ recorded_trace_data_ = events_str_ptr;
+ message_loop_runner_->Quit();
+ }
+
+ TraceAnalyzer* CreateTraceAnalyzer() {
+ return TraceAnalyzer::Create("[" + recorded_trace_data_->data() + "]");
+ }
+
+ void RunGetUserMediaAndCollectMeasures(const int time_to_sample_secs,
+ const std::string& measure_filter,
+ const std::string& graph_name) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ // Put getUserMedia to work and let it run for a couple of seconds.
+ DCHECK(time_to_sample_secs);
+ ExecuteJavascriptAndWaitForOk(
+ base::StringPrintf("%s({video: true});",
+ kGetUserMediaAndGetStreamUp));
+
+ // Now the stream is up and running, start collecting traces.
+ StartTracing();
+
+ // Let the stream run for a while in javascript.
+ ExecuteJavascriptAndWaitForOk(
+ base::StringPrintf("waitAndStopVideoTrack(%d);", time_to_sample_secs));
+
+ // Wait until the page title changes to "OK". Do not sleep() here since that
+ // would stop both this code and the browser underneath.
+ StopTracing();
+
+ scoped_ptr<TraceAnalyzer> analyzer(CreateTraceAnalyzer());
+ analyzer->AssociateBeginEndEvents();
+ trace_analyzer::TraceEventVector events;
+ DCHECK(measure_filter.size());
+ analyzer->FindEvents(
+ Query::EventNameIs(measure_filter),
+ &events);
+ ASSERT_GT(events.size(), 0u)
+ << "Could not collect any samples during test, this is bad";
+
+ std::string duration_us;
+ std::string interarrival_us;
+ for (size_t i = 0; i != events.size(); ++i) {
+ duration_us.append(
+ base::StringPrintf("%d,", static_cast<int>(events[i]->duration)));
+ }
+
+ for (size_t i = 1; i < events.size(); ++i) {
+ // The event |timestamp| comes in ns, divide to get us like |duration|.
+ interarrival_us.append(base::StringPrintf("%d,",
+ static_cast<int>((events[i]->timestamp - events[i - 1]->timestamp) /
+ base::Time::kNanosecondsPerMicrosecond)));
+ }
+
+ perf_test::PrintResultList(
+ graph_name, "", "sample_duration", duration_us, "us", true);
+
+ perf_test::PrintResultList(
+ graph_name, "", "interarrival_time", interarrival_us, "us", true);
+ }
+
+ void RunTwoGetTwoGetUserMediaWithDifferentContraints(
+ const std::string& constraints1,
+ const std::string& constraints2,
+ const std::string& expected_result) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ std::string command = "twoGetUserMedia(" + constraints1 + ',' +
+ constraints2 + ')';
+
+ EXPECT_EQ(expected_result, ExecuteJavascriptAndReturnResult(command));
+ }
+
+ void GetInputDevices(std::vector<std::string>* audio_ids,
+ std::vector<std::string>* video_ids) {
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ std::string devices_as_json = ExecuteJavascriptAndReturnResult(
+ "getSources()");
+ EXPECT_FALSE(devices_as_json.empty());
+
+ int error_code;
+ std::string error_message;
+ scoped_ptr<base::Value> value(
+ base::JSONReader::ReadAndReturnError(devices_as_json,
+ base::JSON_ALLOW_TRAILING_COMMAS,
+ &error_code,
+ &error_message));
+
+ ASSERT_TRUE(value.get() != NULL) << error_message;
+ EXPECT_EQ(value->GetType(), base::Value::TYPE_LIST);
+
+ base::ListValue* values;
+ ASSERT_TRUE(value->GetAsList(&values));
+
+ for (base::ListValue::iterator it = values->begin();
+ it != values->end(); ++it) {
+ const base::DictionaryValue* dict;
+ std::string kind;
+ std::string device_id;
+ ASSERT_TRUE((*it)->GetAsDictionary(&dict));
+ ASSERT_TRUE(dict->GetString("kind", &kind));
+ ASSERT_TRUE(dict->GetString("id", &device_id));
+ ASSERT_FALSE(device_id.empty());
+ EXPECT_TRUE(kind == "audio" || kind == "video");
+ if (kind == "audio") {
+ audio_ids->push_back(device_id);
+ } else if (kind == "video") {
+ video_ids->push_back(device_id);
+ }
+ }
+ ASSERT_FALSE(audio_ids->empty());
+ ASSERT_FALSE(video_ids->empty());
+ }
+
+ private:
+ base::debug::TraceLog* trace_log_;
+ scoped_refptr<base::RefCountedString> recorded_trace_data_;
+ scoped_refptr<MessageLoopRunner> message_loop_runner_;
+};
+
+static const bool kRunTestsWithFlag[] = { false, true };
+INSTANTIATE_TEST_CASE_P(WebRtcGetUserMediaBrowserTests,
+ WebRtcGetUserMediaBrowserTest,
+ testing::ValuesIn(kRunTestsWithFlag));
+
+// These tests will all make a getUserMedia call with different constraints and
+// see that the success callback is called. If the error callback is called or
+// none of the callbacks are called the tests will simply time out and fail.
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest, GetVideoStreamAndStop) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ ExecuteJavascriptAndWaitForOk(
+ base::StringPrintf("%s({video: true});", kGetUserMediaAndStop));
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ RenderSameTrackMediastreamAndStop) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ ExecuteJavascriptAndWaitForOk(
+ base::StringPrintf("%s({video: true});",
+ kRenderSameTrackMediastreamAndStop));
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ RenderClonedMediastreamAndStop) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+
+ ExecuteJavascriptAndWaitForOk(
+ base::StringPrintf("%s({video: true});",
+ kRenderClonedMediastreamAndStop));
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ kRenderClonedTrackMediastreamAndStop) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ ExecuteJavascriptAndWaitForOk(
+ base::StringPrintf("%s({video: true});",
+ kRenderClonedTrackMediastreamAndStop));
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ kRenderDuplicatedMediastreamAndStop) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ ExecuteJavascriptAndWaitForOk(
+ base::StringPrintf("%s({video: true});",
+ kRenderDuplicatedMediastreamAndStop));
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ GetAudioAndVideoStreamAndStop) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ ExecuteJavascriptAndWaitForOk(base::StringPrintf(
+ "%s({video: true, audio: true});", kGetUserMediaAndStop));
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ GetAudioAndVideoStreamAndClone) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ ExecuteJavascriptAndWaitForOk("getUserMediaAndClone();");
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ RenderVideoTrackInMultipleTagsAndPause) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ ExecuteJavascriptAndWaitForOk("getUserMediaAndRenderInSeveralVideoTags();");
+}
+
+
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ GetUserMediaWithMandatorySourceID) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ std::vector<std::string> audio_ids;
+ std::vector<std::string> video_ids;
+ GetInputDevices(&audio_ids, &video_ids);
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+
+ // Test all combinations of mandatory sourceID;
+ for (std::vector<std::string>::const_iterator video_it = video_ids.begin();
+ video_it != video_ids.end(); ++video_it) {
+ for (std::vector<std::string>::const_iterator audio_it = audio_ids.begin();
+ audio_it != audio_ids.end(); ++audio_it) {
+ NavigateToURL(shell(), url);
+ EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
+ GenerateGetUserMediaWithMandatorySourceID(
+ kGetUserMediaAndStop,
+ *audio_it,
+ *video_it)));
+ }
+ }
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ GetUserMediaWithInvalidMandatorySourceID) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ std::vector<std::string> audio_ids;
+ std::vector<std::string> video_ids;
+ GetInputDevices(&audio_ids, &video_ids);
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+
+ // Test with invalid mandatory audio sourceID.
+ NavigateToURL(shell(), url);
+ EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult(
+ GenerateGetUserMediaWithMandatorySourceID(
+ kGetUserMediaAndExpectFailure,
+ "something invalid",
+ video_ids[0])));
+
+ // Test with invalid mandatory video sourceID.
+ EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult(
+ GenerateGetUserMediaWithMandatorySourceID(
+ kGetUserMediaAndExpectFailure,
+ audio_ids[0],
+ "something invalid")));
+
+ // Test with empty mandatory audio sourceID.
+ EXPECT_EQ("DevicesNotFoundError", ExecuteJavascriptAndReturnResult(
+ GenerateGetUserMediaWithMandatorySourceID(
+ kGetUserMediaAndExpectFailure,
+ "",
+ video_ids[0])));
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ GetUserMediaWithInvalidOptionalSourceID) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ std::vector<std::string> audio_ids;
+ std::vector<std::string> video_ids;
+ GetInputDevices(&audio_ids, &video_ids);
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+
+ // Test with invalid optional audio sourceID.
+ NavigateToURL(shell(), url);
+ EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
+ GenerateGetUserMediaWithOptionalSourceID(
+ kGetUserMediaAndStop,
+ "something invalid",
+ video_ids[0])));
+
+ // Test with invalid optional video sourceID.
+ EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
+ GenerateGetUserMediaWithOptionalSourceID(
+ kGetUserMediaAndStop,
+ audio_ids[0],
+ "something invalid")));
+
+ // Test with empty optional audio sourceID.
+ EXPECT_EQ(kOK, ExecuteJavascriptAndReturnResult(
+ GenerateGetUserMediaWithOptionalSourceID(
+ kGetUserMediaAndStop,
+ "",
+ video_ids[0])));
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest, TwoGetUserMediaAndStop) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ ExecuteJavascriptAndWaitForOk(
+ "twoGetUserMediaAndStop({video: true, audio: true});");
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ TwoGetUserMediaWithEqualConstraints) {
+ std::string constraints1 = "{video: true, audio: true}";
+ const std::string& constraints2 = constraints1;
+ std::string expected_result = "w=640:h=480-w=640:h=480";
+
+ RunTwoGetTwoGetUserMediaWithDifferentContraints(constraints1, constraints2,
+ expected_result);
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ TwoGetUserMediaWithSecondVideoCropped) {
+ std::string constraints1 = "{video: true}";
+ std::string constraints2 = "{video: {mandatory: {maxHeight: 360}}}";
+ std::string expected_result = "w=640:h=480-w=640:h=360";
+ RunTwoGetTwoGetUserMediaWithDifferentContraints(constraints1, constraints2,
+ expected_result);
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ TwoGetUserMediaWithFirstHdSecondVga) {
+ std::string constraints1 =
+ "{video: {mandatory: {minWidth:1280 , minHeight: 720}}}";
+ std::string constraints2 =
+ "{video: {mandatory: {maxWidth:640 , maxHeight: 480}}}";
+ std::string expected_result = "w=1280:h=720-w=640:h=480";
+ RunTwoGetTwoGetUserMediaWithDifferentContraints(constraints1, constraints2,
+ expected_result);
+}
+
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ GetUserMediaWithTooHighVideoConstraintsValues) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+
+ int large_value = 99999;
+ std::string call = GenerateGetUserMediaCall(kGetUserMediaAndExpectFailure,
+ large_value,
+ large_value,
+ large_value,
+ large_value,
+ large_value,
+ large_value);
+ NavigateToURL(shell(), url);
+
+ // TODO(perkj): A proper error code should be returned by gUM.
+ EXPECT_EQ("TrackStartError", ExecuteJavascriptAndReturnResult(call));
+}
+
+// This test will make a simple getUserMedia page, verify that video is playing
+// in a simple local <video>, and for a couple of seconds, collect some
+// performance traces from VideoCaptureController colorspace conversion and
+// potential resizing.
+IN_PROC_BROWSER_TEST_P(
+ WebRtcGetUserMediaBrowserTest,
+ TraceVideoCaptureControllerPerformanceDuringGetUserMedia) {
+ RunGetUserMediaAndCollectMeasures(
+ 10,
+ "VideoCaptureController::OnIncomingCapturedData",
+ "VideoCaptureController");
+}
+
+// This test calls getUserMedia and checks for aspect ratio behavior.
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ TestGetUserMediaAspectRatio4To3) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+
+ std::string constraints_4_3 = GenerateGetUserMediaCall(
+ kGetUserMediaAndAnalyseAndStop, 640, 640, 480, 480, 10, 30);
+
+ NavigateToURL(shell(), url);
+ ASSERT_EQ("w=640:h=480",
+ ExecuteJavascriptAndReturnResult(constraints_4_3));
+}
+
+// This test calls getUserMedia and checks for aspect ratio behavior.
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ TestGetUserMediaAspectRatio16To9) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+
+ std::string constraints_16_9 = GenerateGetUserMediaCall(
+ kGetUserMediaAndAnalyseAndStop, 640, 640, 360, 360, 10, 30);
+
+ NavigateToURL(shell(), url);
+ ASSERT_EQ("w=640:h=360",
+ ExecuteJavascriptAndReturnResult(constraints_16_9));
+}
+
+// This test calls getUserMedia and checks for aspect ratio behavior.
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ TestGetUserMediaAspectRatio1To1) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+
+ std::string constraints_1_1 = GenerateGetUserMediaCall(
+ kGetUserMediaAndAnalyseAndStop, 320, 320, 320, 320, 10, 30);
+
+ NavigateToURL(shell(), url);
+ ASSERT_EQ("w=320:h=320",
+ ExecuteJavascriptAndReturnResult(constraints_1_1));
+}
+
+namespace {
+
+struct UserMediaSizes {
+ int min_width;
+ int max_width;
+ int min_height;
+ int max_height;
+ int min_frame_rate;
+ int max_frame_rate;
+};
+
+} // namespace
+
+class WebRtcConstraintsBrowserTest
+ : public WebRtcContentBrowserTest,
+ public testing::WithParamInterface<UserMediaSizes> {
+ public:
+ WebRtcConstraintsBrowserTest() : user_media_(GetParam()) {}
+ const UserMediaSizes& user_media() const { return user_media_; }
+
+ private:
+ UserMediaSizes user_media_;
+};
+
+// This test calls getUserMedia in sequence with different constraints.
+IN_PROC_BROWSER_TEST_P(WebRtcConstraintsBrowserTest, GetUserMediaConstraints) {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+
+ std::string call = GenerateGetUserMediaCall(kGetUserMediaAndStop,
+ user_media().min_width,
+ user_media().max_width,
+ user_media().min_height,
+ user_media().max_height,
+ user_media().min_frame_rate,
+ user_media().max_frame_rate);
+ DVLOG(1) << "Calling getUserMedia: " << call;
+ NavigateToURL(shell(), url);
+ ExecuteJavascriptAndWaitForOk(call);
+}
+
+static const UserMediaSizes kAllUserMediaSizes[] = {
+ {320, 320, 180, 180, 10, 30},
+ {320, 320, 240, 240, 10, 30},
+ {640, 640, 360, 360, 10, 30},
+ {640, 640, 480, 480, 10, 30},
+ {960, 960, 720, 720, 10, 30},
+ {1280, 1280, 720, 720, 10, 30}};
+
+INSTANTIATE_TEST_CASE_P(UserMedia,
+ WebRtcConstraintsBrowserTest,
+ testing::ValuesIn(kAllUserMediaSizes));
+
+} // namespace content