// 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 "content/shell/browser/web_test/blink_test_controller.h"

#include <stddef.h>
#include <string.h>

#include <algorithm>
#include <iostream>
#include <memory>
#include <set>
#include <utility>
#include <vector>

#include "base/barrier_closure.h"
#include "base/base64.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/nullable_string16.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/common/page_state_serialization.h"
#include "content/common/unique_name_helper.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/child_process_termination_info.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/layouttest_support.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/shell/browser/shell_content_browser_client.h"
#include "content/shell/browser/shell_devtools_frontend.h"
#include "content/shell/browser/shell_network_delegate.h"
#include "content/shell/browser/web_test/devtools_protocol_test_bindings.h"
#include "content/shell/browser/web_test/fake_bluetooth_chooser.h"
#include "content/shell/browser/web_test/test_info_extractor.h"
#include "content/shell/browser/web_test/web_test_bluetooth_chooser_factory.h"
#include "content/shell/browser/web_test/web_test_content_browser_client.h"
#include "content/shell/browser/web_test/web_test_devtools_bindings.h"
#include "content/shell/browser/web_test/web_test_first_device_bluetooth_chooser.h"
#include "content/shell/common/shell_messages.h"
#include "content/shell/common/web_test/web_test_messages.h"
#include "content/shell/common/web_test/web_test_switches.h"
#include "content/shell/common/web_test/web_test_utils.h"
#include "content/shell/renderer/web_test/blink_test_helpers.h"
#include "content/shell/test_runner/test_common.h"
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "ui/gfx/codec/png_codec.h"

#if defined(OS_MACOSX)
#include "base/mac/foundation_util.h"
#endif

namespace content {

namespace {

std::string DumpFrameState(const ExplodedFrameState& frame_state,
                           size_t indent,
                           bool is_current_index) {
  std::string result;
  if (is_current_index) {
    constexpr const char kCurrentMarker[] = "curr->";
    result.append(kCurrentMarker);
    result.append(indent - strlen(kCurrentMarker), ' ');
  } else {
    result.append(indent, ' ');
  }

  std::string url = test_runner::NormalizeLayoutTestURL(
      base::UTF16ToUTF8(frame_state.url_string.value_or(base::string16())));
  result.append(url);
  DCHECK(frame_state.target);
  if (!frame_state.target->empty()) {
    std::string unique_name = base::UTF16ToUTF8(*frame_state.target);
    result.append(" (in frame \"");
    result.append(UniqueNameHelper::ExtractStableNameForTesting(unique_name));
    result.append("\")");
  }
  result.append("\n");

  std::vector<ExplodedFrameState> sorted_children = frame_state.children;
  std::sort(
      sorted_children.begin(), sorted_children.end(),
      [](const ExplodedFrameState& lhs, const ExplodedFrameState& rhs) {
        // Child nodes should always have a target (aka unique name).
        DCHECK(lhs.target);
        DCHECK(rhs.target);
        std::string lhs_name = UniqueNameHelper::ExtractStableNameForTesting(
            base::UTF16ToUTF8(*lhs.target));
        std::string rhs_name = UniqueNameHelper::ExtractStableNameForTesting(
            base::UTF16ToUTF8(*rhs.target));
        if (!base::EqualsCaseInsensitiveASCII(lhs_name, rhs_name))
          return base::CompareCaseInsensitiveASCII(lhs_name, rhs_name) < 0;

        return lhs.item_sequence_number < rhs.item_sequence_number;
      });
  for (const auto& child : sorted_children)
    result += DumpFrameState(child, indent + 4, false);

  return result;
}

std::string DumpNavigationEntry(NavigationEntry* navigation_entry,
                                bool is_current_index) {
  // This is silly, but it's currently the best way to extract the information.
  PageState page_state = navigation_entry->GetPageState();
  ExplodedPageState exploded_page_state;
  CHECK(DecodePageState(page_state.ToEncodedData(), &exploded_page_state));
  return DumpFrameState(exploded_page_state.top, 8, is_current_index);
}

std::string DumpHistoryForWebContents(WebContents* web_contents) {
  std::string result;
  const int current_index =
      web_contents->GetController().GetCurrentEntryIndex();
  for (int i = 0; i < web_contents->GetController().GetEntryCount(); ++i) {
    result += DumpNavigationEntry(
        web_contents->GetController().GetEntryAtIndex(i), i == current_index);
  }
  return result;
}

}  // namespace

// BlinkTestResultPrinter ----------------------------------------------------

BlinkTestResultPrinter::BlinkTestResultPrinter(std::ostream* output,
                                               std::ostream* error)
    : state_(DURING_TEST),
      capture_text_only_(false),
      encode_binary_data_(false),
      output_(output),
      error_(error) {}

BlinkTestResultPrinter::~BlinkTestResultPrinter() {}

void BlinkTestResultPrinter::StartStateDump() {
  state_ = DURING_STATE_DUMP;
}

void BlinkTestResultPrinter::PrintTextHeader() {
  if (state_ != DURING_STATE_DUMP)
    return;
  if (!capture_text_only_)
    *output_ << "Content-Type: text/plain\n";
  state_ = IN_TEXT_BLOCK;
}

void BlinkTestResultPrinter::PrintTextBlock(const std::string& block) {
  if (state_ != IN_TEXT_BLOCK)
    return;
  *output_ << block;
}

void BlinkTestResultPrinter::PrintTextFooter() {
  if (state_ != IN_TEXT_BLOCK)
    return;
  if (!capture_text_only_) {
    *output_ << "#EOF\n";
    output_->flush();
  }
  state_ = IN_IMAGE_BLOCK;
}

void BlinkTestResultPrinter::PrintImageHeader(
    const std::string& actual_hash,
    const std::string& expected_hash) {
  if (state_ != IN_IMAGE_BLOCK || capture_text_only_)
    return;
  *output_ << "\nActualHash: " << actual_hash << "\n";
  if (!expected_hash.empty())
    *output_ << "\nExpectedHash: " << expected_hash << "\n";
}

void BlinkTestResultPrinter::PrintImageBlock(
    const std::vector<unsigned char>& png_image) {
  if (state_ != IN_IMAGE_BLOCK || capture_text_only_)
    return;
  *output_ << "Content-Type: image/png\n";
  if (encode_binary_data_) {
    PrintEncodedBinaryData(png_image);
    return;
  }

  *output_ << "Content-Length: " << png_image.size() << "\n";
  output_->write(reinterpret_cast<const char*>(&png_image[0]),
                 png_image.size());
}

void BlinkTestResultPrinter::PrintImageFooter() {
  if (state_ != IN_IMAGE_BLOCK)
    return;
  if (!capture_text_only_) {
    *output_ << "#EOF\n";
    output_->flush();
  }
  state_ = AFTER_TEST;
}

void BlinkTestResultPrinter::PrintAudioHeader() {
  DCHECK_EQ(state_, DURING_STATE_DUMP);
  if (!capture_text_only_)
    *output_ << "Content-Type: audio/wav\n";
  state_ = IN_AUDIO_BLOCK;
}

void BlinkTestResultPrinter::PrintAudioBlock(
    const std::vector<unsigned char>& audio_data) {
  if (state_ != IN_AUDIO_BLOCK || capture_text_only_)
    return;
  if (encode_binary_data_) {
    PrintEncodedBinaryData(audio_data);
    return;
  }

  *output_ << "Content-Length: " << audio_data.size() << "\n";
  output_->write(reinterpret_cast<const char*>(&audio_data[0]),
                 audio_data.size());
}

void BlinkTestResultPrinter::PrintAudioFooter() {
  if (state_ != IN_AUDIO_BLOCK)
    return;
  if (!capture_text_only_) {
    *output_ << "#EOF\n";
    output_->flush();
  }
  state_ = IN_IMAGE_BLOCK;
}

void BlinkTestResultPrinter::AddMessageToStderr(const std::string& message) {
  *error_ << message;
}

void BlinkTestResultPrinter::AddMessage(const std::string& message) {
  AddMessageRaw(message + "\n");
}

void BlinkTestResultPrinter::AddMessageRaw(const std::string& message) {
  if (state_ != DURING_TEST)
    return;
  *output_ << message;
}

void BlinkTestResultPrinter::AddErrorMessage(const std::string& message) {
  if (!capture_text_only_)
    *error_ << message << "\n";
  if (state_ != DURING_TEST && state_ != DURING_STATE_DUMP)
    return;
  PrintTextHeader();
  *output_ << message << "\n";
  PrintTextFooter();
  PrintImageFooter();
}

void BlinkTestResultPrinter::PrintEncodedBinaryData(
    const std::vector<unsigned char>& data) {
  *output_ << "Content-Transfer-Encoding: base64\n";

  std::string data_base64;
  base::Base64Encode(
      base::StringPiece(reinterpret_cast<const char*>(&data[0]), data.size()),
      &data_base64);

  *output_ << "Content-Length: " << data_base64.length() << "\n";
  output_->write(data_base64.c_str(), data_base64.length());
}

void BlinkTestResultPrinter::CloseStderr() {
  if (state_ != AFTER_TEST)
    return;
  if (!capture_text_only_) {
    *error_ << "#EOF\n";
    error_->flush();
  }
}

// BlinkTestController -------------------------------------------------------

BlinkTestController* BlinkTestController::instance_ = nullptr;

// static
BlinkTestController* BlinkTestController::Get() {
  return instance_;
}

BlinkTestController::BlinkTestController()
    : main_window_(nullptr),
      secondary_window_(nullptr),
      devtools_window_(nullptr),
      test_phase_(BETWEEN_TESTS),
      crash_when_leak_found_(false),
      pending_layout_dumps_(0),
      render_process_host_observer_(this),
      weak_factory_(this) {
  CHECK(!instance_);
  instance_ = this;

  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableLeakDetection)) {
    leak_detector_ = std::make_unique<LeakDetector>();
    std::string switchValue =
        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kEnableLeakDetection);
    crash_when_leak_found_ = switchValue == switches::kCrashOnFailure;
  }

  printer_.reset(new BlinkTestResultPrinter(&std::cout, &std::cerr));
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEncodeBinary))
    printer_->set_encode_binary_data(true);

  // Print text only (without binary dumps and headers/footers for run_web_tests
  // protocol) until we enter the protocol mode (see TestInfo::protocol_mode).
  printer_->set_capture_text_only(true);

  registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
                 NotificationService::AllSources());
  GpuDataManager::GetInstance()->AddObserver(this);
  ResetAfterWebTest();
}

