Split WebRTC browser tests in getusermedia and peerconnection tests.

The content browsertests file for WebRTC was growing a bit large. I
extracted the getUserMedia-focused tests into a test of its own and
left the peerconnection tests.

Also renamed all WebRTC content browsertests to use the WebRtc naming
convention, which seems to be the most common in the production code.

Note: this patch will require some filter renames on the WebRTC bots.

[email protected]

Review URL: https://codereview.chromium.org/131203005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245524 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/media/webrtc_aecdump_browsertest.cc b/content/browser/media/webrtc_aecdump_browsertest.cc
index cf98c4ba..1561738 100644
--- a/content/browser/media/webrtc_aecdump_browsertest.cc
+++ b/content/browser/media/webrtc_aecdump_browsertest.cc
@@ -4,23 +4,26 @@
 
 #include "base/command_line.h"
 #include "base/file_util.h"
+#include "base/json/json_reader.h"
 #include "base/platform_file.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/trace_event_analyzer.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/shell/browser/shell.h"
-#include "content/test/content_browser_test.h"
 #include "content/test/content_browser_test_utils.h"
+#include "content/test/webrtc_content_browsertest_base.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 
 namespace content {
 
 // This tests AEC dump enabled using the command line flag. It does not test AEC
 // dump enabled using webrtc-internals (that's tested in webrtc_browsertest.cc).
-class WebrtcAecDumpBrowserTest : public ContentBrowserTest {
+class WebRtcAecDumpBrowserTest : public WebRtcContentBrowserTest {
  public:
-  WebrtcAecDumpBrowserTest() {}
-  virtual ~WebrtcAecDumpBrowserTest() {}
+  WebRtcAecDumpBrowserTest() {}
+  virtual ~WebRtcAecDumpBrowserTest() {}
 
   virtual void SetUp() OVERRIDE {
     // Find a safe place to write the dump to.
@@ -34,12 +37,7 @@
   }
 
   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
-    // We need fake devices in this test since we want to run on naked VMs. We
-    // assume these switches are set by default in content_browsertests.
-    ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
-        switches::kUseFakeDeviceForMediaStream));
-    ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
-        switches::kUseFakeUIForMediaStream));
+    WebRtcContentBrowserTest::SetUpCommandLine(command_line);
 
     // Enable AEC dump with the command line flag.
     command_line->AppendSwitchPath(switches::kEnableWebRtcAecRecordings,
@@ -47,21 +45,11 @@
   }
 
  protected:
-  bool ExecuteJavascript(const std::string& javascript) {
-    return ExecuteScript(shell()->web_contents(), javascript);
-  }
-
-  void ExpectTitle(const std::string& expected_title) const {
-    base::string16 expected_title16(base::ASCIIToUTF16(expected_title));
-    TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
-    EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
-  }
-
   base::ScopedTempDir temp_dir_;
   base::FilePath dump_file_;
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(WebrtcAecDumpBrowserTest);
+  DISALLOW_COPY_AND_ASSIGN(WebRtcAecDumpBrowserTest);
 };
 
 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY))
@@ -75,7 +63,7 @@
 // This tests will make a complete PeerConnection-based call, verify that
 // video is playing for the call, and verify that a non-empty AEC dump file
 // exists.
