// Copyright 2013 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 "chrome/browser/media/webrtc/webrtc_browsertest_base.h"

#include <stddef.h>

#include <limits>

#include "base/json/json_reader.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/media/webrtc/webrtc_browsertest_common.h"
#include "chrome/browser/permissions/permission_request_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/test/browser_test_utils.h"
#include "net/test/embedded_test_server/embedded_test_server.h"

#if defined(OS_WIN)
// For fine-grained suppression.
#include "base/win/windows_version.h"
#endif

const char WebRtcTestBase::kAudioVideoCallConstraints[] =
    "{audio: true, video: true}";
const char WebRtcTestBase::kVideoCallConstraintsQVGA[] =
   "{video: {mandatory: {minWidth: 320, maxWidth: 320, "
   " minHeight: 240, maxHeight: 240}}}";
const char WebRtcTestBase::kVideoCallConstraints360p[] =
   "{video: {mandatory: {minWidth: 640, maxWidth: 640, "
   " minHeight: 360, maxHeight: 360}}}";
const char WebRtcTestBase::kVideoCallConstraintsVGA[] =
   "{video: {mandatory: {minWidth: 640, maxWidth: 640, "
   " minHeight: 480, maxHeight: 480}}}";
const char WebRtcTestBase::kVideoCallConstraints720p[] =
   "{video: {mandatory: {minWidth: 1280, maxWidth: 1280, "
   " minHeight: 720, maxHeight: 720}}}";
const char WebRtcTestBase::kVideoCallConstraints1080p[] =
    "{video: {mandatory: {minWidth: 1920, maxWidth: 1920, "
    " minHeight: 1080, maxHeight: 1080}}}";
const char WebRtcTestBase::kAudioOnlyCallConstraints[] = "{audio: true}";
const char WebRtcTestBase::kVideoOnlyCallConstraints[] = "{video: true}";
const char WebRtcTestBase::kOkGotStream[] = "ok-got-stream";
const char WebRtcTestBase::kFailedWithPermissionDeniedError[] =
    "failed-with-error-PermissionDeniedError";
const char WebRtcTestBase::kFailedWithPermissionDismissedError[] =
    "failed-with-error-PermissionDismissedError";
const char WebRtcTestBase::kAudioVideoCallConstraints360p[] =
   "{audio: true, video: {mandatory: {minWidth: 640, maxWidth: 640, "
   " minHeight: 360, maxHeight: 360}}}";
const char WebRtcTestBase::kAudioVideoCallConstraints720p[] =
   "{audio: true, video: {mandatory: {minWidth: 1280, maxWidth: 1280, "
   " minHeight: 720, maxHeight: 720}}}";
const char WebRtcTestBase::kUseDefaultCertKeygen[] = "null";
const char WebRtcTestBase::kUseDefaultAudioCodec[] = "";
const char WebRtcTestBase::kUseDefaultVideoCodec[] = "";

namespace {

base::LazyInstance<bool>::DestructorAtExit hit_javascript_errors_ =
    LAZY_INSTANCE_INITIALIZER;

// Intercepts all log messages. We always attach this handler but only look at
// the results if the test requests so. Note that this will only work if the
// WebrtcTestBase-inheriting test cases do not run in parallel (if they did they
// would race to look at the log, which is global to all tests).
bool JavascriptErrorDetectingLogHandler(int severity,
                                        const char* file,
                                        int line,
                                        size_t message_start,
                                        const std::string& str) {
  if (file == NULL || std::string("CONSOLE") != file)
    return false;

  bool contains_uncaught = str.find("\"Uncaught ") != std::string::npos;
  if (severity == logging::LOG_ERROR ||
      (severity == logging::LOG_INFO && contains_uncaught)) {
    hit_javascript_errors_.Get() = true;
  }

  return false;
}

// PermissionRequestObserver ---------------------------------------------------

// Used to observe the creation of permission prompt without responding.
class PermissionRequestObserver : public PermissionRequestManager::Observer {
 public:
  explicit PermissionRequestObserver(content::WebContents* web_contents)
      : request_manager_(
            PermissionRequestManager::FromWebContents(web_contents)),
        request_shown_(false),
        message_loop_runner_(new content::MessageLoopRunner) {
    request_manager_->AddObserver(this);
  }
  ~PermissionRequestObserver() override {
    // Safe to remove twice if it happens.
    request_manager_->RemoveObserver(this);
  }