BlinkTestController::~BlinkTestController() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK(instance_ == this);
  CHECK(test_phase_ == BETWEEN_TESTS);
  GpuDataManager::GetInstance()->RemoveObserver(this);
  DiscardMainWindow();
  instance_ = nullptr;
}

bool BlinkTestController::PrepareForWebTest(const TestInfo& test_info) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  test_phase_ = DURING_TEST;
  current_working_directory_ = test_info.current_working_directory;
  expected_pixel_hash_ = test_info.expected_pixel_hash;
  bool is_devtools_js_test = false;
  test_url_ = WebTestDevToolsBindings::MapTestURLIfNeeded(test_info.url,
                                                          &is_devtools_js_test);
  bool is_devtools_protocol_test = false;
  test_url_ = DevToolsProtocolTestBindings::MapTestURLIfNeeded(
      test_url_, &is_devtools_protocol_test);
  did_send_initial_test_configuration_ = false;

  protocol_mode_ = test_info.protocol_mode;
  if (protocol_mode_)
    printer_->set_capture_text_only(false);
  printer_->reset();

  frame_to_layout_dump_map_.clear();
  render_process_host_observer_.RemoveAll();
  all_observed_render_process_hosts_.clear();
  main_window_render_process_hosts_.clear();
  accumulated_web_test_runtime_flags_changes_.Clear();
  web_test_control_map_.clear();

  ShellBrowserContext* browser_context =
      ShellContentBrowserClient::Get()->browser_context();
  is_compositing_test_ =
      test_url_.spec().find("compositing/") != std::string::npos;
  initial_size_ = Shell::GetShellDefaultSize();
  if (!main_window_) {
    main_window_ = content::Shell::CreateNewWindow(
        browser_context, GURL(url::kAboutBlankURL), nullptr, initial_size_);
    WebContentsObserver::Observe(main_window_->web_contents());

    // The render frame host is constructed before the call to
    // WebContentsObserver::Observe, so we need to manually handle the creation
    // of the new render frame host.
    HandleNewRenderFrameHost(main_window_->web_contents()->GetMainFrame());

    if (is_devtools_protocol_test) {
      devtools_protocol_test_bindings_.reset(
          new DevToolsProtocolTestBindings(main_window_->web_contents()));
    }
    current_pid_ = base::kNullProcessId;
    default_prefs_ = main_window_->web_contents()
                         ->GetRenderViewHost()
                         ->GetWebkitPreferences();
    if (is_devtools_js_test) {
      LoadDevToolsJSTest();
    } else {
      // Focus the RenderWidgetHost. This will send an IPC message to the
      // renderer to propagate the state change.
      main_window_->web_contents()->GetRenderViewHost()->GetWidget()->Focus();

      // Flush various interfaces to ensure a test run begins from a known
      // state.
      main_window_->web_contents()
          ->GetRenderViewHost()
          ->GetWidget()
          ->FlushForTesting();
      GetWebTestControlPtr(
          main_window_->web_contents()->GetRenderViewHost()->GetMainFrame())
          .FlushForTesting();

      // Loading the URL will immediately start the layout test. Manually call
      // LoadURLWithParams on the WebContents to avoid extraneous calls from
      // content::Shell such as SetFocus(), which could race with the layout
      // test.
      NavigationController::LoadURLParams params(test_url_);

      // Using PAGE_TRANSITION_LINK avoids a BrowsingInstance/process swap
      // between layout tests.
      params.transition_type =
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK);

      // Clear history to purge the prior navigation to about:blank.
      params.should_clear_history_list = true;
      main_window_->web_contents()->GetController().LoadURLWithParams(params);
    }
  } else {
#if defined(OS_MACOSX)
    // Shell::SizeTo is not implemented on all platforms.
    main_window_->SizeTo(initial_size_);
#endif
    main_window_->web_contents()
        ->GetRenderViewHost()
        ->GetWidget()
        ->GetView()
        ->SetSize(initial_size_);
    // Try to reset the window size. This can fail, see crbug.com/772811
    main_window_->web_contents()
        ->GetRenderViewHost()
        ->GetWidget()
        ->SynchronizeVisualProperties();
    RenderViewHost* render_view_host =
        main_window_->web_contents()->GetRenderViewHost();

    if (is_devtools_protocol_test) {
      devtools_protocol_test_bindings_.reset(
          new DevToolsProtocolTestBindings(main_window_->web_contents()));
    }

    // Compositing tests override the default preferences (see
    // BlinkTestController::OverrideWebkitPrefs) so we force them to be
    // calculated again to ensure is_compositing_test_ changes are picked up.
    OverrideWebkitPrefs(&default_prefs_);

    render_view_host->UpdateWebkitPreferences(default_prefs_);
    HandleNewRenderFrameHost(render_view_host->GetMainFrame());

    // Focus the RenderWidgetHost. This will send an IPC message to the
    // renderer to propagate the state change.
    main_window_->web_contents()->GetRenderViewHost()->GetWidget()->Focus();

    // Flush various interfaces to ensure a test run begins from a known state.
    main_window_->web_contents()
        ->GetRenderViewHost()
        ->GetWidget()
        ->FlushForTesting();
    GetWebTestControlPtr(render_view_host->GetMainFrame()).FlushForTesting();

    if (is_devtools_js_test) {
      LoadDevToolsJSTest();
    } else {
      NavigationController::LoadURLParams params(test_url_);
      // Using PAGE_TRANSITION_LINK avoids a BrowsingInstance/process swap
      // between layout tests.
      params.transition_type =
          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK);
      params.should_clear_history_list = true;
      main_window_->web_contents()->GetController().LoadURLWithParams(params);
    }
  }
  return true;
}