-IN_PROC_BROWSER_TEST_F(WebrtcAecDumpBrowserTest, MAYBE_CallWithAecDump) {
+IN_PROC_BROWSER_TEST_F(WebRtcAecDumpBrowserTest, MAYBE_CallWithAecDump) {
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
 
   GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
diff --git a/content/browser/media/webrtc_browsertest.cc b/content/browser/media/webrtc_browsertest.cc
index 824c0c38..b1bed156 100644
--- a/content/browser/media/webrtc_browsertest.cc
+++ b/content/browser/media/webrtc_browsertest.cc
@@ -3,10 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
-#include "base/json/json_reader.h"
 #include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.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"
@@ -14,194 +11,21 @@
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
-#include "content/test/content_browser_test.h"
 #include "content/test/content_browser_test_utils.h"
+#include "content/test/webrtc_content_browsertest_base.h"
 #include "media/audio/audio_manager.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 kGetUserMediaAndWaitAndStop[] = "getUserMediaAndWaitAndStop";
-static const char kGetUserMediaAndAnalyseAndStop[] =
-    "getUserMediaAndAnalyseAndStop";
-
-// Results returned by JS.
-static const char kOK[] = "OK";
-static const char kGetUserMediaFailed[] =
-    "GetUserMedia call failed with code undefined";
-
-std::string GenerateGetUserMediaCall(const char* function_name,
-                                     int min_width,
-                                     int max_width,
-                                     int min_height,
-                                     int max_height,
-                                     int min_frame_rate,
-                                     int max_frame_rate) {
-  return base::StringPrintf(
-      "%s({video: {mandatory: {minWidth: %d, maxWidth: %d, "
-      "minHeight: %d, maxHeight: %d, minFrameRate: %d, maxFrameRate: %d}, "
-      "optional: []}});",
-      function_name,
-      min_width,
-      max_width,
-      min_height,
-      max_height,
-      min_frame_rate,
-      max_frame_rate);
-}
-
-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 content {
 
-class WebrtcBrowserTest: public ContentBrowserTest {
+class WebRtcBrowserTest : public WebRtcContentBrowserTest {
  public:
-  WebrtcBrowserTest() : trace_log_(NULL) {}
-  virtual ~WebrtcBrowserTest() {}
-
-  virtual void SetUp() OVERRIDE {
-    // These tests require pixel output.
-    UseRealGLContexts();
-    ContentBrowserTest::SetUp();
-  }
-
-  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
-    // We need fake devices in this test since we want to run on naked VMs. We
-    // assume these switches are set by default in content_browsertests.
-    ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
-        switches::kUseFakeDeviceForMediaStream));
-    ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
-        switches::kUseFakeUIForMediaStream));
-  }
-
-  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(&WebrtcBrowserTest::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 GetSources(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 sources_as_json = ExecuteJavascriptAndReturnResult(
-        "getSources()");
-    EXPECT_FALSE(sources_as_json.empty());
-
-    int error_code;
-    std::string error_message;
-    scoped_ptr<base::Value> value(
-        base::JSONReader::ReadAndReturnError(sources_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 id;
-      ASSERT_TRUE((*it)->GetAsDictionary(&dict));
-      ASSERT_TRUE(dict->GetString("kind", &kind));
-      ASSERT_TRUE(dict->GetString("id", &id));
-      ASSERT_FALSE(id.empty());
-      EXPECT_TRUE(kind == "audio" || kind == "video");
-      if (kind == "audio") {
-        audio_ids->push_back(id);
-      } else if (kind == "video") {
-        video_ids->push_back(id);
-      }
-    }
-    ASSERT_FALSE(audio_ids->empty());
-    ASSERT_FALSE(video_ids->empty());
-  }
-
- protected:
-  bool ExecuteJavascript(const std::string& javascript) {
-    return ExecuteScript(shell()->web_contents(), javascript);
-  }
-
-  // Executes |javascript|. The script is required to use
-  // window.domAutomationController.send to send a string value back to here.
-  std::string ExecuteJavascriptAndReturnResult(const std::string& javascript) {
-    std::string result;
-    EXPECT_TRUE(ExecuteScriptAndExtractString(shell()->web_contents(),
-                                              javascript,
-                                              &result));
-    return result;
-  }
-
-  void ExpectTitle(const std::string& expected_title) const {
-    base::string16 expected_title16(base::ASCIIToUTF16(expected_title));
-    TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
-    EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
-  }
+  WebRtcBrowserTest() {}
+  virtual ~WebRtcBrowserTest() {}
 
   // Convenience function since most peerconnection-call.html tests just load
   // the page, kick off some javascript and wait for the title to change to OK.
@@ -222,205 +46,8 @@
     ASSERT_TRUE(ExecuteJavascript(javascript));
     ExpectTitle("OK");
   }
-
- private:
-  base::debug::TraceLog* trace_log_;
-  scoped_refptr<base::RefCountedString> recorded_trace_data_;
-  scoped_refptr<MessageLoopRunner> message_loop_runner_;
 };
 