  void Wait() { message_loop_runner_->Run(); }

  bool request_shown() const { return request_shown_; }

 private:
  // PermissionRequestManager::Observer
  void OnBubbleAdded() override {
    request_shown_ = true;
    request_manager_->RemoveObserver(this);
    message_loop_runner_->Quit();
  }

  PermissionRequestManager* request_manager_;
  bool request_shown_;
  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;

  DISALLOW_COPY_AND_ASSIGN(PermissionRequestObserver);
};

std::vector<std::string> JsonArrayToVectorOfStrings(
    const std::string& json_array) {
  std::unique_ptr<base::Value> value = base::JSONReader::Read(json_array);
  EXPECT_TRUE(value);
  EXPECT_TRUE(value->IsType(base::Value::Type::LIST));
  std::unique_ptr<base::ListValue> list =
      base::ListValue::From(std::move(value));
  std::vector<std::string> vector;
  vector.reserve(list->GetSize());
  for (size_t i = 0; i < list->GetSize(); ++i) {
    base::Value* item;
    EXPECT_TRUE(list->Get(i, &item));
    EXPECT_TRUE(item->IsType(base::Value::Type::STRING));
    std::string item_str;
    EXPECT_TRUE(item->GetAsString(&item_str));
    vector.push_back(std::move(item_str));
  }
  return vector;
}

}  // namespace

WebRtcTestBase::WebRtcTestBase(): detect_errors_in_javascript_(false) {
  // The handler gets set for each test method, but that's fine since this
  // set operation is idempotent.
  logging::SetLogMessageHandler(&JavascriptErrorDetectingLogHandler);
  hit_javascript_errors_.Get() = false;

  EnablePixelOutput();
}

WebRtcTestBase::~WebRtcTestBase() {
  if (detect_errors_in_javascript_) {
    EXPECT_FALSE(hit_javascript_errors_.Get())
        << "Encountered javascript errors during test execution (Search "
        << "for Uncaught or ERROR:CONSOLE in the test output).";
  }
}

bool WebRtcTestBase::GetUserMediaAndAccept(
    content::WebContents* tab_contents) const {
  return GetUserMediaWithSpecificConstraintsAndAccept(
      tab_contents, kAudioVideoCallConstraints);
}

bool WebRtcTestBase::GetUserMediaWithSpecificConstraintsAndAccept(
    content::WebContents* tab_contents,
    const std::string& constraints) const {
  std::string result;
  PermissionRequestManager::FromWebContents(tab_contents)
      ->set_auto_response_for_test(PermissionRequestManager::ACCEPT_ALL);
  PermissionRequestObserver permissionRequestObserver(tab_contents);
  GetUserMedia(tab_contents, constraints);
  EXPECT_TRUE(permissionRequestObserver.request_shown());
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
  return kOkGotStream == result;
}

bool WebRtcTestBase::GetUserMediaWithSpecificConstraintsAndAcceptIfPrompted(
    content::WebContents* tab_contents,
    const std::string& constraints) const {
  std::string result;
  PermissionRequestManager::FromWebContents(tab_contents)
      ->set_auto_response_for_test(PermissionRequestManager::ACCEPT_ALL);
  GetUserMedia(tab_contents, constraints);
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
  return kOkGotStream == result;
}

void WebRtcTestBase::GetUserMediaAndDeny(content::WebContents* tab_contents) {
  return GetUserMediaWithSpecificConstraintsAndDeny(tab_contents,
                                                    kAudioVideoCallConstraints);
}

void WebRtcTestBase::GetUserMediaWithSpecificConstraintsAndDeny(
    content::WebContents* tab_contents,
    const std::string& constraints) const {
  std::string result;
  PermissionRequestManager::FromWebContents(tab_contents)
      ->set_auto_response_for_test(PermissionRequestManager::DENY_ALL);
  PermissionRequestObserver permissionRequestObserver(tab_contents);
  GetUserMedia(tab_contents, constraints);
  EXPECT_TRUE(permissionRequestObserver.request_shown());
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
  EXPECT_EQ(kFailedWithPermissionDeniedError, result);
}