Shell* BlinkTestController::SecondaryWindow() {
  if (!secondary_window_) {
    ShellBrowserContext* browser_context =
        ShellContentBrowserClient::Get()->browser_context();
    secondary_window_ = content::Shell::CreateNewWindow(browser_context, GURL(),
                                                        nullptr, initial_size_);
  }
  return secondary_window_;
}

void BlinkTestController::LoadDevToolsJSTest() {
  devtools_window_ = main_window_;
  Shell* secondary = SecondaryWindow();
  devtools_bindings_ = std::make_unique<WebTestDevToolsBindings>(
      devtools_window_->web_contents(), secondary->web_contents(), test_url_);
}

bool BlinkTestController::ResetAfterWebTest() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  printer_->PrintTextFooter();
  printer_->PrintImageFooter();
  printer_->CloseStderr();
  did_send_initial_test_configuration_ = false;
  test_phase_ = BETWEEN_TESTS;
  is_compositing_test_ = false;
  expected_pixel_hash_.clear();
  test_url_ = GURL();
  prefs_ = WebPreferences();
  should_override_prefs_ = false;
  WebTestContentBrowserClient::Get()->SetPopupBlockingEnabled(false);
  WebTestContentBrowserClient::Get()->ResetMockClipboardHost();
  navigation_history_dump_ = "";
  pixel_dump_.reset();
  actual_pixel_hash_ = "";
  main_frame_dump_ = nullptr;
  waiting_for_pixel_results_ = false;
  waiting_for_main_frame_dump_ = false;
  composite_all_frames_node_queue_ = std::queue<Node*>();
  composite_all_frames_node_storage_.clear();
  weak_factory_.InvalidateWeakPtrs();

#if defined(OS_ANDROID)
  // Re-using the shell's main window on Android causes issues with networking
  // requests never succeeding. See http://crbug.com/277652.
  DiscardMainWindow();
#endif

  return true;
}

void BlinkTestController::SetTempPath(const base::FilePath& temp_path) {
  temp_path_ = temp_path;
}

void BlinkTestController::RendererUnresponsive() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  LOG(WARNING) << "renderer unresponsive";
}

void BlinkTestController::OverrideWebkitPrefs(WebPreferences* prefs) {
  if (should_override_prefs_) {
    *prefs = prefs_;
  } else {
    ApplyLayoutTestDefaultPreferences(prefs);
    if (is_compositing_test_) {
      base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
      if (!command_line.HasSwitch(switches::kDisableGpu))
        prefs->accelerated_2d_canvas_enabled = true;
      prefs->mock_scrollbars_enabled = true;
    }
  }
}