-// 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_F(WebrtcBrowserTest, GetVideoStreamAndStop) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
-  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
-  NavigateToURL(shell(), url);
-
-  ASSERT_TRUE(ExecuteJavascript(
-      base::StringPrintf("%s({video: true});", kGetUserMediaAndStop)));
-
-  ExpectTitle("OK");
-}
-
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetAudioAndVideoStreamAndStop) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
-  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
-  NavigateToURL(shell(), url);
-
-  ASSERT_TRUE(ExecuteJavascript(base::StringPrintf(
-      "%s({video: true, audio: true});", kGetUserMediaAndStop)));
-
-  ExpectTitle("OK");
-}
-
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetAudioAndVideoStreamAndClone) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
-  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
-  NavigateToURL(shell(), url);
-
-  ASSERT_TRUE(ExecuteJavascript("getUserMediaAndClone();"));
-
-  ExpectTitle("OK");
-}
-
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, TwoGetUserMediaAndStop) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
-  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
-  NavigateToURL(shell(), url);
-
-  ASSERT_TRUE(ExecuteJavascript(
-      "twoGetUserMediaAndStop({video: true, audio: true});"));
-
-  ExpectTitle("OK");
-}
-
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetUserMediaWithMandatorySourceID_1) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
-  std::vector<std::string> audio_ids;
-  std::vector<std::string> video_ids;
-  GetSources(&audio_ids, &video_ids);
-
-  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
-  NavigateToURL(shell(), url);
-
-  for (size_t j = 0; j < video_ids.size() / 2; ++j) {
-    for (size_t i = 0; i < audio_ids.size(); ++i) {
-      EXPECT_EQ(kOK,
-                ExecuteJavascriptAndReturnResult(
-                    GenerateGetUserMediaWithMandatorySourceID(
-                        kGetUserMediaAndStop, audio_ids[i], video_ids[j])));
-    }
-  }
-}
-
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetUserMediaWithMandatorySourceID_2) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
-  std::vector<std::string> audio_ids;
-  std::vector<std::string> video_ids;
-  GetSources(&audio_ids, &video_ids);
-
-  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
-  NavigateToURL(shell(), url);
-
-  for (size_t j = video_ids.size() / 2; j < video_ids.size(); ++j) {
-    for (size_t i = 0; i < audio_ids.size(); ++i) {
-      EXPECT_EQ(kOK,
-                ExecuteJavascriptAndReturnResult(
-                    GenerateGetUserMediaWithMandatorySourceID(
-                        kGetUserMediaAndStop, audio_ids[i], video_ids[j])));
-    }
-  }
-}
-
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
-                       GetUserMediaWithInvalidMandatorySourceID) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
-  std::vector<std::string> audio_ids;
-  std::vector<std::string> video_ids;
-  GetSources(&audio_ids, &video_ids);
-
-  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
-
-  // Test with invalid mandatory audio sourceID.
-  NavigateToURL(shell(), url);
-  EXPECT_EQ(kGetUserMediaFailed,
-            ExecuteJavascriptAndReturnResult(
-                GenerateGetUserMediaWithMandatorySourceID(
-                    kGetUserMediaAndStop, "something invalid", video_ids[0])));
-
-  // Test with invalid mandatory video sourceID.
-  EXPECT_EQ(kGetUserMediaFailed,
-            ExecuteJavascriptAndReturnResult(
-                GenerateGetUserMediaWithMandatorySourceID(
-                    kGetUserMediaAndStop, audio_ids[0], "something invalid")));
-
-  // Test with empty mandatory audio sourceID.
-  EXPECT_EQ(kGetUserMediaFailed,
-            ExecuteJavascriptAndReturnResult(
-                GenerateGetUserMediaWithMandatorySourceID(
-                    kGetUserMediaAndStop, "", video_ids[0])));
-}
-
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetUserMediaWithOptionalSourceID_1) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
-  std::vector<std::string> audio_ids;
-  std::vector<std::string> video_ids;
-  GetSources(&audio_ids, &video_ids);
-
-  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
-  NavigateToURL(shell(), url);
-
-  // Test all combinations of mandatory sourceID.
-  for (size_t j = 0; j < video_ids.size() / 2; ++j) {
-    for (size_t i = 0; i < audio_ids.size(); ++i) {
-      EXPECT_EQ(kOK,
-                ExecuteJavascriptAndReturnResult(
-                    GenerateGetUserMediaWithOptionalSourceID(
-                        kGetUserMediaAndStop, audio_ids[i], video_ids[j])));
-    }
-  }
-}
-
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, GetUserMediaWithOptionalSourceID_2) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
-  std::vector<std::string> audio_ids;
-  std::vector<std::string> video_ids;
-  GetSources(&audio_ids, &video_ids);
-
-  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
-  NavigateToURL(shell(), url);
-
-  // Test all combinations of mandatory sourceID.
-  for (size_t j = video_ids.size() / 2; j < video_ids.size(); ++j) {
-    for (size_t i = 0; i < audio_ids.size(); ++i) {
-      EXPECT_EQ(kOK,
-                ExecuteJavascriptAndReturnResult(
-                    GenerateGetUserMediaWithOptionalSourceID(
-                        kGetUserMediaAndStop, audio_ids[i], video_ids[j])));
-    }
-  }
-}
-
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
-                       GetUserMediaWithInvalidOptionalSourceID) {
-  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
-  std::vector<std::string> audio_ids;
-  std::vector<std::string> video_ids;
-  GetSources(&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])));
-}
-
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
 // Timing out on ARM linux bot: http://crbug.com/238490
 #define MAYBE_CanSetupVideoCall DISABLED_CanSetupVideoCall