void WebRtcTestBase::GetUserMediaAndDismiss(
    content::WebContents* tab_contents) const {
  std::string result;
  PermissionRequestManager::FromWebContents(tab_contents)
      ->set_auto_response_for_test(PermissionRequestManager::DISMISS);
  PermissionRequestObserver permissionRequestObserver(tab_contents);
  GetUserMedia(tab_contents, kAudioVideoCallConstraints);
  EXPECT_TRUE(permissionRequestObserver.request_shown());
  // A dismiss should be treated like a deny.
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
  EXPECT_EQ(kFailedWithPermissionDismissedError, result);
}

void WebRtcTestBase::GetUserMediaAndExpectAutoAcceptWithoutPrompt(
    content::WebContents* tab_contents) const {
  std::string result;
  // We issue a GetUserMedia() request. We expect that the origin already has a
  // sticky "accept" permission (e.g. because the caller previously called
  // GetUserMediaAndAccept()), and therefore the GetUserMedia() request
  // automatically succeeds without a prompt.
  // If the caller made a mistake, a prompt may show up instead. For this case,
  // we set an auto-response to avoid leaving the prompt hanging. The choice of
  // DENY_ALL makes sure that the response to the prompt doesn't accidentally
  // result in a newly granted media stream permission.
  PermissionRequestManager::FromWebContents(tab_contents)
      ->set_auto_response_for_test(PermissionRequestManager::DENY_ALL);
  PermissionRequestObserver permissionRequestObserver(tab_contents);
  GetUserMedia(tab_contents, kAudioVideoCallConstraints);
  EXPECT_FALSE(permissionRequestObserver.request_shown());
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
  EXPECT_EQ(kOkGotStream, result);
}

void WebRtcTestBase::GetUserMediaAndExpectAutoDenyWithoutPrompt(
    content::WebContents* tab_contents) const {
  std::string result;
  // We issue a GetUserMedia() request. We expect that the origin already has a
  // sticky "deny" permission (e.g. because the caller previously called
  // GetUserMediaAndDeny()), and therefore the GetUserMedia() request
  // automatically succeeds without a prompt.
  // If the caller made a mistake, a prompt may show up instead. For this case,
  // we set an auto-response to avoid leaving the prompt hanging. The choice of
  // ACCEPT_ALL makes sure that the response to the prompt doesn't accidentally
  // result in a newly granted media stream permission.
  PermissionRequestManager::FromWebContents(tab_contents)
      ->set_auto_response_for_test(PermissionRequestManager::ACCEPT_ALL);
  PermissionRequestObserver permissionRequestObserver(tab_contents);
  GetUserMedia(tab_contents, kAudioVideoCallConstraints);
  EXPECT_FALSE(permissionRequestObserver.request_shown());
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      tab_contents->GetMainFrame(), "obtainGetUserMediaResult();", &result));
  EXPECT_EQ(kFailedWithPermissionDeniedError, result);
}

void WebRtcTestBase::GetUserMedia(content::WebContents* tab_contents,
                                  const std::string& constraints) const {
  // Request user media: this will launch the media stream info bar or bubble.
  std::string result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      tab_contents, "doGetUserMedia(" + constraints + ");", &result));
  EXPECT_TRUE(result == "request-callback-denied" ||
              result == "request-callback-granted");
}

content::WebContents* WebRtcTestBase::OpenPageAndGetUserMediaInNewTab(
    const GURL& url) const {
  return OpenPageAndGetUserMediaInNewTabWithConstraints(
      url, kAudioVideoCallConstraints);
}