void BlinkTestController::OpenURL(const GURL& url) {
  if (test_phase_ != DURING_TEST)
    return;

  Shell::CreateNewWindow(main_window_->web_contents()->GetBrowserContext(), url,
                         main_window_->web_contents()->GetSiteInstance(),
                         gfx::Size());
}

void BlinkTestController::OnTestFinishedInSecondaryRenderer() {
  RenderViewHost* main_render_view_host =
      main_window_->web_contents()->GetRenderViewHost();
  main_render_view_host->Send(new ShellViewMsg_TestFinishedInSecondaryRenderer(
      main_render_view_host->GetRoutingID()));
}

void BlinkTestController::OnInitiateCaptureDump(bool capture_navigation_history,
                                                bool capture_pixels) {
  if (test_phase_ != DURING_TEST)
    return;

  if (capture_navigation_history) {
    RenderFrameHost* main_rfh = main_window_->web_contents()->GetMainFrame();
    for (auto* window : Shell::windows()) {
      WebContents* web_contents = window->web_contents();
      // Only capture the history from windows in the same process_host as the
      // main window. During layout tests, we only use two processes when a
      // devtools window is open.
      // TODO(https://crbug.com/771003): Dump history for all WebContentses, not
      // just ones that happen to be in the same process_host as the main test
      // window's main frame.
      if (main_rfh->GetProcess() != web_contents->GetMainFrame()->GetProcess())
        continue;

      navigation_history_dump_ +=
          "\n============== Back Forward List ==============\n";
      navigation_history_dump_ += DumpHistoryForWebContents(web_contents);
      navigation_history_dump_ +=
          "===============================================\n";
    }
  }

  // Ensure to say that we need to wait for main frame dump here, since
  // CopyFromSurface call below may synchronously issue the callback, meaning
  // that we would report results too early.
  waiting_for_main_frame_dump_ = true;

  if (capture_pixels) {
    DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
        switches::kEnableDisplayCompositorPixelDump));
    waiting_for_pixel_results_ = true;
    auto* rwhv = main_window_->web_contents()->GetRenderWidgetHostView();
    // If we're running in threaded mode, then the frames will be produced via a
    // scheduler elsewhere, all we need to do is to ensure that the surface is
    // synchronized before we copy from it. In single threaded mode, we have to
    // force each renderer to produce a frame.
    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kEnableThreadedCompositing)) {
      rwhv->EnsureSurfaceSynchronizedForLayoutTest();
      EnqueueSurfaceCopyRequest();
    } else {
      CompositeAllFramesThen(
          base::BindOnce(&BlinkTestController::EnqueueSurfaceCopyRequest,
                         weak_factory_.GetWeakPtr()));
    }
  }

  RenderFrameHost* rfh = main_window_->web_contents()->GetMainFrame();
  printer_->StartStateDump();
  GetWebTestControlPtr(rfh)->CaptureDump(
      base::BindOnce(&BlinkTestController::OnCaptureDumpCompleted,
                     weak_factory_.GetWeakPtr()));
}

// Enqueue an image copy output request.
void BlinkTestController::EnqueueSurfaceCopyRequest() {
  auto* rwhv = main_window_->web_contents()->GetRenderWidgetHostView();
  rwhv->CopyFromSurface(
      gfx::Rect(), gfx::Size(),
      base::BindOnce(&BlinkTestController::OnPixelDumpCaptured,
                     weak_factory_.GetWeakPtr()));
}

void BlinkTestController::CompositeAllFramesThen(
    base::OnceCallback<void()> callback) {
  // Only allow a single call to CompositeAllFramesThen(), without a call to
  // ResetAfterLayoutTest() in between. More than once risks overlapping calls,
  // due to the asynchronous nature of CompositeNodeQueueThen(), which can lead
  // to use-after-free, e.g.
  // https://clusterfuzz.com/v2/testcase-detail/4929420383748096
  if (!composite_all_frames_node_storage_.empty() ||
      !composite_all_frames_node_queue_.empty()) {
    // Using NOTREACHED + return here because we want to disallow the second
    // call if this happens in release builds, while still catching this
    // condition in debug builds.
    NOTREACHED();
    return;
  }
  // Build the frame storage and depth first queue.
  Node* root = BuildFrameTree(main_window_->web_contents()->GetAllFrames());
  BuildDepthFirstQueue(root);
  // Now asynchronously run through the node queue.
  CompositeNodeQueueThen(std::move(callback));
}

void BlinkTestController::CompositeNodeQueueThen(
    base::OnceCallback<void()> callback) {
  // Frames can get freed somewhere else while a CompositeWithRaster is taking
  // place. Therefore, we need to double-check that this frame pointer is
  // still valid before using it. To do that, grab the list of all frames
  // again, and make sure it contains the one we're about to composite.
  // See crbug.com/899465 for an example of this problem.
  std::vector<RenderFrameHost*> current_frames(
      main_window_->web_contents()->GetAllFrames());
  RenderFrameHost* next_node_host;
  do {
    if (composite_all_frames_node_queue_.empty()) {
      // Done with the queue - call the callback.
      std::move(callback).Run();
      return;
    }
    next_node_host =
        composite_all_frames_node_queue_.front()->render_frame_host;
    composite_all_frames_node_queue_.pop();
    if (std::find(current_frames.begin(), current_frames.end(),
                  next_node_host) == current_frames.end()) {
      next_node_host = nullptr;  // This one is now gone
    }
  } while (!next_node_host || !next_node_host->IsRenderFrameLive());
  GetWebTestControlPtr(next_node_host)
      ->CompositeWithRaster(
          base::BindOnce(&BlinkTestController::CompositeNodeQueueThen,
                         weak_factory_.GetWeakPtr(), std::move(callback)));
}

void BlinkTestController::BuildDepthFirstQueue(Node* node) {
  for (auto* child : node->children)
    BuildDepthFirstQueue(child);
  composite_all_frames_node_queue_.push(node);
}

