// 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/web_test_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::NormalizeWebTestURL(
      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 web test. Manually call
      // LoadURLWithParams on the WebContents to avoid extraneous calls from
      // content::Shell such as SetFocus(), which could race with the web
      // test.
      NavigationController::LoadURLParams params(test_url_);

      // Using PAGE_TRANSITION_LINK avoids a BrowsingInstance/process swap
      // between web 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 web 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 {
    ApplyWebTestDefaultPreferences(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 web 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->EnsureSurfaceSynchronizedForWebTest();
      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
  // ResetAfterWebTest() 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