@@ -430,60 +57,10 @@
 
 // These tests will make a complete PeerConnection-based call and verify that
 // video is playing for the call.
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CanSetupVideoCall) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MAYBE_CanSetupVideoCall) {
   MakeTypicalPeerConnectionCall("call({video: true});");
 }
 
-// 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.
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, TracePerformanceDuringGetUserMedia) {
-  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.
-  ASSERT_TRUE(ExecuteJavascript(base::StringPrintf(
-      "%s({video: true}, 10);", kGetUserMediaAndWaitAndStop)));
-
-  // Make sure the stream is up and running, then start collecting traces.
-  ExpectTitle("Running...");
-  StartTracing();
-
-  // Wait until the page title changes to "OK". Do not sleep() here since that
-  // would stop both this code and the browser underneath.
-  ExpectTitle("OK");
-  StopTracing();
-
-  scoped_ptr<TraceAnalyzer> analyzer(CreateTraceAnalyzer());
-  analyzer->AssociateBeginEndEvents();
-  trace_analyzer::TraceEventVector events;
-  analyzer->FindEvents(
-      Query::EventNameIs("VideoCaptureController::OnIncomingCapturedFrame"),
-      &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) {
-    interarrival_us.append(base::StringPrintf(
-        "%d,",
-        static_cast<int>(events[i]->timestamp - events[i - 1]->timestamp)));
-  }
-
-  perf_test::PrintResultList(
-      "video_capture", "", "sample_duration", duration_us, "us", true);
-
-  perf_test::PrintResultList(
-      "video_capture", "", "interarrival_time", interarrival_us, "us", true);
-}
-
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
 // Timing out on ARM linux, see http://crbug.com/240376
 #define MAYBE_CanSetupAudioAndVideoCall DISABLED_CanSetupAudioAndVideoCall
@@ -491,18 +68,18 @@
 #define MAYBE_CanSetupAudioAndVideoCall CanSetupAudioAndVideoCall
 #endif
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CanSetupAudioAndVideoCall) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MAYBE_CanSetupAudioAndVideoCall) {
   MakeTypicalPeerConnectionCall("call({video: true, audio: true});");
 }
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MANUAL_CanSetupCallAndSendDtmf) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MANUAL_CanSetupCallAndSendDtmf) {
   MakeTypicalPeerConnectionCall("callAndSendDtmf(\'123,abc\');");
 }
 
 // TODO(phoglund): this test fails because the peer connection state will be
 // stable in the second negotiation round rather than have-local-offer.
 // http://crbug.com/293125.
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
                        DISABLED_CanMakeEmptyCallThenAddStreamsAndRenegotiate) {
   const char* kJavascript =
       "callEmptyThenAddOneStreamAndRenegotiate({video: true, audio: true});";
@@ -520,12 +97,12 @@
 #define MAYBE_CanForwardRemoteStream CanForwardRemoteStream
 #define MAYBE_CanForwardRemoteStream720p CanForwardRemoteStream720p
 #endif
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CanForwardRemoteStream) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MAYBE_CanForwardRemoteStream) {
   MakeTypicalPeerConnectionCall(
       "callAndForwardRemoteStream({video: true, audio: true});");
 }
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CanForwardRemoteStream720p) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MAYBE_CanForwardRemoteStream720p) {
   const std::string javascript = GenerateGetUserMediaCall(
       "callAndForwardRemoteStream", 1280, 1280, 720, 720, 30, 30);
   MakeTypicalPeerConnectionCall(javascript);
@@ -547,7 +124,7 @@
 #define MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle\
         CanSetupAudioAndVideoCallWithoutMsidAndBundle
 #endif
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
                        MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle) {
   MakeTypicalPeerConnectionCall("callWithoutMsidAndBundle();");
 }