BlinkTestController::Node* BlinkTestController::BuildFrameTree(
    const std::vector<RenderFrameHost*>& frames) {
  // Ensure we don't reallocate during tree construction.
  composite_all_frames_node_storage_.reserve(frames.size());

  // Returns a Node for a given RenderFrameHost, or nullptr if doesn't exist.
  auto node_for_frame = [this](RenderFrameHost* rfh) {
    auto it = std::find_if(
        composite_all_frames_node_storage_.begin(),
        composite_all_frames_node_storage_.end(),
        [rfh](const Node& node) { return node.render_frame_host == rfh; });
    return it == composite_all_frames_node_storage_.end() ? nullptr : &*it;
  };

  // Add all of the frames to storage.
  for (auto* frame : frames) {
    DCHECK(!node_for_frame(frame)) << "Frame seen multiple times.";
    composite_all_frames_node_storage_.emplace_back(frame);
  }

  // Construct a tree rooted at |root|.
  Node* root = nullptr;
  for (auto* frame : frames) {
    Node* node = node_for_frame(frame);
    DCHECK(node);
    if (!frame->GetParent()) {
      DCHECK(!root) << "Multiple roots found.";
      root = node;
    } else {
      Node* parent = node_for_frame(frame->GetParent());
      DCHECK(parent);
      parent->children.push_back(node);
    }
  }
  DCHECK(root) << "No root found.";
  return root;
}

bool BlinkTestController::IsMainWindow(WebContents* web_contents) const {
  return main_window_ && web_contents == main_window_->web_contents();
}

std::unique_ptr<BluetoothChooser> BlinkTestController::RunBluetoothChooser(
    RenderFrameHost* frame,
    const BluetoothChooser::EventHandler& event_handler) {
  // TODO(https://crbug.com/509038): Remove |bluetooth_chooser_factory_| once
  // all of the Web Bluetooth tests are migrated to external/wpt/.
  if (bluetooth_chooser_factory_) {
    return bluetooth_chooser_factory_->RunBluetoothChooser(frame,
                                                           event_handler);
  }
  auto next_fake_bluetooth_chooser =
      WebTestContentBrowserClient::Get()->GetNextFakeBluetoothChooser();
  if (next_fake_bluetooth_chooser) {
    next_fake_bluetooth_chooser->SetEventHandler(event_handler);
    return next_fake_bluetooth_chooser;
  }
  return std::make_unique<WebTestFirstDeviceBluetoothChooser>(event_handler);
}

bool BlinkTestController::OnMessageReceived(const IPC::Message& message) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(BlinkTestController, message)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_PrintMessage, OnPrintMessage)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_PrintMessageToStderr,
                        OnPrintMessageToStderr)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_InitiateLayoutDump,
                        OnInitiateLayoutDump)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_OverridePreferences,
                        OnOverridePreferences)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_SetPopupBlockingEnabled,
                        OnSetPopupBlockingEnabled)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_NavigateSecondaryWindow,
                        OnNavigateSecondaryWindow)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_GoToOffset, OnGoToOffset)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_Reload, OnReload)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_LoadURLForFrame, OnLoadURLForFrame)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_CloseRemainingWindows,
                        OnCloseRemainingWindows)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_ResetDone, OnResetDone)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_SetBluetoothManualChooser,
                        OnSetBluetoothManualChooser)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_GetBluetoothManualChooserEvents,
                        OnGetBluetoothManualChooserEvents)
    IPC_MESSAGE_HANDLER(ShellViewHostMsg_SendBluetoothManualChooserEvent,
                        OnSendBluetoothManualChooserEvent)
    IPC_MESSAGE_HANDLER(WebTestHostMsg_BlockThirdPartyCookies,
                        OnBlockThirdPartyCookies)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void BlinkTestController::PluginCrashed(const base::FilePath& plugin_path,
                                        base::ProcessId plugin_pid) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  printer_->AddErrorMessage(
      base::StringPrintf("#CRASHED - plugin (pid %" CrPRIdPid ")", plugin_pid));
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(base::IgnoreResult(
                                    &BlinkTestController::DiscardMainWindow),
                                weak_factory_.GetWeakPtr()));
}

void BlinkTestController::RenderFrameCreated(
    RenderFrameHost* render_frame_host) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  HandleNewRenderFrameHost(render_frame_host);
}

void BlinkTestController::DevToolsProcessCrashed() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  printer_->AddErrorMessage("#CRASHED - devtools");
  devtools_bindings_.reset();
  if (devtools_window_)
    devtools_window_->Close();
  devtools_window_ = nullptr;
}

void BlinkTestController::WebContentsDestroyed() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  printer_->AddErrorMessage("FAIL: main window was destroyed");
  DiscardMainWindow();
}

void BlinkTestController::RenderProcessHostDestroyed(
    RenderProcessHost* render_process_host) {
  render_process_host_observer_.Remove(render_process_host);
  all_observed_render_process_hosts_.erase(render_process_host);
  main_window_render_process_hosts_.erase(render_process_host);
}

void BlinkTestController::RenderProcessExited(
    RenderProcessHost* render_process_host,
    const ChildProcessTerminationInfo& info) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  switch (info.status) {
    case base::TerminationStatus::TERMINATION_STATUS_NORMAL_TERMINATION:
    case base::TerminationStatus::TERMINATION_STATUS_STILL_RUNNING:
      break;

    case base::TerminationStatus::TERMINATION_STATUS_ABNORMAL_TERMINATION:
    case base::TerminationStatus::TERMINATION_STATUS_LAUNCH_FAILED:
    case base::TerminationStatus::TERMINATION_STATUS_PROCESS_CRASHED:
    case base::TerminationStatus::TERMINATION_STATUS_PROCESS_WAS_KILLED:
    default: {
      const base::Process& process = render_process_host->GetProcess();
      if (process.IsValid()) {
        printer_->AddErrorMessage(std::string("#CRASHED - renderer (pid ") +
                                  base::IntToString(process.Pid()) + ")");
      } else {
        printer_->AddErrorMessage("#CRASHED - renderer");
      }

      DiscardMainWindow();
      break;
    }
  }
}

void BlinkTestController::Observe(int type,
                                  const NotificationSource& source,
                                  const NotificationDetails& details) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  switch (type) {
    case NOTIFICATION_RENDERER_PROCESS_CREATED: {
      if (!main_window_)
        return;
      RenderViewHost* render_view_host =
          main_window_->web_contents()->GetRenderViewHost();
      if (!render_view_host)
        return;
      RenderProcessHost* render_process_host =
          Source<RenderProcessHost>(source).ptr();
      if (render_process_host != render_view_host->GetProcess())
        return;
      current_pid_ = render_process_host->GetProcess().Pid();
      break;
    }
    default:
      NOTREACHED();
  }
}