content::WebContents*
WebRtcTestBase::OpenPageAndGetUserMediaInNewTabWithConstraints(
    const GURL& url,
    const std::string& constraints) const {
  chrome::AddTabAt(browser(), GURL(), -1, true);
  ui_test_utils::NavigateToURL(browser(), url);
  content::WebContents* new_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  // Accept if necessary, but don't expect a prompt (because auto-accept is also
  // okay).
  PermissionRequestManager::FromWebContents(new_tab)
      ->set_auto_response_for_test(PermissionRequestManager::ACCEPT_ALL);
  GetUserMedia(new_tab, constraints);
  std::string result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      new_tab->GetMainFrame(), "obtainGetUserMediaResult();", &result));
  EXPECT_EQ(kOkGotStream, result);
  return new_tab;
}

content::WebContents* WebRtcTestBase::OpenTestPageAndGetUserMediaInNewTab(
    const std::string& test_page) const {
  return OpenPageAndGetUserMediaInNewTab(
      embedded_test_server()->GetURL(test_page));
}

void WebRtcTestBase::CloseLastLocalStream(
    content::WebContents* tab_contents) const {
  EXPECT_EQ("ok-stopped",
            ExecuteJavascript("stopLocalStream();", tab_contents));
}

// Convenience method which executes the provided javascript in the context
// of the provided web contents and returns what it evaluated to.
std::string WebRtcTestBase::ExecuteJavascript(
    const std::string& javascript,
    content::WebContents* tab_contents) const {
  std::string result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      tab_contents, javascript, &result));
  return result;
}

void WebRtcTestBase::SetupPeerconnectionWithLocalStream(
    content::WebContents* tab,
    const std::string& certificate_keygen_algorithm) const {
  SetupPeerconnectionWithoutLocalStream(tab, certificate_keygen_algorithm);
  EXPECT_EQ("ok-added", ExecuteJavascript("addLocalStream()", tab));
}

void WebRtcTestBase::SetupPeerconnectionWithoutLocalStream(
    content::WebContents* tab,
    const std::string& certificate_keygen_algorithm) const {
  std::string javascript = base::StringPrintf(
      "preparePeerConnection(%s)", certificate_keygen_algorithm.c_str());
  EXPECT_EQ("ok-peerconnection-created", ExecuteJavascript(javascript, tab));
}

void WebRtcTestBase::SetupPeerconnectionWithCertificateAndLocalStream(
    content::WebContents* tab,
    const std::string& certificate) const {
  SetupPeerconnectionWithCertificateWithoutLocalStream(tab, certificate);
  EXPECT_EQ("ok-added", ExecuteJavascript("addLocalStream()", tab));
}

void WebRtcTestBase::SetupPeerconnectionWithCertificateWithoutLocalStream(
    content::WebContents* tab,
    const std::string& certificate) const {
  std::string javascript = base::StringPrintf(
      "preparePeerConnectionWithCertificate(%s)", certificate.c_str());
  EXPECT_EQ("ok-peerconnection-created", ExecuteJavascript(javascript, tab));
}

std::string WebRtcTestBase::CreateLocalOffer(
    content::WebContents* from_tab) const {
  std::string response = ExecuteJavascript("createLocalOffer({})", from_tab);
  EXPECT_EQ("ok-", response.substr(0, 3)) << "Failed to create local offer: "
      << response;

  std::string local_offer = response.substr(3);
  return local_offer;
}

std::string WebRtcTestBase::CreateAnswer(std::string local_offer,
                                         content::WebContents* to_tab) const {
  std::string javascript =
      base::StringPrintf("receiveOfferFromPeer('%s', {})", local_offer.c_str());
  std::string response = ExecuteJavascript(javascript, to_tab);
  EXPECT_EQ("ok-", response.substr(0, 3))
      << "Receiving peer failed to receive offer and create answer: "
      << response;

  std::string answer = response.substr(3);
  response = ExecuteJavascript(
      base::StringPrintf("verifyDefaultCodecs('%s')", answer.c_str()),
      to_tab);
  EXPECT_EQ("ok-", response.substr(0, 3))
      << "Receiving peer failed to verify default codec: " << response;
  return answer;
}

void WebRtcTestBase::ReceiveAnswer(const std::string& answer,
                                   content::WebContents* from_tab) const {
  ASSERT_EQ(
      "ok-accepted-answer",
      ExecuteJavascript(
          base::StringPrintf("receiveAnswerFromPeer('%s')", answer.c_str()),
          from_tab));
}