@@ -561,7 +138,8 @@
 #else
 #define MAYBE_NegotiateUnsupportedVideoCodec NegotiateUnsupportedVideoCodec
 #endif
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
+
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
                        MAYBE_NegotiateUnsupportedVideoCodec) {
   MakeTypicalPeerConnectionCall("negotiateUnsupportedVideoCodec();");
 }
@@ -574,13 +152,14 @@
 #else
 #define MAYBE_NegotiateNonCryptoCall NegotiateNonCryptoCall
 #endif
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_NegotiateNonCryptoCall) {
+
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MAYBE_NegotiateNonCryptoCall) {
   MakeTypicalPeerConnectionCall("negotiateNonCryptoCall();");
 }
 
 // This test can negotiate an SDP offer that includes a b=AS:xx to control
 // the bandwidth for audio and video
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, NegotiateOfferWithBLine) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, NegotiateOfferWithBLine) {
   MakeTypicalPeerConnectionCall("negotiateOfferWithBLine();");
 }
 
@@ -596,18 +175,18 @@
 #define MAYBE_CanSetupLegacyCall CanSetupLegacyCall
 #endif
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CanSetupLegacyCall) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MAYBE_CanSetupLegacyCall) {
   MakeTypicalPeerConnectionCall("callWithLegacySdp();");
 }
 
 // This test will make a PeerConnection-based call and test an unreliable text
 // dataChannel.
 // TODO(mallinath) - Remove this test after rtp based data channel is disabled.
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, CallWithDataOnly) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, CallWithDataOnly) {
   MakeTypicalPeerConnectionCall("callWithDataOnly();");
 }
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, CallWithSctpDataOnly) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, CallWithSctpDataOnly) {
   MakeTypicalPeerConnectionCall("callWithSctpDataOnly();");
 }
 
@@ -621,7 +200,7 @@
 // This test will make a PeerConnection-based call and test an unreliable text
 // dataChannel and audio and video tracks.
 // TODO(mallinath) - Remove this test after rtp based data channel is disabled.
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CallWithDataAndMedia) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MAYBE_CallWithDataAndMedia) {
   MakeTypicalPeerConnectionCall("callWithDataAndMedia();");
 }
 
@@ -633,7 +212,7 @@
 #define MAYBE_CallWithSctpDataAndMedia CallWithSctpDataAndMedia
 #endif
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
                        MAYBE_CallWithSctpDataAndMedia) {
   MakeTypicalPeerConnectionCall("callWithSctpDataAndMedia();");
 }
@@ -648,7 +227,7 @@
 
 // This test will make a PeerConnection-based call and test an unreliable text
 // dataChannel and later add an audio and video track.
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CallWithDataAndLaterAddMedia) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MAYBE_CallWithDataAndLaterAddMedia) {
   MakeTypicalPeerConnectionCall("callWithDataAndLaterAddMedia();");
 }
 
@@ -662,7 +241,7 @@
 // This test will make a PeerConnection-based call and send a new Video
 // MediaStream that has been created based on a MediaStream created with
 // getUserMedia.
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CallWithNewVideoMediaStream) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MAYBE_CallWithNewVideoMediaStream) {
   MakeTypicalPeerConnectionCall("callWithNewVideoMediaStream();");
 }
 