void BlinkTestController::OnGpuProcessCrashed(
    base::TerminationStatus exit_code) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  printer_->AddErrorMessage("#CRASHED - gpu");
  DiscardMainWindow();
}

void BlinkTestController::DiscardMainWindow() {
  // If we're running a test, we need to close all windows and exit the message
  // loop. Otherwise, we're already outside of the message loop, and we just
  // discard the main window.
  devtools_bindings_.reset();
  devtools_protocol_test_bindings_.reset();
  WebContentsObserver::Observe(nullptr);
  if (test_phase_ != BETWEEN_TESTS) {
    // CloseAllWindows will also signal the main message loop to exit.
    Shell::CloseAllWindows();
    test_phase_ = CLEAN_UP;
  } else if (main_window_) {
    main_window_->Close();
  }
  main_window_ = nullptr;
  current_pid_ = base::kNullProcessId;
}

void BlinkTestController::HandleNewRenderFrameHost(RenderFrameHost* frame) {
  RenderProcessHost* process_host = frame->GetProcess();
  bool main_window =
      WebContents::FromRenderFrameHost(frame) == main_window_->web_contents();

  // Track pid of the renderer handling the main frame.
  if (main_window && frame->GetParent() == nullptr) {
    const base::Process& process = process_host->GetProcess();
    if (process.IsValid())
      current_pid_ = process.Pid();
  }

  // Is this the 1st time this renderer contains parts of the main test window?
  if (main_window &&
      !base::ContainsKey(main_window_render_process_hosts_, process_host)) {
    main_window_render_process_hosts_.insert(process_host);

    // Make sure the new renderer process_host has a test configuration shared
    // with other renderers.
    mojom::ShellTestConfigurationPtr params =
        mojom::ShellTestConfiguration::New();
    params->allow_external_pages = false;
    params->current_working_directory = current_working_directory_;
    params->temp_path = temp_path_;
    params->test_url = test_url_;
    params->allow_external_pages =
        base::CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kAllowExternalPages);
    params->expected_pixel_hash = expected_pixel_hash_;
    params->initial_size = initial_size_;
    params->protocol_mode = protocol_mode_;

    if (did_send_initial_test_configuration_) {
      GetWebTestControlPtr(frame)->ReplicateTestConfiguration(
          std::move(params));
    } else {
      did_send_initial_test_configuration_ = true;
      GetWebTestControlPtr(frame)->SetTestConfiguration(std::move(params));
    }
  }

  // Is this a previously unknown renderer process_host?
  if (!render_process_host_observer_.IsObserving(process_host)) {
    render_process_host_observer_.Add(process_host);
    all_observed_render_process_hosts_.insert(process_host);

    if (!main_window) {
      GetWebTestControlPtr(frame)->SetupSecondaryRenderer();
    }

    process_host->Send(new WebTestMsg_ReplicateWebTestRuntimeFlagsChanges(
        accumulated_web_test_runtime_flags_changes_));
  }
}

void BlinkTestController::OnTestFinished() {
  test_phase_ = CLEAN_UP;
  if (!printer_->output_finished())
    printer_->PrintImageFooter();
  if (main_window_)
    main_window_->web_contents()->ExitFullscreen(/*will_cause_resize=*/false);
  devtools_bindings_.reset();
  devtools_protocol_test_bindings_.reset();

  ShellBrowserContext* browser_context =
      ShellContentBrowserClient::Get()->browser_context();

  base::RepeatingClosure barrier_closure = base::BarrierClosure(
      2, base::BindOnce(&BlinkTestController::OnCleanupFinished,
                        weak_factory_.GetWeakPtr()));

  StoragePartition* storage_partition =
      BrowserContext::GetStoragePartition(browser_context, nullptr);
  storage_partition->GetServiceWorkerContext()->ClearAllServiceWorkersForTest(
      barrier_closure);
  storage_partition->ClearBluetoothAllowedDevicesMapForTesting();

  // TODO(nhiroki): Add a comment about the reason why we terminate all shared
  // workers here.
  TerminateAllSharedWorkersForTesting(
      BrowserContext::GetStoragePartition(
          ShellContentBrowserClient::Get()->browser_context(), nullptr),
      barrier_closure);
}

void BlinkTestController::OnCleanupFinished() {
  if (main_window_) {
    main_window_->web_contents()->Stop();
    RenderViewHost* rvh = main_window_->web_contents()->GetRenderViewHost();
    rvh->Send(new ShellViewMsg_Reset(rvh->GetRoutingID()));
  }
  if (secondary_window_) {
    secondary_window_->web_contents()->Stop();
    RenderViewHost* rvh =
        secondary_window_->web_contents()->GetRenderViewHost();
    rvh->Send(new ShellViewMsg_Reset(rvh->GetRoutingID()));
  }
}

void BlinkTestController::OnCaptureDumpCompleted(mojom::WebTestDumpPtr dump) {
  main_frame_dump_ = std::move(dump);

  waiting_for_main_frame_dump_ = false;
  ReportResults();
}

void BlinkTestController::OnPixelDumpCaptured(const SkBitmap& snapshot) {
  DCHECK(!snapshot.drawsNothing());
  pixel_dump_ = snapshot;
  waiting_for_pixel_results_ = false;
  ReportResults();
}