void WebRtcTestBase::GatherAndSendIceCandidates(
    content::WebContents* from_tab,
    content::WebContents* to_tab) const {
  std::string ice_candidates =
      ExecuteJavascript("getAllIceCandidates()", from_tab);

  EXPECT_EQ("ok-received-candidates", ExecuteJavascript(
      base::StringPrintf("receiveIceCandidates('%s')", ice_candidates.c_str()),
      to_tab));
}

void WebRtcTestBase::CreateDataChannel(content::WebContents* tab,
                                       const std::string& label) {
  EXPECT_EQ("ok-created",
            ExecuteJavascript("createDataChannel('" + label + "')", tab));
}

void WebRtcTestBase::NegotiateCall(content::WebContents* from_tab,
                                   content::WebContents* to_tab) const {
  std::string local_offer = CreateLocalOffer(from_tab);
  std::string answer = CreateAnswer(local_offer, to_tab);
  ReceiveAnswer(answer, from_tab);

  // Send all ICE candidates (wait for gathering to finish if necessary).
  GatherAndSendIceCandidates(to_tab, from_tab);
  GatherAndSendIceCandidates(from_tab, to_tab);
}

void WebRtcTestBase::HangUp(content::WebContents* from_tab) const {
  EXPECT_EQ("ok-call-hung-up", ExecuteJavascript("hangUp()", from_tab));
}

void WebRtcTestBase::DetectErrorsInJavaScript() {
  detect_errors_in_javascript_ = true;
}

void WebRtcTestBase::StartDetectingVideo(
    content::WebContents* tab_contents,
    const std::string& video_element) const {
  std::string javascript = base::StringPrintf(
      "startDetection('%s', 320, 240)", video_element.c_str());
  EXPECT_EQ("ok-started", ExecuteJavascript(javascript, tab_contents));
}

bool WebRtcTestBase::WaitForVideoToPlay(
    content::WebContents* tab_contents) const {
  bool is_video_playing = test::PollingWaitUntil(
      "isVideoPlaying()", "video-playing", tab_contents);
  EXPECT_TRUE(is_video_playing);
  return is_video_playing;
}

std::string WebRtcTestBase::GetStreamSize(
    content::WebContents* tab_contents,
    const std::string& video_element) const {
  std::string javascript =
      base::StringPrintf("getStreamSize('%s')", video_element.c_str());
  std::string result = ExecuteJavascript(javascript, tab_contents);
  EXPECT_TRUE(base::StartsWith(result, "ok-", base::CompareCase::SENSITIVE));
  return result.substr(3);
}

bool WebRtcTestBase::OnWin8OrHigher() const {
#if defined(OS_WIN)
  return base::win::GetVersion() >= base::win::VERSION_WIN8;
#else
  return false;
#endif
}

void WebRtcTestBase::OpenDatabase(content::WebContents* tab) const {
  EXPECT_EQ("ok-database-opened", ExecuteJavascript("openDatabase()", tab));
}

void WebRtcTestBase::CloseDatabase(content::WebContents* tab) const {
  EXPECT_EQ("ok-database-closed", ExecuteJavascript("closeDatabase()", tab));
}

void WebRtcTestBase::DeleteDatabase(content::WebContents* tab) const {
  EXPECT_EQ("ok-database-deleted", ExecuteJavascript("deleteDatabase()", tab));
}

void WebRtcTestBase::GenerateAndCloneCertificate(
    content::WebContents* tab, const std::string& keygen_algorithm) const {
  std::string javascript = base::StringPrintf(
      "generateAndCloneCertificate(%s)", keygen_algorithm.c_str());
  EXPECT_EQ("ok-generated-and-cloned", ExecuteJavascript(javascript, tab));
}

void WebRtcTestBase::VerifyStatsGeneratedCallback(
    content::WebContents* tab) const {
  EXPECT_EQ("ok-got-stats", ExecuteJavascript("verifyStatsGenerated()", tab));
}