@@ -672,94 +251,16 @@
 // AudioTrack is added instead.
 // TODO(phoglund): This test is manual since not all buildbots has an audio
 // input.
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MANUAL_CallAndModifyStream) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MANUAL_CallAndModifyStream) {
   MakeTypicalPeerConnectionCall(
       "callWithNewVideoMediaStreamLaterSwitchToAudio();");
 }
 
-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 WebrtcUserMediaBrowserTest
-    : public WebrtcBrowserTest,
-      public testing::WithParamInterface<UserMediaSizes> {
- public:
-  WebrtcUserMediaBrowserTest() : 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(WebrtcUserMediaBrowserTest, 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);
-  ASSERT_TRUE(ExecuteJavascript(call));
-  ExpectTitle("OK");
-}
-
-static const UserMediaSizes kAllUserMediaSizes[] = {
-    {320, 320, 180, 180, 30, 30},
-    {320, 320, 240, 240, 30, 30},
-    {640, 640, 360, 360, 30, 30},
-    {640, 640, 480, 480, 30, 30},
-    {960, 960, 720, 720, 30, 30},
-    {1280, 1280, 720, 720, 30, 30},
-    {1920, 1920, 1080, 1080, 30, 30}};
-
-INSTANTIATE_TEST_CASE_P(UserMedia,
-                        WebrtcUserMediaBrowserTest,
-                        testing::ValuesIn(kAllUserMediaSizes));
-
-// This test calls getUserMedia and checks for aspect ratio behavior.
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, TestGetUserMediaAspectRatio) {
-  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, 30, 30);
-  std::string constraints_16_9 = GenerateGetUserMediaCall(
-      kGetUserMediaAndAnalyseAndStop, 640, 640, 360, 360, 30, 30);
-
-  // TODO(mcasas): add more aspect ratios, in particular 16:10 crbug.com/275594.
-
-  NavigateToURL(shell(), url);
-  ASSERT_TRUE(ExecuteJavascript(constraints_4_3));
-  ExpectTitle("4:3 letterbox");
-
-  NavigateToURL(shell(), url);
-  ASSERT_TRUE(ExecuteJavascript(constraints_16_9));
-  ExpectTitle("16:9 letterbox");
-}
-
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, AddTwoMediaStreamsToOnePC) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, AddTwoMediaStreamsToOnePC) {
   MakeTypicalPeerConnectionCall("addTwoMediaStreamsToOneConnection();");
 }
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
                        EstablishAudioVideoCallAndMeasureOutputLevel) {
   if (!media::AudioManager::Get()->HasAudioOutputDevices()) {
     // Bots with no output devices will force the audio code into a different
@@ -778,7 +279,7 @@
   MakeTypicalPeerConnectionCall("callAndEnsureAudioIsPlaying();");
 }
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
                        EstablishAudioVideoCallAndVerifyMutingWorks) {
   if (!media::AudioManager::Get()->HasAudioOutputDevices()) {
     // Bots with no output devices will force the audio code into a different
@@ -797,7 +298,7 @@
   MakeTypicalPeerConnectionCall("callAndEnsureAudioMutingWorks();");
 }
 
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, CallAndVerifyVideoMutingWorks) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, CallAndVerifyVideoMutingWorks) {
   MakeTypicalPeerConnectionCall("callAndEnsureVideoMutingWorks();");
 }
 
@@ -816,7 +317,7 @@
 // and Javascript is bypassed since it would trigger a file picker dialog.
 // Instead, the dialog callback FileSelected() is invoked directly. In fact,
 // there's never a webrtc-internals page opened at all since that's not needed.
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, MAYBE_CallWithAecDump) {
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, MAYBE_CallWithAecDump) {
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
 
   // We must navigate somewhere first so that the render process is created.
@@ -850,7 +351,7 @@
 
 // As above, but enable and disable dump before starting a call. The file should
 // be created, but should be empty.
-IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
+IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest,
                        MAYBE_CallWithAecDumpEnabledThenDisabled) {
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
 
@@ -877,5 +378,4 @@
   base::DeleteFile(dump_file, false);
 }
 
-
 }  // namespace content