void BlinkTestController::ReportResults() {
  if (waiting_for_pixel_results_ || waiting_for_main_frame_dump_)
    return;
  if (main_frame_dump_->audio)
    OnAudioDump(*main_frame_dump_->audio);
  if (main_frame_dump_->layout)
    OnTextDump(*main_frame_dump_->layout);
  // If we have local pixels, report that. Otherwise report whatever the pixel
  // dump received from the renderer contains.
  if (pixel_dump_) {
    // See if we need to draw the selection bounds rect on top of the snapshot.
    if (!main_frame_dump_->selection_rect.IsEmpty()) {
      content::web_test_utils::DrawSelectionRect(
          *pixel_dump_, main_frame_dump_->selection_rect);
    }
    // The snapshot arrives from the GPU process via shared memory. Because MSan
    // can't track initializedness across processes, we must assure it that the
    // pixels are in fact initialized.
    MSAN_UNPOISON(pixel_dump_->getPixels(), pixel_dump_->computeByteSize());
    base::MD5Digest digest;
    base::MD5Sum(pixel_dump_->getPixels(), pixel_dump_->computeByteSize(),
                 &digest);
    actual_pixel_hash_ = base::MD5DigestToBase16(digest);

    OnImageDump(actual_pixel_hash_, *pixel_dump_);
  } else if (!main_frame_dump_->actual_pixel_hash.empty()) {
    OnImageDump(main_frame_dump_->actual_pixel_hash, main_frame_dump_->pixels);
  }
  OnTestFinished();
}

void BlinkTestController::OnImageDump(const std::string& actual_pixel_hash,
                                      const SkBitmap& image) {
  printer_->PrintImageHeader(actual_pixel_hash, expected_pixel_hash_);

  // Only encode and dump the png if the hashes don't match. Encoding the
  // image is really expensive.
  if (actual_pixel_hash != expected_pixel_hash_) {
    std::vector<unsigned char> png;

    bool discard_transparency = true;
    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kForceOverlayFullscreenVideo)) {
      discard_transparency = false;
    }

    gfx::PNGCodec::ColorFormat pixel_format;
    switch (image.info().colorType()) {
      case kBGRA_8888_SkColorType:
        pixel_format = gfx::PNGCodec::FORMAT_BGRA;
        break;
      case kRGBA_8888_SkColorType:
        pixel_format = gfx::PNGCodec::FORMAT_RGBA;
        break;
      default:
        NOTREACHED();
        return;
    }

    std::vector<gfx::PNGCodec::Comment> comments;
    comments.push_back(gfx::PNGCodec::Comment("checksum", actual_pixel_hash));
    bool success = gfx::PNGCodec::Encode(
        static_cast<const unsigned char*>(image.getPixels()), pixel_format,
        gfx::Size(image.width(), image.height()),
        static_cast<int>(image.rowBytes()), discard_transparency, comments,
        &png);
    if (success)
      printer_->PrintImageBlock(png);
  }
  printer_->PrintImageFooter();
}

void BlinkTestController::OnAudioDump(const std::vector<unsigned char>& dump) {
  printer_->PrintAudioHeader();
  printer_->PrintAudioBlock(dump);
  printer_->PrintAudioFooter();
}

void BlinkTestController::OnTextDump(const std::string& dump) {
  printer_->PrintTextHeader();
  printer_->PrintTextBlock(dump);
  if (!navigation_history_dump_.empty())
    printer_->PrintTextBlock(navigation_history_dump_);
  printer_->PrintTextFooter();
}

void BlinkTestController::OnInitiateLayoutDump() {
  // There should be at most 1 layout dump in progress at any given time.
  DCHECK_EQ(0, pending_layout_dumps_);

  int number_of_messages = 0;
  for (RenderFrameHost* rfh : main_window_->web_contents()->GetAllFrames()) {
    if (!rfh->IsRenderFrameLive())
      continue;

    ++number_of_messages;
    GetWebTestControlPtr(rfh)->DumpFrameLayout(
        base::BindOnce(&BlinkTestController::OnDumpFrameLayoutResponse,
                       weak_factory_.GetWeakPtr(), rfh->GetFrameTreeNodeId()));
  }

  pending_layout_dumps_ = number_of_messages;
}

void BlinkTestController::OnWebTestRuntimeFlagsChanged(
    int sender_process_host_id,
    const base::DictionaryValue& changed_web_test_runtime_flags) {
  // Stash the accumulated changes for future, not-yet-created renderers.
  accumulated_web_test_runtime_flags_changes_.MergeDictionary(
      &changed_web_test_runtime_flags);

  // Propagate the changes to all the tracked renderer processes.
  for (RenderProcessHost* process : all_observed_render_process_hosts_) {
    // Do not propagate the changes back to the process that originated
    // them. (propagating them back could also clobber subsequent changes in the
    // originator).
    if (process->GetID() == sender_process_host_id)
      continue;

    process->Send(new WebTestMsg_ReplicateWebTestRuntimeFlagsChanges(
        changed_web_test_runtime_flags));
  }
}

void BlinkTestController::OnDumpFrameLayoutResponse(int frame_tree_node_id,
                                                    const std::string& dump) {
  // Store the result.
  auto pair = frame_to_layout_dump_map_.insert(
      std::make_pair(frame_tree_node_id, dump));
  bool insertion_took_place = pair.second;
  DCHECK(insertion_took_place);

  // See if we need to wait for more responses.
  pending_layout_dumps_--;
  DCHECK_LE(0, pending_layout_dumps_);
  if (pending_layout_dumps_ > 0)
    return;

  // If the main test window was destroyed while waiting for the responses, then
  // there is nobody to receive the |stitched_layout_dump| and finish the test.
  if (!web_contents()) {
    OnTestFinished();
    return;
  }

  // Stitch the frame-specific results in the right order.
  std::string stitched_layout_dump;
  for (auto* render_frame_host : web_contents()->GetAllFrames()) {
    auto it =
        frame_to_layout_dump_map_.find(render_frame_host->GetFrameTreeNodeId());
    if (it != frame_to_layout_dump_map_.end()) {
      const std::string& dump = it->second;
      stitched_layout_dump.append(dump);
    }
  }

  // Continue finishing the test.
  RenderViewHost* render_view_host =
      main_window_->web_contents()->GetRenderViewHost();
  render_view_host->Send(new ShellViewMsg_LayoutDumpCompleted(
      render_view_host->GetRoutingID(), stitched_layout_dump));
}

void BlinkTestController::OnPrintMessage(const std::string& message) {
  printer_->AddMessageRaw(message);
}

void BlinkTestController::OnPrintMessageToStderr(const std::string& message) {
  printer_->AddMessageToStderr(message);
}