std::vector<std::string> WebRtcTestBase::VerifyStatsGeneratedPromise(
    content::WebContents* tab) const {
  std::string result = ExecuteJavascript("verifyStatsGeneratedPromise()", tab);
  EXPECT_TRUE(base::StartsWith(result, "ok-", base::CompareCase::SENSITIVE));
  return JsonArrayToVectorOfStrings(result.substr(3));
}

double WebRtcTestBase::MeasureGetStatsCallbackPerformance(
    content::WebContents* tab) const {
  std::string result = ExecuteJavascript(
      "measureGetStatsCallbackPerformance()", tab);
  EXPECT_TRUE(base::StartsWith(result, "ok-", base::CompareCase::SENSITIVE));
  double ms;
  if (!base::StringToDouble(result.substr(3), &ms))
    return std::numeric_limits<double>::infinity();
  return ms;
}

scoped_refptr<content::TestStatsReportDictionary>
WebRtcTestBase::GetStatsReportDictionary(content::WebContents* tab) const {
  std::string result = ExecuteJavascript("getStatsReportDictionary()", tab);
  EXPECT_TRUE(base::StartsWith(result, "ok-", base::CompareCase::SENSITIVE));
  std::unique_ptr<base::Value> parsed_json = base::JSONReader::Read(
      result.substr(3));
  base::DictionaryValue* dictionary;
  CHECK(parsed_json);
  CHECK(parsed_json->GetAsDictionary(&dictionary));
  ignore_result(parsed_json.release());
  return scoped_refptr<content::TestStatsReportDictionary>(
      new content::TestStatsReportDictionary(
          std::unique_ptr<base::DictionaryValue>(dictionary)));
}

double WebRtcTestBase::MeasureGetStatsPerformance(
    content::WebContents* tab) const {
  std::string result = ExecuteJavascript("measureGetStatsPerformance()", tab);
  EXPECT_TRUE(base::StartsWith(result, "ok-", base::CompareCase::SENSITIVE));
  double ms;
  if (!base::StringToDouble(result.substr(3), &ms))
    return std::numeric_limits<double>::infinity();
  return ms;
}

std::vector<std::string> WebRtcTestBase::GetWhitelistedStatsTypes(
    content::WebContents* tab) const {
  return JsonArrayToVectorOfStrings(
      ExecuteJavascript("getWhitelistedStatsTypes()", tab));
}

void WebRtcTestBase::SetDefaultAudioCodec(
    content::WebContents* tab,
    const std::string& audio_codec) const {
  EXPECT_EQ("ok", ExecuteJavascript(
      "setDefaultAudioCodec('" + audio_codec + "')", tab));
}

void WebRtcTestBase::SetDefaultVideoCodec(
    content::WebContents* tab,
    const std::string& video_codec) const {
  EXPECT_EQ("ok", ExecuteJavascript(
      "setDefaultVideoCodec('" + video_codec + "')", tab));
}

void WebRtcTestBase::EnableOpusDtx(content::WebContents* tab) const {
  EXPECT_EQ("ok-forced", ExecuteJavascript("forceOpusDtx()", tab));
}

void WebRtcTestBase::CreateAndAddStreams(content::WebContents* tab,
                                         size_t count) const {
  EXPECT_EQ(
      "ok-streams-created-and-added",
      ExecuteJavascript(
          "createAndAddStreams(" + base::SizeTToString(count) + ")", tab));
}

void WebRtcTestBase::VerifyRtpSenders(
    content::WebContents* tab,
    base::Optional<size_t> expected_num_tracks) const {
  std::string javascript =
      expected_num_tracks ? "verifyRtpSenders(" +
                                base::SizeTToString(*expected_num_tracks) + ")"
                          : "verifyRtpSenders()";
  EXPECT_EQ("ok-senders-verified", ExecuteJavascript(javascript, tab));
}

void WebRtcTestBase::VerifyRtpReceivers(
    content::WebContents* tab,
    base::Optional<size_t> expected_num_tracks) const {
  std::string javascript =
      expected_num_tracks ? "verifyRtpReceivers(" +
                                base::SizeTToString(*expected_num_tracks) + ")"
                          : "verifyRtpReceivers()";
  EXPECT_EQ("ok-receivers-verified", ExecuteJavascript(javascript, tab));
}