diff --git a/content/browser/media/webrtc_getusermedia_browsertest.cc b/content/browser/media/webrtc_getusermedia_browsertest.cc
new file mode 100644
index 0000000..8ab99c3
--- /dev/null
+++ b/content/browser/media/webrtc_getusermedia_browsertest.cc
@@ -0,0 +1,427 @@
+// 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/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/test/browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils.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 kGetUserMediaAndWaitAndStop[] = "getUserMediaAndWaitAndStop";
+static const char kGetUserMediaAndAnalyseAndStop[] =
+    "getUserMediaAndAnalyseAndStop";
+
+// Results returned by JS.
+static const char kOK[] = "OK";
+static const char kGetUserMediaFailed[] =
+    "GetUserMedia call failed with code undefined";
+
+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:
+  WebRtcGetUserMediaBrowserTest() : trace_log_(NULL) {}
+  virtual ~WebRtcGetUserMediaBrowserTest() {}
+
+  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 GetSources(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 sources_as_json = ExecuteJavascriptAndReturnResult(
+        "getSources()");
+    EXPECT_FALSE(sources_as_json.empty());
+
+    int error_code;
+    std::string error_message;
+    scoped_ptr<base::Value> value(
+        base::JSONReader::ReadAndReturnError(sources_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 id;
+      ASSERT_TRUE((*it)->GetAsDictionary(&dict));
+      ASSERT_TRUE(dict->GetString("kind", &kind));
+      ASSERT_TRUE(dict->GetString("id", &id));
+      ASSERT_FALSE(id.empty());
+      EXPECT_TRUE(kind == "audio" || kind == "video");
+      if (kind == "audio") {
+        audio_ids->push_back(id);
+      } else if (kind == "video") {
+        video_ids->push_back(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_;
+};
+
+// 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_F(WebRtcGetUserMediaBrowserTest, GetVideoStreamAndStop) {
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+  NavigateToURL(shell(), url);
+
+  ASSERT_TRUE(ExecuteJavascript(
+      base::StringPrintf("%s({video: true});", kGetUserMediaAndStop)));
+
+  ExpectTitle("OK");
+}
+
+IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
+                       GetAudioAndVideoStreamAndStop) {
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+  NavigateToURL(shell(), url);
+
+  ASSERT_TRUE(ExecuteJavascript(base::StringPrintf(
+      "%s({video: true, audio: true});", kGetUserMediaAndStop)));
+
+  ExpectTitle("OK");
+}
+
+IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
+                       GetAudioAndVideoStreamAndClone) {
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+  NavigateToURL(shell(), url);
+
+  ASSERT_TRUE(ExecuteJavascript("getUserMediaAndClone();"));
+
+  ExpectTitle("OK");
+}
+
+IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
+                       GetUserMediaWithMandatorySourceID) {
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+  std::vector<std::string> audio_ids;
+  std::vector<std::string> video_ids;
+  GetSources(&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_F(WebRtcGetUserMediaBrowserTest,
+                       GetUserMediaWithInvalidMandatorySourceID) {
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+  std::vector<std::string> audio_ids;
+  std::vector<std::string> video_ids;
+  GetSources(&audio_ids, &video_ids);
+
+  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+
+  // Test with invalid mandatory audio sourceID.
+  NavigateToURL(shell(), url);
+  EXPECT_EQ(kGetUserMediaFailed, ExecuteJavascriptAndReturnResult(
+      GenerateGetUserMediaWithMandatorySourceID(
+          kGetUserMediaAndStop,
+          "something invalid",
+          video_ids[0])));
+
+  // Test with invalid mandatory video sourceID.
+  EXPECT_EQ(kGetUserMediaFailed, ExecuteJavascriptAndReturnResult(
+      GenerateGetUserMediaWithMandatorySourceID(
+          kGetUserMediaAndStop,
+          audio_ids[0],
+          "something invalid")));
+
+  // Test with empty mandatory audio sourceID.
+  EXPECT_EQ(kGetUserMediaFailed, ExecuteJavascriptAndReturnResult(
+      GenerateGetUserMediaWithMandatorySourceID(
+          kGetUserMediaAndStop,
+          "",
+          video_ids[0])));
+}
+
+IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
+                       GetUserMediaWithInvalidOptionalSourceID) {
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+  std::vector<std::string> audio_ids;
+  std::vector<std::string> video_ids;
+  GetSources(&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_F(WebRtcGetUserMediaBrowserTest, TwoGetUserMediaAndStop) {
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+  GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+  NavigateToURL(shell(), url);
+
+  ASSERT_TRUE(ExecuteJavascript(
+      "twoGetUserMediaAndStop({video: true, audio: true});"));
+
+  ExpectTitle("OK");
+}
+
+// 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.
+IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
+                       TracePerformanceDuringGetUserMedia) {
+  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.
+  ASSERT_TRUE(ExecuteJavascript(base::StringPrintf(
+      "%s({video: true}, 10);", kGetUserMediaAndWaitAndStop)));
+
+  // Make sure the stream is up and running, then start collecting traces.
+  ExpectTitle("Running...");
+  StartTracing();
+
+  // Wait until the page title changes to "OK". Do not sleep() here since that
+  // would stop both this code and the browser underneath.
+  ExpectTitle("OK");
+  StopTracing();
+
+  scoped_ptr<TraceAnalyzer> analyzer(CreateTraceAnalyzer());
+  analyzer->AssociateBeginEndEvents();
+  trace_analyzer::TraceEventVector events;
+  analyzer->FindEvents(
+      Query::EventNameIs("VideoCaptureController::OnIncomingCapturedFrame"),
+      &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) {
+    interarrival_us.append(base::StringPrintf(
+        "%d,",
+        static_cast<int>(events[i]->timestamp - events[i - 1]->timestamp)));
+  }
+
+  perf_test::PrintResultList(
+      "video_capture", "", "sample_duration", duration_us, "us", true);
+
+  perf_test::PrintResultList(
+      "video_capture", "", "interarrival_time", interarrival_us, "us", true);
+}
+
+// This test calls getUserMedia and checks for aspect ratio behavior.
+IN_PROC_BROWSER_TEST_F(WebRtcGetUserMediaBrowserTest,
+                       TestGetUserMediaAspectRatio) {
+  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, 30, 30);
+  std::string constraints_16_9 = GenerateGetUserMediaCall(
+      kGetUserMediaAndAnalyseAndStop, 640, 640, 360, 360, 30, 30);
+
+  // TODO(mcasas): add more aspect ratios, in particular 16:10 crbug.com/275594.
+
+  NavigateToURL(shell(), url);
+  ASSERT_TRUE(ExecuteJavascript(constraints_4_3));
+  ExpectTitle("4:3 letterbox");
+
+  NavigateToURL(shell(), url);
+  ASSERT_TRUE(ExecuteJavascript(constraints_16_9));
+  ExpectTitle("16:9 letterbox");
+}
+
+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 WebRtcGetUserMediaBrowserTest,
+      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);
+  ASSERT_TRUE(ExecuteJavascript(call));
+  ExpectTitle("OK");
+}
+
+static const UserMediaSizes kAllUserMediaSizes[] = {
+    {320, 320, 180, 180, 30, 30},
+    {320, 320, 240, 240, 30, 30},
+    {640, 640, 360, 360, 30, 30},
+    {640, 640, 480, 480, 30, 30},
+    {960, 960, 720, 720, 30, 30},
+    {1280, 1280, 720, 720, 30, 30},
+    {1920, 1920, 1080, 1080, 30, 30}};
+
+INSTANTIATE_TEST_CASE_P(UserMedia,
+                        WebRtcConstraintsBrowserTest,
+                        testing::ValuesIn(kAllUserMediaSizes));
+
+}  // namespace content
diff --git a/content/browser/media/webrtc_internals.h b/content/browser/media/webrtc_internals.h
index 5355484..64991801 100644
--- a/content/browser/media/webrtc_internals.h
+++ b/content/browser/media/webrtc_internals.h
@@ -101,8 +101,8 @@
 
  private:
   friend struct DefaultSingletonTraits<WebRTCInternals>;
-  FRIEND_TEST_ALL_PREFIXES(WebrtcBrowserTest, CallWithAecDump);
-  FRIEND_TEST_ALL_PREFIXES(WebrtcBrowserTest,
+  FRIEND_TEST_ALL_PREFIXES(WebRtcBrowserTest, CallWithAecDump);
+  FRIEND_TEST_ALL_PREFIXES(WebRtcBrowserTest,
                            CallWithAecDumpEnabledThenDisabled);
 
   WebRTCInternals();