void BlinkTestController::OnOverridePreferences(const WebPreferences& prefs) {
  should_override_prefs_ = true;
  prefs_ = prefs;

  // Notifies the main RenderViewHost that Blink preferences changed so
  // immediately apply the new settings and to avoid re-usage of cached
  // preferences that are now stale. RenderViewHost::UpdateWebkitPreferences is
  // not used here because it would send an unneeded preferences update to the
  // renderer.
  RenderViewHost* main_render_view_host =
      main_window_->web_contents()->GetRenderViewHost();
  main_render_view_host->OnWebkitPreferencesChanged();
}

void BlinkTestController::OnSetPopupBlockingEnabled(bool block_popups) {
  WebTestContentBrowserClient::Get()->SetPopupBlockingEnabled(block_popups);
}

void BlinkTestController::OnNavigateSecondaryWindow(const GURL& url) {
  if (secondary_window_)
    secondary_window_->LoadURL(url);
}

void BlinkTestController::OnInspectSecondaryWindow() {
  if (devtools_bindings_)
    devtools_bindings_->Attach();
}

void BlinkTestController::OnGoToOffset(int offset) {
  main_window_->GoBackOrForward(offset);
}

void BlinkTestController::OnReload() {
  main_window_->Reload();
}

void BlinkTestController::OnLoadURLForFrame(const GURL& url,
                                            const std::string& frame_name) {
  main_window_->LoadURLForFrame(url, frame_name, ui::PAGE_TRANSITION_LINK);
}

void BlinkTestController::OnCloseRemainingWindows() {
  DevToolsAgentHost::DetachAllClients();
  std::vector<Shell*> open_windows(Shell::windows());
  for (size_t i = 0; i < open_windows.size(); ++i) {
    if (open_windows[i] != main_window_ && open_windows[i] != secondary_window_)
      open_windows[i]->Close();
  }
  base::RunLoop().RunUntilIdle();
}

void BlinkTestController::OnResetDone() {
  if (leak_detector_) {
    if (main_window_ && main_window_->web_contents()) {
      RenderViewHost* rvh = main_window_->web_contents()->GetRenderViewHost();
      DCHECK_EQ(GURL(url::kAboutBlankURL),
                rvh->GetMainFrame()->GetLastCommittedURL());
      leak_detector_->TryLeakDetection(
          rvh->GetProcess(),
          base::BindOnce(&BlinkTestController::OnLeakDetectionDone,
                         weak_factory_.GetWeakPtr()));
    }
    return;
  }

  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&Shell::QuitMainMessageLoopForTesting));
}

void BlinkTestController::OnLeakDetectionDone(
    const LeakDetector::LeakDetectionReport& report) {
  if (!report.leaked) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(&Shell::QuitMainMessageLoopForTesting));
    return;
  }

  printer_->AddErrorMessage(base::StringPrintf(
      "#LEAK - renderer pid %d (%s)", current_pid_, report.detail.c_str()));
  CHECK(!crash_when_leak_found_);

  DiscardMainWindow();
}

void BlinkTestController::OnSetBluetoothManualChooser(bool enable) {
  bluetooth_chooser_factory_.reset();
  if (enable) {
    bluetooth_chooser_factory_.reset(new WebTestBluetoothChooserFactory());
  }
}

void BlinkTestController::OnGetBluetoothManualChooserEvents() {
  if (!bluetooth_chooser_factory_) {
    printer_->AddErrorMessage(
        "FAIL: Must call setBluetoothManualChooser before "
        "getBluetoothManualChooserEvents.");
    return;
  }
  RenderViewHost* rvh = main_window_->web_contents()->GetRenderViewHost();
  rvh->Send(new ShellViewMsg_ReplyBluetoothManualChooserEvents(
      rvh->GetRoutingID(), bluetooth_chooser_factory_->GetAndResetEvents()));
}

void BlinkTestController::OnSendBluetoothManualChooserEvent(
    const std::string& event_name,
    const std::string& argument) {
  if (!bluetooth_chooser_factory_) {
    printer_->AddErrorMessage(
        "FAIL: Must call setBluetoothManualChooser before "
        "sendBluetoothManualChooserEvent.");
    return;
  }
  BluetoothChooser::Event event;
  if (event_name == "cancelled") {
    event = BluetoothChooser::Event::CANCELLED;
  } else if (event_name == "selected") {
    event = BluetoothChooser::Event::SELECTED;
  } else if (event_name == "rescan") {
    event = BluetoothChooser::Event::RESCAN;
  } else {
    printer_->AddErrorMessage(base::StringPrintf(
        "FAIL: Unexpected sendBluetoothManualChooserEvent() event name '%s'.",
        event_name.c_str()));
    return;
  }
  bluetooth_chooser_factory_->SendEvent(event, argument);
}

void BlinkTestController::OnBlockThirdPartyCookies(bool block) {
  if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
    ShellBrowserContext* browser_context =
        ShellContentBrowserClient::Get()->browser_context();
    browser_context->GetDefaultStoragePartition(browser_context)
        ->GetCookieManagerForBrowserProcess()
        ->BlockThirdPartyCookies(block);
  } else {
    base::PostTaskWithTraits(
        FROM_HERE, {BrowserThread::IO},
        base::BindOnce(ShellNetworkDelegate::SetBlockThirdPartyCookies, block));
  }
}

mojom::WebTestControlAssociatedPtr& BlinkTestController::GetWebTestControlPtr(
    RenderFrameHost* frame) {
  GlobalFrameRoutingId key(frame->GetProcess()->GetID(), frame->GetRoutingID());
  if (web_test_control_map_.find(key) == web_test_control_map_.end()) {
    mojom::WebTestControlAssociatedPtr& new_ptr = web_test_control_map_[key];
    frame->GetRemoteAssociatedInterfaces()->GetInterface(&new_ptr);
    new_ptr.set_connection_error_handler(
        base::BindOnce(&BlinkTestController::HandleWebTestControlError,
                       weak_factory_.GetWeakPtr(), key));
  }
  DCHECK(web_test_control_map_[key].get());
  return web_test_control_map_[key];
}

void BlinkTestController::HandleWebTestControlError(
    const GlobalFrameRoutingId& key) {
  web_test_control_map_.erase(key);
}

BlinkTestController::Node::Node() = default;
BlinkTestController::Node::Node(RenderFrameHost* host)
    : render_frame_host(host) {}
BlinkTestController::Node::Node(Node&& other) = default;
BlinkTestController::Node::~Node() = default;

}  // namespace content
